84

How to customize the order of execution of tests in TestNG?

For example:

public class Test1 {
  @Test
  public void test1() {
      System.out.println("test1");
  }

  @Test
  public void test2() {
      System.out.println("test2");
  }

  @Test
  public void test3() {
      System.out.println("test3");
  }
}

In the above suite, the order of execution of tests is arbitrary. For one execution the output may be:

test1
test3
test2

How do I execute the tests in the order in which they've been written?

Petter Friberg
  • 21,252
  • 9
  • 60
  • 109
Badri
  • 2,212
  • 3
  • 25
  • 26

17 Answers17

93

This will work.

@Test(priority=1)
public void Test1() {

}

@Test(priority=2)
public void Test2() {

}

@Test(priority=3)
public void Test3() {

}

priority encourages execution order but does not guarantee the previous priority level has completed. test3 could start before test2 completes. If a guarantee is needed, then declare a dependency.

Unlike the solutions which declare dependencies, tests which use priority will execute even if one test fails. This problem with dependencies can be worked around with @Test(...alwaysRun = true...) according to documentation.

Nathan
  • 8,093
  • 8
  • 50
  • 76
user1927494
  • 939
  • 6
  • 2
67

In TestNG, you use dependsOnMethods and/or dependsOnGroups:

@Test(groups = "a")
public void f1() {}

@Test(groups = "a")
public void f2() {}

@Test(dependsOnGroups = "a")
public void g() {}

In this case, g() will only run after f1() and f2() have completed and succeeded.

You will find a lot of examples in the documentation: http://testng.org/doc/documentation-main.html#test-groups

Cedric Beust
  • 15,480
  • 2
  • 55
  • 55
  • 2
    `dependsOnGroups` is extremely useful but it seems to me that TestNG is ignoring `priority` when both are combined together. – G. Demecki Jun 02 '15 at 15:40
  • However, Cedric's solution has some drawbacks when working with the TestNG Eclipse Plugin, ver. 5.9.0.4 as it befeore every run of the TestCase shows message that groups are not suppoerted by this plugin. – honzajde Jul 06 '10 at 11:29
33

To address specific scenario in question:

@Test
public void Test1() {

}

@Test (dependsOnMethods={"Test1"})
public void Test2() {

}

@Test (dependsOnMethods={"Test2"})
public void Test3() {

}
user2759895
  • 331
  • 3
  • 3
9
@Test(dependsOnMethods="someBloodyMethod")
user2137872
  • 101
  • 2
  • 2
  • 4
    I might point out this isn't a particularly helpful answer - I suggest expanding on your answers in a little more detail! –  Apr 22 '13 at 21:21
9

If you don't want to use the @Test(priority = ) option in TestNG, you can make use of the javaassist library and TestNG's IMethodInterceptor to prioritize the tests according to the order by which the test methods are defined in the test class. This is based on the solution provided here.

Add this listener to your test class:

package cs.jacob.listeners;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;

import org.testng.IMethodInstance;
import org.testng.IMethodInterceptor;
import org.testng.ITestContext;

public class PriorityInterceptor implements IMethodInterceptor {
    public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {

    Comparator<IMethodInstance> comparator = new Comparator<IMethodInstance>() {
        private int getLineNo(IMethodInstance mi) {
        int result = 0;

        String methodName = mi.getMethod().getConstructorOrMethod().getMethod().getName();
        String className  = mi.getMethod().getConstructorOrMethod().getDeclaringClass().getCanonicalName();
        ClassPool pool    = ClassPool.getDefault();

        try {
            CtClass cc        = pool.get(className);
            CtMethod ctMethod = cc.getDeclaredMethod(methodName);
            result            = ctMethod.getMethodInfo().getLineNumber(0);
        } catch (NotFoundException e) {
            e.printStackTrace();
        }

        return result;
        }

        public int compare(IMethodInstance m1, IMethodInstance m2) {
        return getLineNo(m1) - getLineNo(m2);
        }
    };

    IMethodInstance[] array = methods.toArray(new IMethodInstance[methods.size()]);
    Arrays.sort(array, comparator);
    return Arrays.asList(array);
    }
}

This basically finds out the line numbers of the methods and sorts them by ascending order of their line number, i.e. the order by which they are defined in the class.

jacobcs
  • 539
  • 5
  • 14
8

Use this:

public class TestNG
{
        @BeforeTest
        public void setUp() 
        {
                   /*--Initialize broowsers--*/

        }

        @Test(priority=0)
        public void Login() 
        {

        }

        @Test(priority=2)
        public void Logout() 
        {

        }

        @AfterTest
        public void tearDown() 
        {
                //--Close driver--//

        }

}

Usually TestNG provides number of annotations, We can use @BeforeSuite, @BeforeTest, @BeforeClass for initializing browsers/setup.

We can assign priority if you have written number of test cases in your script and want to execute as per assigned priority then use: @Test(priority=0) starting from 0,1,2,3....

Meanwhile we can group number of test cases and execute it by grouping. for that we will use @Test(Groups='Regression')

At the end like closing the browsers we can use @AfterTest, @AfterSuite, @AfterClass annotations.

Saikat
  • 14,222
  • 20
  • 104
  • 125
Bharat Mane
  • 296
  • 2
  • 12
  • 22
4

If I understand your question correctly in that you want to run tests in a specified order, TestNG IMethodInterceptor can be used. Take a look at http://beust.com/weblog2/archives/000479.html on how to leverage them.

If you want run some preinitialization, take a look at IHookable http://testng.org/javadoc/org/testng/IHookable.html and associated thread http://groups.google.com/group/testng-users/browse_thread/thread/42596505990e8484/3923db2f127a9a9c?lnk=gst&q=IHookable#3923db2f127a9a9c

Kartik
  • 2,541
  • 2
  • 37
  • 59
2

Piggy backing off of user1927494's answer, In case you want to run a single test before all others, you can do this:

@Test()
public void testOrderDoesntMatter_1() {
}

@Test(priority=-1)
public void testToRunFirst() {
}

@Test()
public void testOrderDoesntMatter_2() {
}
Big Gunz
  • 31
  • 3
2

By Specifying test methods to be executed in testNg.xml we can execute the test cases in desired order

<suite>
<test name="selenium1">
   <classes>
   <class name="com.test.SeleniumTest" >
       <methods><include name="methodB"></include>
           <include name="methodA"></include>
       </methods>    
    </class>
  </classes>
 
 </test>
</suite>
seetha
  • 199
  • 2
  • 7
2

An answer with an important explanation:

There are two parameters of "TestNG" who are supposed to determine the order of execution the tests:

@Test(dependsOnGroups= "someGroup")

And:

@Test(dependsOnMethods= "someMethod")

In both cases these functions will depend on the method or group,

But the differences:

In this case:

@Test(dependsOnGroups= "someGroup")

The method will be dependent on the whole group, so it is not necessarily that immediately after the execution of the dependent function, this method will also be executed, but it may occur later in the run and even after other tests run.

It is important to note that in the case and there is more than one use within the same set of tests in this parameter, this is a safe recipe for problems because the dependent methods of the entire set of tests will run first and only then the methods that depend on them.

However, in this case:

@Test(dependsOnMethods= "someMethod")

Even if this parameter is used more than once within the same set of tests, the dependent method will still be executed after the dependent method is executed immediately.

Hope it's clear and helps.

Gavriel Cohen
  • 4,355
  • 34
  • 39
1

By using priority paramenter for @Test we can control the order of test execution.

Madan
  • 141
  • 2
  • 10
1

The ordering of methods in the class file is unpredictable, so you need to either use dependencies or include your methods explicitly in XML.

By default, TestNG will run your tests in the order they are found in the XML file. If you want the classes and methods listed in this file to be run in an unpredictible order, set the preserve-order attribute to false

san1deep2set3hi
  • 4,904
  • 1
  • 23
  • 23
1

I've faced the same issue, the possible reason is due to parallel execution of testng and the solution is to add Priority option or simply update preserve-order="true" in your testng.xml.

<test name="Firefox Test" preserve-order="true">
Tunaki
  • 132,869
  • 46
  • 340
  • 423
Kiran
  • 11
  • 2
  • 1
    preserve-order="true", is default in testng.xml and it works only for the order you defined in testng.xml only, so resolution for your problem is only adding priority to @Tests – Kiran May 20 '16 at 10:17
0

There are ways of executing tests in a given order. Normally though, tests have to be repeatable and independent to guarantee it is testing only the desired functionality and is not dependent on side effects of code outside of what is being tested.

So, to answer your question, you'll need to provide more information such as WHY it is important to run tests in a specific order.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Kelly S. French
  • 12,198
  • 10
  • 63
  • 93
  • 19
    There are many situations where dependencies are useful, especially for integration and functional testing. For example, testing a web site: you want to test the login page first, and then the next page, etc... Clearing and recreating the state from scratch all the time is impractical and leads to very slow tests. Also, dependencies give you much better diagnostics, such as "1 test failed, 99 tests skipped" instead of the traditional "100 tests failed" which doesn't help realize that all these failures are actually because one test failed. – Cedric Beust Apr 19 '10 at 18:40
0

In case you happen to use additional stuff like dependsOnMethods, you may want to define the entire @Test flow in your testng.xml file. AFAIK, the order defined in your suite XML file (testng.xml) will override all other ordering strategies.

Akshay Maldhure
  • 787
  • 2
  • 19
  • 38
0

use: preserve-order="true" enabled="true" that would run test cases in the manner in which you have written.

<suite name="Sanity" verbose="1" parallel="" thread-count="">   
<test name="Automation" preserve-order="true"  enabled="true">
        <listeners>
            <listener class-name="com.yourtest.testNgListner.RetryListener" />
        </listeners>
        <parameter name="BrowserName" value="chrome" />
        <classes>
            <class name="com.yourtest.Suites.InitilizeClass" />
            <class name="com.yourtest.Suites.SurveyTestCases" />
            <methods>
                <include name="valid_Login" />
                <include name="verifyManageSurveyPage" />
                <include name="verifySurveyDesignerPage" />
                <include name="cloneAndDeleteSurvey" />
                <include name="createAndDelete_Responses" />
                <include name="previewSurvey" />
                <include name="verifySurveyLink" />
                <include name="verifySurveyResponses" />
                <include name="verifySurveyReports" />
            </methods>
        </classes>
    </test>
</suite>
Ankit Gupta
  • 776
  • 5
  • 12
-5

Tests like unit tests? What for? Tests HAVE to be independant, otherwise.... you can not run a test individually. If they are independent, why even interfere? Plus - what is an "order" if you run them in multiple threads on multiple cores?

TomTom
  • 61,059
  • 10
  • 88
  • 148
  • 2
    It's actually quite possible to mix dependencies and parallelism, take a look at this article to find out how TestNG does it: http://beust.com/weblog/2009/11/28/hard-core-multicore-with-testng/ – Cedric Beust Apr 19 '10 at 18:41
  • People use JUnit for lots of things besides Unit tests. Almost all of those additional uses have times when you need to do things in a particular order. This is one of the major rationales for developing TestNG, BTW. – Jeffiekins Jan 30 '14 at 17:14
  • While technically correct, it might be convenient sometimes. Assume, you want to have some kind of precondition where some parameters are set. This might be done in the same class and be something that needs testing. However, for all other tests, these preconditions must be set. In that case it is not ok to have it in the setup, as it is technically a test. Though you may not want it in every test method. It's enough to test it once. The other option is to have two test classes with might be inconvenient. Other use case, you may want to test for size==x and also content of individual elements. – patrik Sep 20 '22 at 13:53