Difference between BeforeClass and BeforeTest in TestNG

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


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

Hope it helps :)


@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.