📜 ⬆️ ⬇️

TestNG annotation guide for Selenium WebDriver

Peace, labor, May, habrovchane! For those who, like us, broke into the inter-holiday working week, we prepared a translation that we want to coincide with the start of the recruitment course for the “Java QA Engineer” , which is scheduled to start on May 28th.



TestNG is a test framework created by Cédric Beust , it helps us to meet many of our testing needs. TestNG is widely used with Selenium. Want to know what NG means? This means “Next Generation” . TestNG is similar to JUnit, but it is more powerful when it comes to managing the flow of your program. The framework architecture helps us make tests more structured and provide better validation points.
')
Some features of TestNG that deserve attention:


Typically, the testing process using TestNG includes the following steps:



Before proceeding to TestNG annotations for Selenium, let us designate the prerequisites for setting up TestNG.

Prerequisites:


Note: Java annotations can only be used with Java version 1.5 and higher.

If you are new to TestNG, then look at the article on how to run the first automation script with TestNG .

So what is annotation?

An annotation is a label that provides additional information about a class or method ( Translator's Note: in java, annotations can be used not only for classes and methods, but also for other elements ). For annotations use the prefix "@". TestNG uses annotations to help create a robust test structure. Let's look at TestNG annotations used to automate testing with Selenium.


@Test

This is the most important annotation in TestNG, which contains the main logic of the test . All automated functions are in the method annotated with @Test . It has various attributes with which the start method can be configured.

The sample code below checks the url transition:

 @Test public void testCurrentUrl() throws InterruptedException { driver.findElement(By.xpath("//*[@id='app']/header/aside/ul/li[4]/a")) .click(); String currentUrl = driver.getCurrentUrl(); assertEquals( currentUrl, "https://automation.lambdatest.com/timeline/?viewType=build&page=1", "url did not matched"); } 

@BeforeTest

The method with this annotation is launched before the launch of the first method with the annotation @Test . (Translator’s note: as part of a test defined in the test section of the xml configuration file) . You can use this annotation in TestNG with Selenium to configure your browser. For example, launch a browser and expand it to full screen, set specific browser settings, etc.

Below is an example for BeforeTest, in which the browser is expanded to full screen:

 @BeforeTest public void profileSetup() { driver.manage().window().maximize(); } 

@AfterTest

The methods marked with this annotation are run after all the @Test methods of your test. ( Translator's note: in the framework of the test defined in the test section in the xml configuration file, the “current class” is not quite correctly written in the original ). This is a useful summary that is useful for providing test results. You can use this annotation to create a report on your tests and send it to interested parties by email.

Code example:

 @AfterTest public void reportReady() { System.out.println("Report is ready to be shared, with screenshots of tests"); } 

@BeforeMethod

Methods with this annotation are run before each @Test method . You can use it to test the connection to the database before running the test. Or, for example, when testing functionality that is dependent on the user's login, put the login code here.
Below is a code snippet showing the entrance to LambdaTest:

 @BeforeMethod public void checkLogin() { driver.get("https://accounts.lambdatest.com/login"); driver.findElement(By.xpath("//input[@name='email']")).sendKeys("sadhvisingh24@gmail.com"); driver.findElement(By.xpath("//input[@name='password']")).sendKeys("activa9049"); driver.findElement(By.xpath("//*[@id='app']/section/form/div/div/button")).click(); } 

@AfterMethod

Methods with this annotation are run after each @Test method . This annotation can be used to create screenshots each time a test is run.
Below is a code snippet showing how to get a screenshot:

 @AfterMethod public void screenShot() throws IOException { TakesScreenshot scr = ((TakesScreenshot) driver); File file1 = scr.getScreenshotAs(OutputType.FILE); FileUtils.copyFile(file1, new File(":\\test-output\\test1.PNG")); } 

@BeforeClass

The method with this annotation will be executed before the first test method in the current class. This annotation can be used to set browser properties, initialize the driver, open the browser with the desired URL, etc.

Sample code for BeforeClass:

 @BeforeClass public void appSetup() { driver.get(url); } 

@AfterClass

The method with this annotation will be executed after the last test method in the current class. This annotation in TestNG can be used to perform resource cleanup actions after running a test, such as closing a driver, etc.
Below is an example of a snippet of code showing the closing of the driver:

 @AfterClass public void closeUp() { driver.close(); } 

@BeforeSuite

A suite of tests (suite) can consist of several classes, this annotation is run before all test methods of all classes. This annotation marks the entry point at startup. @BeforeSuite can use the @BeforeSuite in TestNG to perform common functions, such as setting up and running Selenium or remote web drivers, etc.
An example of the @BeforeSuite annotation in TestNG, demonstrating driver setup:

 @BeforeSuite public void setUp() { System.setProperty( "webdriver.chrome.driver", ":\\selenium\\chromedriver.exe"); driver = new ChromeDriver(); } 

@AfterSuite

This annotation in TestNG runs after running all test methods in all classes. This annotation can be used to clean up before completing tests, when you use several classes, for example, closing drivers, etc.
Below is the code snippet for the @AfterSuite annotation in TestNG for Selenium:

 @AfterSuite public void cleanUp() { System.out.println("All close up activities completed"); } 

@BeforeGroups

TestNG can group tests into groups using the group attribute in the @Test annotation. For example, if you want all similar user-related functions to be combined together, you can mark tests, such as the dashboard (user panel), profile (profile), transactions (transactions) and the like, into one group, such as user_management. The @BeforeGroups in TestNG helps to run certain actions in front of a specified group of tests. This annotation can be used if the group focuses on the same functionality, as indicated in the example above. The @BeforeGroup may contain a login function that is required to run tests in a group, for example, testing a user panel, user profile, etc.

An example of using @BeforeGroups :

 @BeforeGroups("urlValidation") public void setUpSecurity() { System.out.println("url validation test starting"); } 

@AfterGroups

This annotation is run after the execution of all test methods of the specified group.

Sample code for the @AfterGroups annotation in TestNG for Selenium:

 @AfterGroups("urlValidation") public void tearDownSecurity() { System.out.println("url validation test finished"); } 

Example

The code below shows examples of using all of the annotations discussed above:

 import org.apache.commons.io.FileUtils; import org.openqa.selenium.By; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.annotations.*; import java.io.File; import java.io.IOException; import java.util.concurrent.TimeUnit; import static org.testng.Assert.assertEquals; public class AnnotationsTestNG { private WebDriver driver; private String url = "https://www.lambdatest.com/"; @BeforeSuite public void setUp() { System.setProperty( "webdriver.chrome.driver", ":\\selenium\\chromedriver.exe"); driver = new ChromeDriver(); driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS); System.out.println("The setup process is completed"); } @BeforeTest public void profileSetup() { driver.manage().window().maximize(); System.out.println("The profile setup process is completed"); } @BeforeClass public void appSetup() { driver.get(url); System.out.println("The app setup process is completed"); } @BeforeMethod public void checkLogin() { driver.get("https://accounts.lambdatest.com/login"); driver.findElement(By.xpath("//input[@name='email']")).sendKeys("sadhvisingh24@gmail.com"); driver.findElement(By.xpath("//input[@name='password']")).sendKeys("activa9049"); driver.findElement(By.xpath("//*[@id='app']/section/form/div/div/button")).click(); System.out.println("The login process on lamdatest is completed"); } @Test(groups = "urlValidation") public void testCurrentUrl() throws InterruptedException { driver.findElement(By.xpath("//*[@id='app']/header/aside/ul/li[4]/a")).click(); Thread.sleep(6000); String currentUrl = driver.getCurrentUrl(); assertEquals(currentUrl, "https://automation.lambdatest.com/timeline/?viewType=build&page=1", "url did not matched"); System.out.println("The url validation test is completed"); } @AfterMethod public void screenShot() throws IOException { TakesScreenshot scr = ((TakesScreenshot) driver); File file1 = scr.getScreenshotAs(OutputType.FILE); FileUtils.copyFile(file1, new File(":\\test-output\\test1.PNG")); System.out.println("Screenshot of the test is taken"); } @AfterClass public void closeUp() { driver.close(); System.out.println("The close_up process is completed"); } @AfterTest public void reportReady() { System.out.println("Report is ready to be shared, with screenshots of tests"); } @AfterSuite public void cleanUp() { System.out.println("All close up activities completed"); } @BeforeGroups("urlValidation") public void setUpSecurity() { System.out.println("url validation test starting"); } @AfterGroups("urlValidation") public void tearDownSecurity() { System.out.println("url validation test finished"); } } 

TestNG Report:



Output to console:



Translator's Note:

  • To run the test, change the path to chromedriver.exe in the setUp () method and the path to the folder with the screenShot () method. Also for successful test execution in the checkLogin () method there must be a valid login and password.
  • Used maven dependencies:

 <dependencies> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.14.3</version> <scope>test</scope> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-chrome-driver</artifactId> <version>3.141.59</version> <scope>test</scope> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> <scope>test</scope> </dependency> </dependencies> 
TestNG annotation execution sequence for Selenium

The annotations described above are executed in runtime in the following order:


Here is the order of their execution:



Attributes Used With TestNG Annotations

TestNG annotations have attributes that you can use to customize. They help to customize the order of execution of test methods.

These attributes are:


The above attributes are used with annotations in TestNG c Selenium. Below is a code snippet showing the use of the above attributes:

 import static org.testng.Assert.assertEquals; import java.io.File; import java.io.IOException; import org.apache.commons.io.FileUtils; import org.openqa.selenium.By; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.annotations.AfterClass; import org.testng.annotations.AfterGroups; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterSuite; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeSuite; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; public class AnnotationsTest { private WebDriver driver; private String url = "https://www.lambdatest.com/"; @BeforeSuite public void setUp() { System.setProperty( "webdriver.chrome.driver", ":\\selenium\\chromedriver.exe"); driver = new ChromeDriver(); System.out.println("The setup process is completed"); } @BeforeTest public void profileSetup() { driver.manage().window().maximize(); System.out.println("The profile setup process is completed"); } @BeforeClass public void appSetup() { driver.get(url); System.out.println("The app setup process is completed"); } @Test(priority = 2) public void checkLogin() { driver.get("https://accounts.lambdatest.com/login"); driver.findElement(By.xpath("//input[@name='email']")).sendKeys("sadhvisingh24@gmail.com"); driver.findElement(By.xpath("//input[@name='password']")).sendKeys("xxxxx"); driver.findElement(By.xpath("//*[@id='app']/section/form/div/div/button")).click(); System.out.println("The login process on lamdatest is completed"); } @Test(priority = 0, description = "this test validates the sign-up test") public void signUp() throws InterruptedException { WebElement link = driver.findElement(By.xpath("//a[text()='Free Sign Up']")); link.click(); WebElement organization = driver.findElement(By.xpath("//input[@name='organization_name']")); organization.sendKeys("LambdaTest"); WebElement firstName = driver.findElement(By.xpath("//input[@name='name']")); firstName.sendKeys("Test"); WebElement email = driver.findElement(By.xpath("//input[@name='email']")); email.sendKeys("User622@gmail.com"); WebElement password = driver.findElement(By.xpath("//input[@name='password']")); password.sendKeys("TestUser123"); WebElement phoneNumber = driver.findElement(By.xpath("//input[@name='phone']")); phoneNumber.sendKeys("9412262090"); WebElement termsOfService = driver.findElement(By.xpath("//input[@name='terms_of_service']")); termsOfService.click(); WebElement button = driver.findElement(By.xpath("//button[text()='Signup']")); button.click(); } @Test(priority = 3, alwaysRun = true, dependsOnMethods = "check_login", description = "this test validates the URL post logging in", groups = "url_validation") public void testCurrentUrl() throws InterruptedException { driver.findElement(By.xpath("//*[@id='app']/header/aside/ul/li[4]/a")).click(); String currentUrl = driver.getCurrentUrl(); assertEquals( currentUrl, "https://automation.lambdatest.com/timeline/?viewType=build&page=1", "url did not matched"); System.out.println("The url validation test is completed"); } @Test(priority = 1, description = "this test validates the logout functionality", timeOut = 25000) public void logout() throws InterruptedException { Thread.sleep(6500); driver.findElement(By.xpath("//*[@id='userName']")).click(); driver.findElement(By.xpath("//*[@id='navbarSupportedContent']/ul[2]/li/div/a[5]")).click(); } @Test(enabled = false) public void skipMethod() { System.out.println("this method will be skipped from the test run using the attribute enabled=false"); } @Test(priority = 6, invocationCount = 5, invocationTimeOut = 20) public void invocationcountShowCaseMethod() { System.out.println("this method will be executed by 5 times"); } @AfterMethod() public void screenshot() throws IOException { TakesScreenshot scr = ((TakesScreenshot) driver); File file1 = scr.getScreenshotAs(OutputType.FILE); FileUtils.copyFile(file1, new File(":\\test-output\\test1.PNG")); System.out.println("Screenshot of the test is taken"); } @AfterClass public void closeUp() { driver.close(); System.out.println("The close_up process is completed"); } @AfterTest public void reportReady() { System.out.println("Report is ready to be shared, with screenshots of tests"); } @AfterSuite public void cleanUp() { System.out.println("All close up activities completed"); } @BeforeGroups("urlValidation") public void setUpSecurity() { System.out.println("url validation test starting"); } @AfterGroups("urlValidation") public void tearDownSecurity() { System.out.println("url validation test finished"); } } 

Console output:



TestNG report:



Additional annotations in TestNG

There are some more useful annotations that will help us achieve the desired goals.

@DataProvider

The method with this annotation is used to provide data to a test method in which the dataProvider attribute is specified. This method helps in creating tests driven by data to which multiple sets of input values ​​can be passed. The method must return a two-dimensional array or object.

The @DataProvider annotation has two attributes:


The example below shows the use of the @DataProvider annotation with the given name and parallel attributes.

 @DataProvider(name = "SetEnvironment", parallel = true) public Object[][] getData() { Object[][] browserProperty = new Object[][]{ {Platform.WIN8, "chrome", "70.0"}, {Platform.WIN8, "chrome", "71.0"} }; return browserProperty; } 

@Factory

This annotation helps you run multiple test classes through a single test class. Simply put, it defines and creates tests dynamically.

The following code snippet shows the use of the @Factory annotation, which helps to invoke test class methods.

 import org.testng.annotations.Test; import org.testng.annotations.Factory; class FactorySimplyTest1 { @Test public void testMethod1() { System.out.println("This is to test for method 1 for Factor Annotation"); } } class FactorySimpleTest2 { @Test public void testMethod2() { System.out.println("This is to test for method 2 for Factor Annotation"); } } public class FactoryAnnotation { @Factory() @Test public Object[] getTestFactoryMethod() { Object[] factoryTest = new Object[2]; factoryTest[0] = new FactorySimplyTest1(); factoryTest[1] = new FactorySimpleTest2(); return factoryTest; } } 

Console output:



@Parameters

This annotation allows you to pass parameters to your tests through the TestNG.xml file. This is useful when you need to transfer a limited amount of data to your tests. In the case of complex and large data sets, it is better to use the @DataProvider or Excel annotation.

Example of use:

 @Parameters({"username", "password"}) @Test() public void checkLogin(String username, String password) { driver.get("https://accounts.lambdatest.com/login"); driver.findElement(By.xpath("//input[@name='email']")).sendKeys(username); driver.findElement(By.xpath("//input[@name='password']")).sendKeys(password); driver.findElement(By.xpath("//*[@id='app']/section/form/div/div/button")).click(); System.out.println("The login process on lamdatest is completed"); } 

In the TestNG.xml file, the parameters are defined as follows:

 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="Suite"> <test thread-count="5" name="Annotations"> <parameter name="username" value="sadhvisingh24@gmail.com" /> <parameter name="password" value="XXXXX" /> <classes> <class name="Parameter_annotation"/> </classes> </test> <!-- Annotations --> </suite> <!-- Suite --> 

@Listener

This annotation helps with logging and reporting. There are several “listeners”:


But the description of these listeners and their use will be left for another article.

That's all!

The key point to consider when working with all of these annotations and attributes is that you need to use Java version 1.5 or higher, since annotations are not supported in earlier versions of java.

All the above annotations and attributes of TestNG help to improve the structure and readability of the code. This helps to provide detailed reports that make status reports easier and more useful. The use of these annotations in TestNG for Selenium depends entirely on your business requirements. Therefore, choosing the right annotations and using them correctly is important. You can try these annotations in TestNG on the LambdaTest Selenium Grid right now!

Those who read up to the end are invited to a free open webinar , which our teacher, Dmitry Eremin , will be already on May 14th. Well, according to the established tradition, we are waiting for your comments, friends.

Source: https://habr.com/ru/post/450872/


All Articles