Selenium Keyword Driven And Hybrid Framework

There are three kinds of test Frameworks in Selenium testing. They are Keyword Driven Framework, Data Driven Framework, and Hybrid Framework. With these frameworks, we can separate java code and test data in the test program. So your java code is more readable and reusable, the automation script is more portable, and script maintenance cost will be reduced.

After the Framework is set up, even a manual tester can make the test case automated. Because they do not need to write even a single line of java code to build the test script. This can extremely improve the test process and reduce cost.

1. Keyword Driven Framework.

selenium-keyword-driven-framework

In the keyword-driven framework, the test case data or web element data can be saved anywhere, but in our example, we will save test data in an excel file.

1.1 There are four parts in the keyword-driven framework.

  1. Test Case Manager: Parse out the test case and steps and return the data back to the Test Case Runner. Then test case runner will run the test case one by one.
  2. In this example, there are four columns in the test data saved excel file, they are Test Case, Action Keyword, Web Element Symbol Name, Web Element Value.
  3. Test Case: the name of this test case.
  4. Action Keyword: Which action will take in this step.
  5. Web Element Symbol Name: The name of the web element that will interact with. This is just a symbol name not the web element’s real name on the web page, it is used to get a real web element in the web element datasheet.
  6. Web Element Value: The value that this step will apply to the web element.
    selenium-keyword-driven-test-case-sheet
  7. Web Element Manager: Parse out web element-related data such as web element symbol name, web element locator type, web element locator value. There are three columns in this example test data saved excel file, they are Symbol NameLocator TypeLocator Value.
  8. Symbol Name: Same with test case data sheet’s web element symbol name.
  9. Locator Type: By which to locate the web element, its value can be id, name, XPath, tagName, CSS, etc.
  10. Locator Value: The value for the locator, for example //*[@id=”Password”].
    selenium-web-element-data
  11. Test Action Performer: Find the web element in the test step by its locator. Perform actions such as click, set text according to the action keyword.
  12. Test Case Runner: Run all test cases one by one. For each step, it will call the action performer to run it.

1.2 Example Java Code.

1.2.1 Below are the example files.
C:\WORKSPACE\WORK\DEV2QA.COM-EXAMPLE-CODE\JAVACOREEXAMPLEPROJECT\SRC\COM\DEV2QA\WEBDRIVER\FRAMEWORK
    index.html
    login.html
    TestActionPerformer.java
    TestCaseDTO.java
    TestCaseManager.java
    TestCaseRunner.java
    TestData.xls
    TestStepDTO.java
    UtilTool.java
    WebElementDTO.java
    WebElementManager.java
1.2.2 TestCaseManager.java.
public class TestCaseManager {
	
	public List<TestCaseDTO> readTestCaseData(String excelFilePath, String sheetName)
	{
		List<TestCaseDTO> ret = new ArrayList<TestCaseDTO>();
		
		try
		{
			if(excelFilePath!=null && sheetName!=null)
			{
				FileInputStream fInputStream = new FileInputStream(excelFilePath.trim());
				
				/* Create excel workbook object. */
				Workbook workBook = new HSSFWorkbook(fInputStream);
	
				/* Get excel work sheet by name. */
				Sheet testCaseSheet = workBook.getSheet(sheetName);
				
				int lastRowNum = testCaseSheet.getLastRowNum();
				
				TestCaseDTO tmpTestCaseDto = null;
				
				/* First row is header row, so we read data from second row. */
				for(int i=1; i<lastRowNum+1; i++)
				{
					Row row = testCaseSheet.getRow(i);
					
					/* Get first cell value.*/
					String cValue = UtilTool.getExecelCellStringValue(row.getCell(0));
					/* This is the test case name cell. It is start for one test case.*/
					if(cValue.trim().length()>0)
					{
						tmpTestCaseDto = new TestCaseDTO();
						tmpTestCaseDto.setName(cValue);
						
						ret.add(tmpTestCaseDto);
					}
										
					TestStepDTO testStepDto = new TestStepDTO();
					/* Get second cell value.*/
					cValue = UtilTool.getExecelCellStringValue(row.getCell(1));
					testStepDto.setActionKeyword(cValue);
					
					/* Get third cell value.*/
					cValue = UtilTool.getExecelCellStringValue(row.getCell(2));
					testStepDto.setWebEleSymbolName(cValue);
					
					/* Get fourth cell value.*/
					cValue = UtilTool.getExecelCellStringValue(row.getCell(3));
					testStepDto.setWebEleValue(cValue);
					
					tmpTestCaseDto.getStepList().add(testStepDto);
				}
			}
		}catch(Exception ex)
		{
			ex.printStackTrace();
		}finally
		{
			return ret;
		}
	}

}
1.2.3 TestCaseDTO.java.
/* Represent a test case. */
public class TestCaseDTO {

	private String name;
	
	private List<TestStepDTO> stepList = null;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<TestStepDTO> getStepList() {
		if(stepList == null)
		{
			stepList = new ArrayList<TestStepDTO>();
		}
		return stepList;
	}

	public void setStepList(List<TestStepDTO> stepList) {
		this.stepList = stepList;
	}
	
	
}
1.2.4 TestStepDTO.java.
/* Represent a test step object.*/
public class TestStepDTO {

	private String actionKeyword;
	
	private String webEleSymbolName;
	
	private String webEleValue;

	public String getActionKeyword() {
		return actionKeyword;
	}

	public void setActionKeyword(String actionKeyword) {
		this.actionKeyword = actionKeyword;
	}

	public String getWebEleSymbolName() {
		return webEleSymbolName;
	}

	public void setWebEleSymbolName(String webEleSymbolName) {
		this.webEleSymbolName = webEleSymbolName;
	}

	public String getWebEleValue() {
		return webEleValue;
	}

	public void setWebEleValue(String webEleValue) {
		this.webEleValue = webEleValue;
	}
	
	
}
1.2.5 WebElementManager.java.
public class WebElementManager {

	public List<WebElementDTO> readWebElementData(String excelFilePath, String sheetName)
	{
		List<WebElementDTO> ret = new ArrayList<WebElementDTO>();
		
		try
		{
			if(excelFilePath!=null && sheetName!=null)
			{
				FileInputStream fInputStream = new FileInputStream(excelFilePath.trim());
				
				/* Create excel workbook object. */
				Workbook workBook = new HSSFWorkbook(fInputStream);
	
				/* Get excel work sheet by name. */
				Sheet testCaseSheet = workBook.getSheet(sheetName);
				
				int lastRowNum = testCaseSheet.getLastRowNum();
				
				/* First row is header row, so we read data from second row. */
				for(int i=1; i<lastRowNum+1; i++)
				{
					Row row = testCaseSheet.getRow(i);
					
					WebElementDTO webElementDto = new WebElementDTO();
					
					String cValue = row.getCell(0).getStringCellValue();
					webElementDto.setSymbolName(cValue);
					
					cValue = row.getCell(1).getStringCellValue();
					webElementDto.setLocatorType(cValue);
					
					cValue = row.getCell(2).getStringCellValue();
					webElementDto.setLocatorValue(cValue);
					
					ret.add(webElementDto);
				}
			}
		}catch(Exception ex)
		{
			ex.printStackTrace();
		}finally
		{
			return ret;
		}
	}
	
	
	public static WebElementDTO getWebEleDtoBySymbolName(List<WebElementDTO> weDtoList, String symbolName)
	{
		WebElementDTO ret = new WebElementDTO();
		
		if(weDtoList!=null && symbolName.trim().length()>0)
		{
			int size = weDtoList.size();
			for(int i=0;i<size;i++)
			{
				WebElementDTO tmpDto = weDtoList.get(i);
				if(symbolName.equalsIgnoreCase(tmpDto.getSymbolName()))
				{
					ret = tmpDto;
					break;
				}
			}
		}
		return ret;
	}
}
1.2.6 WebElementDTO.java.
/* Represent web element data.*/
public class WebElementDTO {
	
	private String symbolName = "";
	
	private String locatorType = "";
	
	private String locatorValue = "";

	public String getSymbolName() {
		return symbolName;
	}

	public void setSymbolName(String symbolName) {
		this.symbolName = symbolName;
	}

	public String getLocatorType() {
		return locatorType;
	}

	public void setLocatorType(String locatorType) {
		this.locatorType = locatorType;
	}

	public String getLocatorValue() {
		return locatorValue;
	}

	public void setLocatorValue(String locatorValue) {
		this.locatorValue = locatorValue;
	}

}
1.2.7 TestActionPerformer.java.
public class TestActionPerformer {
	

	public void performAction(String action, WebElementDTO weDto, String webEleValue, WebDriver driver) throws InterruptedException
	{
		if(action!=null && weDto!=null && driver!=null)
		{			
			switch(action.toLowerCase())
			{
				case "gotourl":
					driver.get(webEleValue);
					break;
				case "settext":
					driver.findElement(this.getWebElementLocator(weDto.getLocatorType(), weDto.getLocatorValue())).sendKeys(webEleValue);
					break;
				case "click":
					driver.findElement(this.getWebElementLocator(weDto.getLocatorType(), weDto.getLocatorValue())).click();
					break;
			}
			
			Thread.sleep(3000);
		}
	}
	
	/* Return the By object to locate the web element. */
	private By getWebElementLocator(String locatorType, String locatorValue)
	{
		switch(locatorType.toLowerCase()){
			case "xpath":
				return By.xpath(locatorValue);
			case "id":
				return By.id(locatorValue);
			case "name":
				return By.name(locatorValue);
			case "tagname":
				return By.tagName(locatorValue);
			case "className":
				return By.className(locatorValue);
			default:
				return null;
		}
	}

}
1.2.8 TestCaseRunner.java.
  private void runTestCase(List<TestCaseDTO> tcDtoList, List<WebElementDTO> weDtoList) throws InterruptedException
  {
	  if(tcDtoList!=null && weDtoList!=null)
	  {
		  TestActionPerformer actionPerformer = new TestActionPerformer();
		  
		  int tcSize = tcDtoList.size();
		  
		  for(int i=0;i<tcSize;i++)
		  {
			  TestCaseDTO tcDto = tcDtoList.get(i);
			  
			  String tcName = tcDto.getName();
			  
			  System.out.println("Run test case : " + tcName);
			  
			  List<TestStepDTO> stepList = tcDto.getStepList();
			  
			  int stepSize = stepList.size();
			  
			  for(int j=0;j<stepSize;j++)
			  {
				  TestStepDTO stepDto = stepList.get(j);
				  
				  String action = stepDto.getActionKeyword();
				  
				  String symbolName = stepDto.getWebEleSymbolName();
				  
				  String value = stepDto.getWebEleValue();
				  
				  if(action.length()>0)
				  {
					  System.out.println("Run step " + j + " : " + action + " , "  + symbolName + " , " + value);
					  
					  actionPerformer.performAction(action, WebElementManager.getWebEleDtoBySymbolName(weDtoList, symbolName), value, this.ffDriver);
				  }
			  }
			  
			  System.out.println("----------------------------------------------");
		  }
	  }
  }
  
		
  @Test
  public void keywordDrivenTest() throws InterruptedException, IOException {
	  
	  String excelFilePath = "C:/WorkSpace/dev2qa.com/Code/src/com/dev2qa/webdriver/framework/TestData.xls";
	  
	  String tcDataSheetName = "Test Case";
	  
	  String weDataSheetName = "Web Element";
	  
	  
	  TestCaseManager tcManager = new TestCaseManager();
	  List<TestCaseDTO> tcDtoList = tcManager.readTestCaseData(excelFilePath, tcDataSheetName);
	  
	  WebElementManager weManager = new WebElementManager();
	  List<WebElementDTO> weDtoList = weManager.readWebElementData(excelFilePath, weDataSheetName);
	  
	  this.runTestCase(tcDtoList, weDtoList);
  }
1.2.9 UtilTool.java.
public class UtilTool {

	public static String getExecelCellStringValue(Cell cell)
	{
		String ret = "";
		if(cell!=null)
		{
			ret = cell.getStringCellValue();
		}
		return ret;
	}
}

2. Data-Driven Framework.

Read test data from excel, CSV, XML, and database. With this, you can run one selenium test method with huge different test data. This has been discussed in previous articles. You can read the below articles to learn.

  1. TestNG Parameterized Testing Via DataProvider Or Testng.xml
  2. Read / Write Excel Data Using Apache POI
  3. Read / Write CSV File With Apache Commons CSV
  4. TestNG DataProvider Read Test Data From Xml File

3. Hybrid Framework.

The hybrid framework integrate both keyword-driven and data-driven frameworks. In the hybrid model, the test data list is used as a dataProvider parameter for keywordDrivenTest() method. Below is the java example source code for the hybrid framework implemented by TestNG.

  @Test(dataProvider = "testDataHybrid")
  public void keywordDrivenTestHybrid(List<TestCaseDTO> tcDtoList, List<WebElementDTO> weDtoList) throws InterruptedException {
	  
	 this.runTestCase(tcDtoList, weDtoList);

  }
  
  @DataProvider(name="testDataHybrid")
  public Object[][] getTestData() throws IOException{
	  String excelFilePath = "C:/WorkSpace/dev2qa.com/Code/src/com/dev2qa/webdriver/framework/TestData.xls";
	  
	  String tcDataSheetName = "Test Case";
	  
	  String weDataSheetName = "Web Element";
	  
	  TestCaseManager tcManager = new TestCaseManager();
	  List<TestCaseDTO> tcDtoList = tcManager.readTestCaseData(excelFilePath, tcDataSheetName);
	  
	  WebElementManager weManager = new WebElementManager();
	  List<WebElementDTO> weDtoList = weManager.readWebElementData(excelFilePath, weDataSheetName);
	  
	  Object[][] ret = {{tcDtoList, weDtoList}};
	  return ret;
  }

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Index