Three frameworks for automated test cases

The previous Selenium articles in this series gave you an understanding of the basic concepts of Selenium testing. However, in this post, I will tell you how to use the Selenium framework to optimize your code structure, which will bring you one step closer to becoming a Selenium Certified Professional.

What is the Selenium framework?

Selenium framework is a code structure used to simplify code maintenance and improve code readability. Framing involves breaking down the entire code into smaller pieces of code to test specific functionality. The code is structured such that the “datasets” are separated from the actual “test cases” that will test the functionality of the web application. It can also be structured in such a way that the test cases that need to be executed can be called (called) from an external application (like .csv).

  • Data Driven Framework
  • Keyword Driven Framework
  • hybrid framework

Why do you need the Selenium framework?

Without a proper framework, there will be only one test case, which will contain the entire test functionality. The scary part is that this single test case has the capacity to go up to a million lines of code. So, obviously, such a huge test case would be difficult to read. Even if you want to modify any functionality later, you will have a hard time modifying the code. Since implementing a framework will result in smaller but multiple code snippets, there are various benefits.

Benefits brought by the Selenium framework

  • increase code reuse
  • Improved code readability
  • Greater portability
  • Reduce script maintenance

Data Driven Framework

Data-driven frameworks in Selenium are techniques for separating “datasets” from actual “test cases” (code). The framework relies entirely on the input test data. Test data comes from external sources such as EXCEL files, .CSV files or any database.

Because test cases are separate from datasets, we can easily modify test cases for specific functionality without making large-scale changes to your code. For example, if you want to modify the code for the login functionality, you can do so without having to modify any other dependent parts of the same code as well. Besides that, you can easily control the amount of data you need to test. You can easily increase the number of test parameters by adding more username and password fields to the excel file (or other source). For example, if I have to check a login for a web page, then I can save the set of username and password credentials in an Excel file and pass the credentials to the code to perform automation on the browser in a separate Java class file.

Using Apache POI with Selenium WebDriver

WebDriver does not directly support reading Excel files. So we use Apache POI to read/write any Microsoft office documents. You can download Apache POI (a set of JAR files) from here. Download the zip file or tar file according to your needs and put them together with the Selenium JAR set.

Coordination between the main code and the dataset will be taken care of by the testng data provider, which is part of the ApachePOI JAR file. For demonstration purposes, I have created an Excel file called “LoginCredentials” where usernames and passwords are stored in separate columns.

Please see the code below to understand the test case. Here is a simple code to test the login functionality of a flight booking application.

package DataDriven;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class DDTExcel
{
ChromeDriver driver;
@Test(dataProvider="testdata")
public void DemoProject(String username, String password) throws InterruptedException
{
System.setProperty("webdriver.chrome.driver", "C:UsersVardhanDownloadschromedriver.exe");
driver = new ChromeDriver();
driver.get("http://newtours.demoaut.com/");
driver.findElement(By.name("userName")).sendKeys(username);
driver.findElement(By.name("password")).sendKeys(password);
driver.findElement(By.name("login")).click();
Thread. sleep(5000);
Assert.assertTrue(driver.getTitle().matches("Find a Flight: Mercury Tours:"), "Invalid credentials");
System.out.println("Login successful");
}
@AfterMethod
void Program Termination()
{
driver. quit();
}
@DataProvider(name="testdata")
public Object[][] TestDataFeed()
{
ReadExcelFile config = new ReadExcelFile("C:UsersVardhanworkspaceSeleniumLoginCredentials.xlsx");
int rows = config. getRowCount(0);
Object[][] credentials = new Object[rows][2];
for(int i=0;i<rows;i++)
{
credentials[i][0] = config. getData(0, i, 0);
credentials[i][1] = config. getData(0, i, 1);
}
return credentials;
}
}

If you noticed from above, we have a method called “TestDataFeed()”. In this method, I create another object instance of the class called “ReadExcelFile”. While instantiating this object, I provide the path to the myexcel file that contains the data. I further defined a for loop to retrieve the text from the excel workbook. However, in order to read data from a given page number, column number, and row number, the “ReadExcelFile” class needs to be called. My “ReadExcelFile” code is as follows.

package DataDriven;
import java.io.File;
import java.io.FileInputStream;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ReadExcelFile
{
XSSFWorkbook wb;
XSSFSheet sheet;
public ReadExcelFile(String excelPath)
{
try
{
File src = new File(excelPath);
FileInputStream fis = new FileInputStream(src);
wb = new XSSFWorkbook(fis);
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
public String getData(int sheetnumber, int row, int column)
{
sheet = wb. getSheetAt(sheetnumber);
String data = sheet.getRow(row).getCell(column).getStringCellValue();
return data;
}
public int getRowCount(int sheetIndex)
{
int row = wb.getSheetAt(sheetIndex).getLastRowNum();
row = row + 1;
return row;
}
}

First notice the libraries I import. I have imported Apache POI XSSF_LIBRARY which are used to read/write data to Excel files. Here, I created a constructor (object of the same method) to pass the values: Sheetnumber, RowNumber and ColumnNumber. To better understand this framework, I ask you to go through the video below, where I explain it in a structured manner.

Keyword Driven Framework

Keyword-driven framework is a technique where all actions and instructions to be executed are written separately from the actual test cases. It is similar to a data-driven framework in that the actions to be performed are again stored in an external file such as an Excel sheet.

The operations I’m talking about are nothing more than methods that need to be executed as part of a test case. The benefit of a keyword-driven framework is that you can easily control which features to test. You can specify the method of testing the functionality of the application in the Excel file. Therefore, only those method names specified in Excel will be tested. For example, for logging into a web application, we can write multiple methods in the main test case, each test case will test certain functionality. There could be a method for instantiating the browser driver, there could be a method for finding the username and password fields, there could be a method for navigating to a web page, there could be another method, and so on.

Take a look at the code below to get an idea of what the frame looks like. These lines commented out in the code below serve as an explanation if you don’t understand.

package KeywordDriven;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class Actions
{
public static WebDriver driver;
public static void openBrowser()
{
System.setProperty("webdriver.chrome.driver", "C:UsersVardhanDownloadschromedriver.exe");
driver=new ChromeDriver();
}
public static void navigate()
{
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://newtours.demoaut.com");
}
public static void input_Username()
{
driver.findElement(By.name("userName")).sendKeys("mercury");
}
public static void input_Password()
{
driver.findElement(By.name("password")).sendKeys("mercury");
}
public static void click_Login()
{
driver.findElement(By.name("login")).click();
}
@Test
public static void verify_login()
{
String pageTitle = driver. getTitle();
Assert.assertEquals(pageTitle, "Find a Flight: Mercury Tours:");
}
public static void closeBrowser()
{
driver. quit();
}
}

As you can see, the different functionality that needs to be tested resides in different methods that await to be called. Now, based on the method names present in the Excel file, the methods will be called from another class. Similarly, to read the EXCEL file and return the result, I wrote another class. They are all shown below. The class file that calls these methods is shown below.

package KeywordDriven;
public class DriverScript
{
public static void main(String[] args) throws Exception
{
//Declaring the path of the Excel file with the name of the Excel file
String sPath = "C:UsersVardhanworkspaceSelenium Frameworks DemodataEngine.xlsx";
//Here we are passing the Excel path and SheetName as arguments to connect with Excel file
ReadExcelData.setExcelFile(sPath, "Sheet1");
 //Hard coded values are used for Excel row & amp; columns for now
//Hard coded values are used for Excel row & amp; columns for now
//In later chapters we will replace these hard coded values with varibales //This is the loop for reading the values of the column 3 (Action Keyword) row by row
for (int iRow=1;iRow<=7;iRow ++ )
{
String sActions = ReadExcelData.getCellData(iRow, 1);
//Comparing the value of Excel cell with all the keywords in the "Actions" class
if(sActions. equals("openBrowser"))
{
//This will execute if the excel cell value is 'openBrowser'
//Action Keyword is called here to perform action
Actions. openBrowser();
}
else if(sActions. equals("navigate"))
{
Actions. navigate();
}
else if(sActions. equals("input_Username"))
{
Actions. input_Username();
}
else if(sActions. equals("input_Password"))
{
Actions. input_Password();
}
else if(sActions. equals("click_Login"))
{
Actions.click_Login();
}
else if(sActions. equals("verify_Login"))
{
Actions. verify_login();
}
else if(sActions. equals("closeBrowser"))
{
Actions. closeBrowser();
}
}
}
}

The class file to read Excel values is shown below.

package KeywordDriven;
import java.io.FileInputStream;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
public class ReadExcelData
{
private static XSSFSheet ExcelWSheet;
private static XSSFWorkbook ExcelWBook;
private static XSSFCell Cell;
//This method is to set the File path and to open the Excel file
//Pass Excel Path and SheetName as Arguments to this method
public static void setExcelFile(String Path,String SheetName) throws Exception
{
FileInputStream ExcelFile = new FileInputStream(Path);
ExcelWBook = new XSSFWorkbook(ExcelFile);
ExcelWSheet = ExcelWBook. getSheet(SheetName);
}
//This method is to read the test data from the Excel cell
//In this we are passing parameters/arguments as Row Num and Col Num
public static String getCellData(int RowNum, int ColNum) throws Exception
{
Cell = ExcelWSheet.getRow(RowNum).getCell(ColNum);
String CellData = Cell. getStringCellValue();
return CellData;
}
}

Hybrid framework

A hybrid framework is a technique that can take full advantage of DataDriven and keyword-driven Selenium framework. Using the example shown in this post, we can build a hybrid framework by storing the methods to be executed in an Excel file (keyword-driven approach) and passing those method names to Java reflection classes (data-driven approach) instead of in the ” Create an ANIF/ELSE loop in the DriverScript” class. Take a look at the modified “DriverScript” class in the code snippet below. Here, instead of using multiple if/else loops, a data-driven approach is used to read the method names from the Excel file.

package HybridFramework;
import java.lang.reflect.Method;
public class DriverScriptJava
{
//This is a class object, declared as 'public static'
//So that it can be used outside the scope of main[] method
public static Actions actionKeywords;
public static String sActions;
//This is reflection class object, declared as 'public static'
//So that it can be used outside the scope of main[] method
public static Method method[];
public static void main(String[] args) throws Exception
{
//Declaring the path of the Excel file with the name of the Excel file
String sPath = "C:UsersVardhanworkspaceSelenium Frameworks DemodataEngine.xlsx";
 //Here we are passing the Excel path and SheetName to connect with the Excel file
//This method was created previously
ReadExcelData.setExcelFile(sPath, "Sheet1");
//Hard coded values are used for Excel row & amp; columns for now
//Later on, we will use these hard coded value much more efficiently
//This is the loop for reading the values of the column (Action Keyword) row by row
//It means this loop will execute all the steps mentioned for the test case in Test Steps sheet
for (int iRow=1;iRow<=7;iRow ++ )
{
sActions = ReadExcelData.getCellData(iRow, 1);
//A new separate method is created with the name 'execute_Actions'
//You will find this method below of the this test
//So this statement is doing nothing but calling that piece of code to execute
execute_Actions();
}
}
//This method contains the code to perform some action
//As it is completely different set of logic, which revolves around the action only, it makes sense to keep it separate from the main driver script
//This is to execute test step (Action)
private static void execute_Actions() throws Exception
{
//Here we are instantiating a new object of class 'Actions'
actionKeywords = new Actions();
//This will load all the methods of the class 'Actions' in it.
//It will be like array of method, use the break point here and do the watch
method = actionKeywords. getClass(). getMethods();
//This is a loop which will run for the number of actions in the Action Keyword class
//method variable contain all the method and method.length returns the total number of methods
for(int i = 0;i<method.length;i++)
{
//This is now comparing the method name with the ActionKeyword value received from the excel
if(method[i].getName().equals(sActions))
{ //In case of match found, it will execute the matched method
method[i].invoke(actionKeywords);
//Once any method is executed, this break statement will take the flow outside of for loop
break;
}
}
}
}

Learning arrangement

As someone who has been here, I also hope that everyone will avoid some detours. If you don’t want to experience the feeling of not being able to find information when learning, no one answering questions, and giving up after a few days of persistence, here I will share with you some automation. The learning resources of the test hope to help you along the way. [100% Free Guaranteed]

How to get the video file:

This document and video material, For friends who want to engage in [software testing], it should be the most comprehensive and complete preparation warehouse. This warehouse has also accompanied me through the most difficult journey. Can help you! All of the above can be shared, and you can collect it yourself by clicking the small card below.