Before discussing Data-driven framework, let’s understand why do we need Framework for Test Automation?
A Test Automation framework is a set of assumptions, concepts, and practices that provide support for automated software testing. It is simply an execution environment for automated tests. Framework empowers testers to write valuable tests that are reusable, maintainable, scalable and resilient across all the browsers. Once the framework is created it can be used across the projects in an organization with few changes in configuration, test data & object repository. It helps in fast execution with minimal human intervention. A nontechnical user can write scripts with proper documentation.
Below are the popular Test Automation frameworks:
In this article, we will see how to automate the test scenario of login page of SenchaTutorials application with the Data-Driven framework.
Prerequisites
- Eclipse IDE
- Java
- TestNG
- Install Maven in eclipse
- Firefox browser
- Selenium Webdriver (supports all major browsers. We will use Firefox, Chrome, and IE)
- Apache POI to perform operations with excel like read, write and update excel sheet
Getting Started
Data Driven framework is used to drive the test cases and suite from an external data feed. The data feed can be data sheets like xls, xlsx, and csv files.
TestNG is a testing framework created in line with the Junit, but with more features that makes it suitable for use in regression test automation projects. Data Provider is one such feature in TestNG. It allows a test method to be executed with multiple sets of data.
In this article, we will look at the process involved in using the Data Provider feature for supplying the test data from an excel sheet to a test method. In the article we will cover the following:
- Architecture for Data Driven Framework.
- What is a Data Provider?
- Test Scenario for login page
- How to provide Multiple sets of data to a Test method using DataProvider.
- Fetching data from Excel sheet using Data provider.
1) Architecture for Data Driven testing
The above diagram explains the architecture of data-driven framework, where Selenium Web Driver interacts with Application Under Test (AUT), locates the elements specified in automated test scripts and performs the actions. The advantage of TestNG framework with Maven is that it is able to create HTML reports. Data is read from Excel sheets and to read the data from Excel we use Apache POI library.
2) TestNg Data Provider
Data Provider is a method used for supplying the test data to a test method. It is used to test the App with multiple sets of data. The Data-driven concept is achieved by @Data Provider annotation in TestNG.
Data Provider returns a two-dimensional object to a test method. To supply the data for the test method it can be specified with an attribute “name” or if we do not specify the attribute “name” then the Data Provider name will be same as the corresponding method name.
Sample Data Provider with attribute name
1 2 3 4 5 6 7 |
@DataProvider(name=”loginData”) public String[][] testLogin(){ Object[][] data = new Object[1][2]; data[0][0] = "username1@gmail.com"; data[0][1] = "pssword1"; return data; } |
Sample Data Provider without attribute name
1 2 3 4 5 6 7 |
@DataProvider() public String[][] testLogin(){ Object[][] data = new Object[1][2]; data[0][0] = "username1@gmail.com"; data[0][1] = "pssword1"; return data; } |
3) Test Scenario for login page
1.Visit the login form of SenchaTutorials (http://senchatutorials.in/)
2.Find the login form’s username field and input text
3.Find the login form’s password field and input text
4.Find the submit button and click it
Expected Result: User shall login successfully and see the home page.
4) How to provide multiple sets of data to a test method using DataProvider
The below code explains a test case where we test the “Sencha Tutorials” login Page with multiple sets of data using Data Provider.
We have two functions in this example:
- getData()
- testSenchaLogin()
getData() is the DataProvider function that is sending out test data in the form of an array of array of objects (object[][]). The test method testSenchaLogin() hooks onto the DataProvider by declaring that its data should be supplied by the DataProvider named “getData”.
testSenchaLogin() is the function, which contains the parameters for fetching data from DataProvider. It can contain conditions, loops, selenium commands, etc. Here we are having the parameters that match with an array in DataProvider and also the required selenium commands that need to be performed on the application.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
package DataProvider; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.AfterSuite; import org.testng.annotations.BeforeSuite; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; public class SenchaLogin { public WebDriver driver; @BeforeSuite public void launchApp(){ driver = new FirefoxDriver(); driver.manage().window().maximize(); driver.get("http://senchatutorials.in/"); } @Test(dataProvider = "getData") public void testSenchaLogin(String Username, String Password) throws InterruptedException{ driver.findElement(By.xpath("//input[@name='username']")).sendKeys(Username); driver.findElement(By.xpath("//input[@name='password']")).sendKeys(Password); driver.findElement(By.xpath("(//span[text()='Sign In'])[2]")).click(); Thread.sleep(3000); Assert.assertTrue(driver.findElement(By.xpath("//font[text()='SenchaExtJSOverview']")).isDisplayed(),"Login Failed"); System.out.println("Login successful"); } @DataProvider public Object[][] getData(){ Object[][] data = new Object[3][2]; data[0][0] = "username1@gmail.com"; data[0][1] = "pssword1"; data[1][0] = "username3@gmail.com"; data[1][1] = "password3"; data[2][0] = "test@gmail.com"; data[2][1] = "Testing"; return data; } @AfterSuite public void closeBrowser(){ driver.quit(); } } |
In the above example, we have declared the test data array in our test script instead of using a spreadsheet. To achieve this we should call a function that fetches data from excel sheet and returns an object to the data provider.
5) Fetching Data from Excel Sheet
Below is the function that fetches data from an Excel sheet. It uses Apache POI to fetch data from Excel sheet. Update the pom.xml file with POI dependencies as shown below.
It has two parameters
- path: the path of Excel file/workbook containing the data. This path is relative to the Java project
- sheetName: name of the Excel sheet that contains the data
Below code is used to read the data from excel sheet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package DataProvider; import java.io.FileInputStream; import java.io.IOException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; public class ReadExcel { public String[][] getCellData(String path, String sheetName) throws InvalidFormatException, IOException { FileInputStream stream = new FileInputStream(path); Workbook workbook = WorkbookFactory.create(stream); Sheet s = workbook.getSheet(sheet); int rowcount = s.getLastRowNum(); int cellcount = s.getRow(0).getLastCellNum(); String data[][] = new String[rowcount][cellcount]; for (int i = 1; i <= rowcount; i++) { Row r = s.getRow(i); for (int j = 0; j < cellcount; j++) { Cell c = r.getCell(j); try { if (c.getCellType() == c.CELL_TYPE_STRING) { data[i - 1][j] = c.getStringCellValue(); } else { data[i - 1][j] = String.valueOf(c.getNumericCellValue()); } } catch (Exception e) { e.printStackTrace(); } } } return data; } } |
Below code explains how to fetch the data from excel sheet and provide the data to test method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
package com.Senchalogin; import java.io.IOException; import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.AfterSuite; import org.testng.annotations.BeforeSuite; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; public class SenchaLoginTest { public WebDriver driver; @DataProvider public String[][] getExcelData() throws InvalidFormatException, IOException{ ReadExcel read = new ReadExcel(); return read.getCellData("Testdata/SenchaLogin.xls", "Sheet1"); } @BeforeSuite public void launchApp(){ driver = new FirefoxDriver(); driver.manage().window().maximize(); driver.get("http://senchatutorials.in/"); } @Test(testName="sencha",dataProvider = "getExcelData") public void testSenchaLogin(String Username, String Password) throws InterruptedException{ WebDriverWait wait = new WebDriverWait(driver, 30) driver.findElement(By.name("username")).clear(); driver.findElement(By.name("username")).sendKeys(Username); driver.findElement(By.name("password")).clear(); driver.findElement(By.name("password")).sendKeys(Password); driver.findElement(By.xpath("(//span[text()='Sign In'])[2]")).click(); Thread.sleep(2000); String InvalidLogin = driver.findElement(By.xpath("//a[contains(text(), 'Support Team')]")).getText(); if(InvalidLogin.contains("Support Team")){ System.out.println("Login Failed"); } else { wait.until(ExpectedConditions.textToBePresentInElementLocated(By.xpath("(//font[text()='Sencha Ext JS Overview'])"), "Sencha Ext JS Overview")); Assert.assertEquals("Sencha Ext JS Overview", driver.findElement(By.xpath("//font[text()='Sencha Ext JS Overview']")).getText()); System.out.println("Login successful"); } } @AfterSuite public void closeBrowser(){ driver.quit(); } } |
Run this test by right clicking on the test script and select Run As > TestNG Test. Once it is finished, results will be shown, as shown below. As test data is provided three times, the test has executed thrice.
Summary
As part of this article, we learned about the Data-Driven framework of Selenium. Also, we learned about how we make use of TestNG’s Data Provider to read data from Excel spreadsheet and pass them to your test methods so that we can test your application with different data without changing the test script.
At WalkingTree, test automation is the core part of our development strategy and we strongly recommend our customers to get rid of the redundancies by making use of the appropriate test automation framework and associated strategy. We will be happy to assist you in taking advantage of our experience.
Hi, How to write back the results to excel while using data provider
Hi Kiran,
I have one quick quesiton regarding Data Driven test using Testng.
I have updated excel with 5 rows of data and written code in the TestNG format where I have used for loop @Test.
When I ran the script through TestNG, all the five records data is captured and executed successfully.
But in the console it shows only one Test runs instead of 5 Test runs as for loop ran 5 times for different data.