TestNG testing framework — Annotations

Arvind Choudhary
4 min readMay 8, 2022
TestNG
TestNG

Introduction of what is TestNG & why we need it?

Please head to — TestNG testing framework — Introduction

What is @DataProvider or how we can pass parameters to @Test method

Please head to TestNG testing framework — Parameterization

Annotations:

TestNG Annotations are used to control the methods to be executed in the test script. Annotations are defined on methods to control how execution flows in the test code. In case any method is not prefixed with annotations, it will be ignored and not be executed as part of the test code.

Types Of Annotations & Description:

TestNG Annotations

Example:

Script

Annotations examples

Output

@BeforeSuite called
@BeforeTest called
@BeforeClass called
@BeforeMethod called
@Test executed
@AfterMethod called
@AfterClass called
@AfterTest called
@AfterSuite called
===============================================
Default Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================

Example with Data-Provider:

@BeforeMethod & @AfterMethod will be executed before every @Test execution

Script

Output

@BeforeSuite called
@BeforeTest called
@BeforeClass called
@BeforeMethod called
@Test executed with value1 = abc value2 = def
@AfterMethod called
@BeforeMethod called
@Test executed with value1 = pqr value2 = xyz
@AfterMethod called

@AfterClass called
@AfterTest called
@AfterSuite called
===============================================
Default Suite
Total tests run: 2, Passes: 2, Failures: 0, Skips: 0
===============================================

Example with Multiple Test Classes inheriting base TestNG class which have all @Before and @After for controlled execution.

@BeforeTest/@AfterTest execution depends on how many <Test> tags you have specified in your testng.xml(example in part-I), if you have more than one <Test> tags your @BeforeTest & @AfterTest will be executed that no. of times.(example in part-II)

Package Structure

  1. TestNGBase — Have all basic control methods like @Before & @After methods.
  2. Runner1 extends TestNGBase and have its own @Test methods.
  3. Runner2 extends TestNGBase and have its own @Test methods.

TestNGBase.java

public class TestNGBase {
@BeforeSuite
public void beforeSuite(){
System.out.println("@BeforeSuite called");
}
@BeforeTest
public void beforeTest(){
System.out.println("@BeforeTest called");
}
@BeforeClass
public void beforeClass(){
System.out.println("@BeforeClass called\t:: "+this.getClass().getName());
}
@BeforeMethod
public void beforeMethod(){
System.out.println("@BeforeMethod called\t:: "+this.getClass().getName());
}
@AfterMethod
public void afterMethod(){
System.out.println("@AfterMethod called\t:: "+this.getClass().getName());
}
@AfterClass
public void afterClass(){
System.out.println("@AfterClass called\t:: "+this.getClass().getName());
}
@AfterTest
public void afterTest(){
System.out.println("@AfterTest called");
}
@AfterSuite
public void afterSuite(){
System.out.println("@AfterSuite called");
}
}

Runner1.java

public class Runner1 extends TestNGBase{
@DataProvider(name = "default")
public Object[][] dataProvider(){
Object[][] obj = new Object[2][2];
obj[0][0] = "abc";
obj[0][1] = "def";
obj[1][0] = "pqr";
obj[1][1] = "xyz";
return obj;
}
@Test(dataProvider = "default")
public void testMethod(String value1,String value2){
System.out.println("@Test executed with value1 = "+value1+" value2 = "+value2+"\t:: "+this.getClass().getName());
}
}

Runner2.java

public class Runner2 extends TestNGBase {
@Test
public void testMethod(){
System.out.println("@Test executed with \t:: "+this.getClass().getName());
}
}

Part — I

Testng.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Practice Suite">
<test name="practice test">
<packages>
<package name="demoPackage.*"></package>
</packages><!-- Package -->
</test> <!-- Test -->
</suite> <!-- Suite -->

Output

@BeforeSuite called
@BeforeTest called
@BeforeClass called :: demoPackage.Runner1
@BeforeMethod called :: demoPackage.Runner1
@Test executed with value1 = abc value2 = def :: demoPackage.Runner1
@AfterMethod called :: demoPackage.Runner1
@BeforeMethod called :: demoPackage.Runner1
@Test executed with value1 = pqr value2 = xyz :: demoPackage.Runner1
@AfterMethod called :: demoPackage.Runner1
@AfterClass called :: demoPackage.Runner1
@BeforeClass called :: demoPackage.Runner2
@BeforeMethod called :: demoPackage.Runner2
@Test executed with :: demoPackage.Runner2
@AfterMethod called :: demoPackage.Runner2
@AfterClass called :: demoPackage.Runner2
@AfterTest called
@AfterSuite called
===============================================
Practice Suite
Total tests run: 3, Passes: 3, Failures: 0, Skips: 0
===============================================

Part — II

Testng.xml

here as you see we have 2 <Test> tags and will in turn will result into execution of @BeforeTest & @AfterTest twice

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Practice Suite">
<test name="practice test1">
<packages>
<package name="demoPackage.*"></package>
</packages>
</test> <!-- Test -->

<test name="practice test2">
<packages>
<package name="demoPackage.*"></package>
</packages>
</test> <!-- Test -->
</suite> <!-- Suite -->

Output

@BeforeSuite called
@BeforeTest called
@BeforeClass called :: demoPackage.Runner1
@BeforeMethod called :: demoPackage.Runner1
@Test executed with value1 = abc value2 = def :: demoPackage.Runner1
@AfterMethod called :: demoPackage.Runner1
@BeforeMethod called :: demoPackage.Runner1
@Test executed with value1 = pqr value2 = xyz :: demoPackage.Runner1
@AfterMethod called :: demoPackage.Runner1
@AfterClass called :: demoPackage.Runner1
@BeforeClass called :: demoPackage.Runner2
@BeforeMethod called :: demoPackage.Runner2
@Test executed with :: demoPackage.Runner2
@AfterMethod called :: demoPackage.Runner2
@AfterClass called :: demoPackage.Runner2
@AfterTest called
@BeforeTest called
@BeforeClass called :: demoPackage.Runner1
@BeforeMethod called :: demoPackage.Runner1
@Test executed with value1 = abc value2 = def :: demoPackage.Runner1
@AfterMethod called :: demoPackage.Runner1
@BeforeMethod called :: demoPackage.Runner1
@Test executed with value1 = pqr value2 = xyz :: demoPackage.Runner1
@AfterMethod called :: demoPackage.Runner1
@AfterClass called :: demoPackage.Runner1
@BeforeClass called :: demoPackage.Runner2
@BeforeMethod called :: demoPackage.Runner2
@Test executed with :: demoPackage.Runner2
@AfterMethod called :: demoPackage.Runner2
@AfterClass called :: demoPackage.Runner2
@AfterTest called
@AfterSuite called
===============================================
Practice Suite
Total tests run: 6, Passes: 6, Failures: 0, Skips: 0
===============================================

I’ll be covering @BeforeGroups & @AfterGroups & few other attributes of @Test method in my next article(will update reference here once article is published).

Thank you for staying along, would appreciate if you could drop review based on what went well and what could have been focused more.

--

--