55

As we know from official TestNG documentation:

@BeforeClass: The annotated method will be run before the first test method in the current class is invoked.

@BeforeTest: The annotated method will be run before any test method belonging to the classes inside the <test> tag is run.

Both the above TestNG annotations look similar in functionality. Can anyone explain the unique difference?

Nathan
  • 8,093
  • 8
  • 50
  • 76
Prashanth Sams
  • 19,677
  • 20
  • 102
  • 125
  • Once per class vs once per testcase, you can have several testcases in one class i think? – Dude Jun 02 '15 at 05:58
  • Both the annotations used to initiate before executing all the testcases. This is the similarity. Anything unique apart from this? – Prashanth Sams Jun 02 '15 at 06:18
  • 1
    you have 1 Testclass, with 3 Testmethods:`@BeforeClass` will be executed once, `@BeforeTest` will be executed 3 times. thats the difference. `@BeforeClass` can be used to set up the test environment, `@BeforeTest` can be used to clean data or setup data etc... – Dude Jun 02 '15 at 06:38
  • 6
    @Dude if so, what '@BeforeMethod' does? actually both the '@BeforeClass' and '@BeforeTest' will be executed once :) '@BeforeMethod' will be executed 3 times. Yes, data clean is the main thing. – Prashanth Sams Jun 02 '15 at 10:16
  • okay i was wrong, but the answer made it very clear, perfect – Dude Jun 02 '15 at 11:23

8 Answers8

162

SeleniumAbstractTest.class

public abstract class SeleniumAbstractTest {

  @BeforeSuite
  public void beforeSuite() {
    System.out.println("BeforeSuite");
  }

  @BeforeTest
  public void beforeTest() {
    System.out.println("BeforeTest");
  }

  @BeforeClass
  public void beforeClass() {
    System.out.println("BeforeClass");
  }

  @BeforeMethod
  public void beforeMethod() {
    System.out.println("BeforeMethod");
  }

  @AfterMethod
  public void afterMethod() {
    System.out.println("AfterMethod");
  }

  @AfterClass
  public void afterClass() {
    System.out.println("AfterClass");
  }

  @AfterTest
  public void afterTest() {
    System.out.println("AfterTest");
  }

  @AfterSuite
  public void afterSuite() {
    System.out.println("AfterSuite");
  }

}

MyTestClass1.class

public class MyTestClass1 extends SeleniumAbstractTest {
  
  @Test
  public void myTestMethod1() {
    System.out.println("myTestMethod1");
  }

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

MyTestClass2.class

public class MyTestClass2 extends SeleniumAbstractTest {
  
  @Test
  public void myTestMethod3() {
    System.out.println("myTestMethod3");
  }

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

If you have the following Test Suite...

<suite name="Suite">
  <test name="Test1" >
    <classes>
       <class name="MyTestClass2" />
    </classes>
  </test>
 
  <test name="Test2">
    <classes>
      <class name="MyTestClass1"/>
      <class name="MyTestClass2"/>
    </classes>
  </test>
</suite>

... then the output [indented for easy reading] will be

BeforeSuite
'   BeforeTest
'   '   BeforeClass
'   '   '   BeforeMethod
'   '   '   '   myTestMethod3
'   '   '   AfterMethod
'   '   '   BeforeMethod
'   '   '   '   myTestMethod4
'   '   '   AfterMethod
'   '   AfterClass
'   AfterTest
'   BeforeTest
'   '   BeforeClass
'   '   '   BeforeMethod
'   '   '   '   myTestMethod1
'   '   '   AfterMethod
'   '   '   BeforeMethod
'   '   '   '   myTestMethod2
'   '   '   AfterMethod
'   '   AfterClass
'   '   BeforeClass
'   '   '   BeforeMethod
'   '   '   '   myTestMethod3
'   '   '   AfterMethod
'   '   '   BeforeMethod
'   '   '   '   myTestMethod4
'   '   '   AfterMethod
'   '   AfterClass
'   AfterTest
AfterSuite
starball
  • 20,030
  • 7
  • 43
  • 238
peetya
  • 3,578
  • 2
  • 16
  • 30
11

@BeforeMethod - executes before every test method e.g. The Method which uses @Test annotation

@BeforeTest - executes only before tag given in testng.xml file.

In a nutshell, @BeforeMethod works on test defined in Java classes. And @BeforeTest works on test defined in testng.xml i.e XML files.

Dinesh Nikam
  • 119
  • 1
  • 3
10

Before explaining the difference, first this is some testing terminologies

Test suite – Consists of one or more test tags.

Test tag - Consists of one or more test classes.

Test class – Consists of one or more methods.

for examble

<suite name="suit1">
  <test name="TestTag1">
    <classes>
      <class name="TestClass1"/>
    </classes>
  </test>
  <test name="TestTag2">
    <classes>
      <class name="TestClass2"/>
      <class name="TestClass3"/>
    </classes>
  </test>
</suite>

@BeforeTest : It will be called Only one time before any test tag, no matter how many test classes inside that tag or how many method annotated with @Test, it will be called only one time for each test tag,in the previous XML example @BeforeTest will be called twice, one time beforeTestTag1 the second time before TestTag2 so it can be used to initialize common objects between different test classes inside one test tag.

@BeforeClass : It will be called Only one time before any test class, no matter how many method annotated with @Test inside this test class, it will be called only one time for each test class,in the previous XML example @BeforeClass will be called three times, one time beforeTestClass1 the second time before TestClass2 and the third time before TestClass3 so it can be used to initialize common objects between different test methods inside one test class.

@BeforeSuite will be called once for the suit1 suit

the order of calls will be as follow

@BeforeSuite
    @BeforeTest
        @BeforeClass
            @BeforeMethod
                @Test

To know more about @BeforeMethod, please refer to the answer https://stackoverflow.com/a/52331616/1973933

Melad Basilius
  • 3,847
  • 10
  • 44
  • 81
2

This is the TestNG hierarchy: Test Suite -> Test -> Class -> Method

@BeforeTest is executed once before the execution of all methods in all classes within test tag.

on the other hand;

@BeforeClass is executed once before the execution of all methods within the class it is defined.

I have uploaded the script on my GitHub Profile. Here is a link for same. Please give a thumbs up if you like.

Please have a look at github:

Gaurav Khurana
  • 3,423
  • 2
  • 29
  • 38
1

if you extend from another class this are the results:

parentTest - BeforeTest- parent     
testClass1 - BeforeTest- test1    
parentTest - BeforeClass- parent    
testClass1 - BeforeClass- test1    
parentTest - BeforeMethod- parent    
testClass1 - BeforeMethod- test1    
testClass1 - myTestMethod1    
testClass1 - AfterMethod- test1    
parentTest - AfterMethod- parent    
parentTest - BeforeMethod- parent    
testClass1 - BeforeMethod- test1    
testClass1 - myTestMethod2    
testClass1 - AfterMethod- test1    
parentTest - AfterMethod- parent
testClass1 - AfterClass- test1    
parentTest - AfterClass- parent
testClass1 - AfterTest- test1
parentTest – AfterTest- parent
David_Garcia
  • 622
  • 7
  • 15
1

My opinions:

@BeforeClass:The annotated method will be run before the first test method in the current class is invoked

@BeforeTest:The annotated method will be run before any test method in the current suite is run

MorganChen
  • 37
  • 3
0
@BeforeClass: The annotated method will be run before the first test method in the current class is invoked. 
@BeforeMethod: The annotated method will be run before each test method.

The annotations above will also be honored (inherited) when placed on a superclass of a TestNG class. This is useful for example to centralize test setup for multiple test classes in a common superclass.

In that case, TestNG guarantees that the "@Before" methods are executed in inheritance order (highest superclass first, then going down the inheritance chain), and the "@After" methods in reverse order (going up the inheritance chain).

To know more about TestNG annotations: https://testng.org/doc/documentation-main.html#annotations

0

What is missing in the above answers is the usage difference between @BeforeClass and @BeforeTest annotations.

As it is clear that the method (most commonly the setup method) annotated with @BeforeClass will execute only once before all the testcases written in the class. And the method annotated with '@BeforeTest' will execute before every testcase regardless of their count/sequence/underline logic.

Therefore, @BeforeClass is used when our method has long calls with long execution time and the output of these calls will be unchanged by any of the testcases. For example, getting an API response in the setup method, which will be used by all the tests. Whereas, @BeforeTest@ is used when we need to do some cleanup stuff, and every test needs some fresh resource to start with. For example, one newly created order etc.

Iqra.
  • 685
  • 1
  • 7
  • 18