Selenium WebDriver is one of the most popular frameworks for web automation. To get more from your Selenium WebDriver tests there are many test frameworks, services, and libraries, which help you to organize your tests, monitor their execution, and provide comprehensive reports. This article describes solutions for three aspects in automation testing. Creation of parameterized tests, test execution reports, and logging for Selenium WebDriver.
Parameterized tests are necessary for cases when you need to execute the same suite of tests with different test data. You can write several identical tests, but with different input conditions, but it’s not an optimal solution. What you need is to add parameters for your tests. Thus, one test will be performed several times under different conditions.
Test execution reports help you to present test execution results in a friendly format. The TestNG framework offers a list of tests and statuses corresponding to them. Such statistics give a general idea of the success of the tests. Nevertheless, you may get intermediate results for each stage of tests execution into the reports. To do this, you need to add the Allure framework. It will show not only the statistics of test execution but also step-by-step actions in each test.
Logging in the Selenium WebDriver is a necessary thing for complex multi-step tests for tracking the logic of test case execution. For example, you can connect logging methods, implemented in Log4j library.
All the examples for this article are written in Java, use TestNG framework, Idea IDE and for some test examples, the Maven builder is used.
TestNG parameterized tests
How to launch a few tests with similar parameters
If some parameter is defined for all tests of a project.
Often in web automation, it happens that the same values have to be used in different tests. In this case, one can use the TestNG capacity to define a certain parameter for a test suite in the configuration file. For example, to provide the URL for the Selenium WebDriver method for execution of a test suite. The example of such a test written in TestNG framework is shown here.
[java] public class TestNGParameterExample { @Parameters({“firstSampleParameter”}) @Test(enabled = true) public void firstTestForOneParameter(String firstSampleParameter) { driver.get(firstSampleParameter); WebElement searchBar = driver.findElement(By.linkText(“Mobile Device & Browser Lab”)); searchBar.click(); Assert.assertEquals(driver.findElement(By.tagName(“h1”)).getText(), “Mobile Device & Browser Lab”); } @Parameters({“firstSampleParameter”}) @Test public void secondTestForOneParameter(String firstSampleParameter) { driver.get(firstSampleParameter); WebElement searchBar = driver.findElement(By.linkText(“Live Cross Browser Testing”)); searchBar.click(); Assert.assertEquals(driver.findElement(By.tagName(“h1”)).getText(), “Cross Browser Testing”); } } [/java]
The TestNG.xml file structure is shown below.
[html]
Parameterized tests have to be launched with a builder, for instance, Maven. Now we are going to demonstrate how to feed parameters to the Selenium WebDriver tests with the TestNG test framework.
Selenium WebDriver tests with parameters
Passing simple values to a test.
If you need to create tests, which enable you to process data sets, you can use DataProvider. DataProvider is a method, which returns a two-dimensional array of objects. The first dimension of this array is the number of test launches. The second dimension of this array has to correspond to the number and types of the test parameters.
The method has annotation @DataProvider The example of code on simple test suites is shown here.
[java] @DataProvider() public Object[][] listOfLinks() { return new Object[][] { {“Mobile Device & Browser Lab”, “Mobile Device & Browser Lab”}, {“Live Cross Browser Testing”, “Cross Browser Testing”}, {“Automated Mobile Testing”, “Mobile Test Automation!”}, }; } The test refers to the the dataprovider method with the corresponding name. @Test(dataProvider = “listOfLinks”) public void firstTestWithSimpleData(String linkname, String header) { driver.get(“https://experitest.com/”); WebElement searchBar = driver.findElement(By.linkText(linkname)); searchBar.click(); Assert.assertEquals(driver.findElement(By.tagName(“h1”)).getText(), header); } [/java]
Let’s execute the command mvn clean test and check the execution results.
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 34.23 s – in TestSuite
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ————————————————————————
[INFO] BUILD SUCCESS
Passing iterative objects
The example with passing iterative objects is shown in the code below. In this example (found here) parameters are passed to the test method in the arraylist.
[java] @DataProvider(name = “iterator”) public Iterator
Data from a csv file.
The data required for the test execution can be written to a CSV file. In this case, the same iterative object can be used to pass data to the test. In the DataProvider method, data from the CSV file has to be copied to the ArrayList and then used in the method @Test. Data from the CSV file is read string by string and split by the delimiter char. For the code example let’s use the same data, as they are in the example below, but place them into the data.csv file. The changed code of the test will look in the following way.
[java] @DataProvider(name=”valid”) public Iterator
data.csv structure is shown below:
Mobile Device & Browser Lab; Mobile Device & Browser Lab
Live Cross Browser Testing; Cross Browser Testing
Automated Mobile Testing; Mobile Test Automation
Data from a JSON file
Another format for the test data representation is the JSON format. The approach of feeding test data to tests is to use iterative objects. The only difference from the approaches shown above is that the DataProvider method has to process a JSON file and fill an ArrayList with data from it. For this task, we need to create a class in which JSON array elements will be passed. In the Selenium WebDriver test, we get values as these class instances. For the convenience of working with JSON objects, the library gson is used. The documentation for this library can be found here. Use this dependency section to add it to the maven project.
[html]
For the code example let’s use the same data, as they are in the example below, but place them into the data.JSON file. The changed code of the test will look in the following way.
[java] @DataProvider() public Iterator>(){}.getType()); return data.stream().map((o) -> new Object[] {o}).collect(Collectors.toList()).iterator(); } @Test(dataProvider = “validFromJson”) public void testForJsonData(TestData element) { driver.get(“https://experitest.com/”); WebElement searchBar = driver.findElement(By.linkText(element.getLink())); searchBar.click(); Assert.assertEquals(driver.findElement(By.tagName(“h1”)).getText(), element.getHeader()); } data.json file structure is shown below: [ {“link”: “Mobile Device & Browser Lab”, “header”: “Mobile Device & Browser Lab”}, {“link”: “Live Cross Browser Testing”, “header”: “Cross Browser Testing”}, {“link”: “Automated Mobile Testing”, “header”: “Mobile Test Automation”} ] TestData class is presented below. @Expose annotation indicates that this element has to be available for JSON serialization and deserialization. import com.google.gson.annotations.Expose; public class TestData { @Expose String link; @Expose String header; public String getLink() { return link; } public String getHeader() { return header; } } [/java]
Test report with Allure
After you have a considerable number of Selenium WebDriver tests you need to find an instrument to control their execution results. As a rule, you are interested in information about successful tests, and the number of tests whose execution finished with a failure. This basic information can be provided by the TestNG framework. It can be connected to your project from the Maven repository. Comprehensive documentation for the framework can be found at this link. After the tests are executed, an XML document with the execution results is formed and an HTML document for their presentation is created.
For example, we have three tests. Two of them are passed and one fails. After tests are executed the execution result will be printed out to the IDE console.
[INFO] Results:
[INFO]
[ERROR] Failures:
[ERROR] TestNGReport.testLink(TestNGReport)
[INFO] Run 1: PASS
[INFO] Run 2: PASS
[ERROR] Run 3: TestNGReport.testLink:39 expected [Mobile Test Automation!] but found [Mobile Test Automation]
[INFO]
[INFO]
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
[INFO]
[INFO] ————————————————————————
[INFO] BUILD FAILURE
TestNG also created a report and it can be found in /target/surefire-reports/index.html folder.
TestNG shows the list of tests which failed and their number, string in the test code where the error occurred and the error description. However, if we want to trace the tests execution step by step and get the statistics on test groups, statistics of tests execution, download the test execution results in CSV format, it’s recommended to connect your tests to the Allure framework and use it.
Allure – is a framework for displaying the test execution results and for generating test execution reports. If we use the maven builder, the Allure library has to be defined in the dependency section of the maven pom.xml file.
In the build section of the pom.xml file, we need to provide a path to the testng.xml file, which has the description of tests to be launched. In the file allure.properties we need to define a path to the folder with allure report as one of the parameters.
allure.results.directory=target/allure-results
The resulting pom.xml file with dependency and build sections is shown here.
[html]
To demonstrate the displaying of a test execution steps, let’s create the test, using the data provider in which each step is described with the method @Step. Each test step description should be added in parameters. The code of the test is shown here.
[java] @DataProvider() public Object[][] listOfLinks() { return new Object[][] { {“Mobile Device & Browser Lab”, “Mobile Device & Browser Lab”}, {“Live Cross Browser Testing”, “Cross Browser Testing”}, {“Automated Mobile Testing”, “Mobile Test Automation!”}, }; } @Test(dataProvider = “listOfLinks”) public void testLink(String linkname, String header) { goToLink(); clickLinkText(linkname); Assert.assertEquals(driver.findElement(By.tagName(“h1”)).getText(), header); } @Step(“Go to URI https://experitest.com”) public void goToLink() { driver.get(“https://experitest.com/”); } @Step(“Click link on the page”) public void clickLinkText(String linkname) { WebElement searchBar = driver.findElement(By.linkText(linkname)); searchBar.click(); } [/java]
Use mvn clean test command typed in the console to launch the test.
Test execution results will appear in the folder target/allure-results. To generate a report and open the Allure page, execute the command, typed in the console: allure serve target/allure-results. The main page of the Allure report shows the statistics of test executions, distribution tests over tests suites and categories.
You may navigate to the section with the list of tests. The statistics of the executed tests, each test execution time, list of parameters for each test, and test groupings are shown there as well.
Going to a specific test you may see a lot of information related to the test: A list of steps, the execution time of each step, status, category, list of parameters, error messages for a failed test and other information.
In this part, we discussed the basic set of Allure framework properties. Besides getting reports on the local environment, you may integrate it with Jenkins and use for continuous integration.
Generating log files in Selenium WebDriver tests
Let’s imagine that we have a complex set of Selenium WebDriver tests, and it’s necessary to track the status of both the tests themselves and the individual steps while the Webdriver is running. Perhaps we will need not only to display messages in the console but also to keep a full-fledged journal about what is happening in our test. To achieve these goals, we will use log4j. Below is an example of using the log4j library.
Create a set of primitive tests. To do this, create a class LogTest.
[java]import org.openqa.selenium.*; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; public class LogTest { WebDriver driver = new ChromeDriver(); WebDriverWait wait = new WebDriverWait(driver, 60); @BeforeTest public void beforeTest() { System.setProperty(“webdriver.chrome.driver”,”F:\Jenkins\workspace\chromedriver.exe”); // <-- Change this path System.out.println("Test started"); } @Test public void Experitest1(){ String expectedText = "Last updated: 22 May 2018"; String actualText = ""; driver.get("https://experitest.com/legal"); wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[2]/div/div/p[3]/span"))); actualText = driver.findElement(By.xpath("//div[2]/div/div/p[3]/span")).getText(); if (actualText.contentEquals(expectedText)){ System.out.println("1st TEST PASSED!"); } else { System.out.println("1st TEST FAILED"); } } @Test public void Experitest2(){ String expectedTitle = "experitest.com"; String actualTitle = ""; driver.get("https://experitest.com/free-trial/"); actualTitle = driver.getTitle(); if (actualTitle.contentEquals(expectedTitle)){ System.out.println("2nd TEST PASSED!"); } else { System.out.println("2nd TEST FAILED"); } } @Test public void Experitest3() { String expectedTitle = "experitest.com"; String actualTitle = ""; driver.get("https://experitest.com/pricing"); wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id="starter""]""))).click(); actualTitle = driver.getTitle(); actualTitle.contentEquals(expectedTitle); if (actualTitle.contentEquals(expectedTitle)){ System.out.println(""3rd TEST PASSED!""); } else { System.out.println(""3rd TEST FAILED""); } } @Test public void Experitest4(){ wait.until(ExpectedConditions.elementToBeClickable(By.xpath(""/html/body/div[1]/div/div/div/div[3]/a""))).click(); Boolean isPresent = driver.findElements(By.xpath(""/html/body/section/div/div[3]/div/div[2]/div"")).size() > 0; if (isPresent){ System.out.println(“”4th TEST PASSED!””); } else { System.out.println(“”4th TEST FAILED””); } } @AfterTest public void afterTest(){ driver.quit(); System.out.println(“”Test complete!””); } } [/java] [html] And also create TestNG config file:
Launch these tests and you will see the following information in the IDE console:
As you can see
Are you ready to scale your enterprise?
Explore
What's New In The World of Digital.ai
100% Test Automation Might Be Desirable, But Is It Practical?
Discover the challenges and value of test automation in achieving 100% coverage for continuous testing. Find the right balance for effective software development.
Digital.ai Continuous Testing, Now Supports Testing on iOS 17 (Beta) Devices
Digital.ai Continuous Testing is the first to support a new operating system version. iOS 17 (Beta) has been released – Discover the new features and see how it works with a demo below.
Ensuring Quality: Digital.ai Continuous Testing Honored with a DevOps Dozen Award
Digital.ai Continuous Testing wins Best Testing Service/Tool at the DevOps Dozen Awards 2022, recognizing their exceptional code quality assurance and innovation.