Hybrid Testing (Data + Keyword Driven) using Selenium
May 31, 2011 20 Comments
Today, we’ll see how to do hybrid testing using selenium. Let’s discuss what’s hybrid testing first. Hybrid testing is a combination of Data Driven testing along with keyword. Here we’ll use some keywords as the driving parameters in data driven testing the data sheet. The keywords will be defined by the user, and let’s call them user defined keywords.
Before getting into the framework, let’s discuss on what are the external files which will be required. The list of files that will be required in addition to selenium client driver and selenium server jar files are as below
- TestNG: in order to data drive our test, we would require the latest version of testNG jar file which is now testng-5.14.1.jar and can be downloaded from http://testng.org/doc/download.html
- JXL: in order to use Microsoft Excel files as data source we would need the jxl jar file which can be downloaded from http://sourceforge.net/projects/jexcelapi/files/
- Latest Junit: this will be required to verify certain condition and can be downloaded from https://github.com/KentBeck/junit/downloads
- TestNG plugin for Eclipse: This will be required to run the TestNG scripts in eclipse and the content of this plugin has to be placed inside the “dropin” folder inside the eclipse directory. The file can be downloaded from http://testng.org/doc/download.html
The first 3 file need to be added to the build path in the project in eclipse to use them. The fourth file needs to extracted in the dropin folder of the eclipse folder so that when you open the droping folder, a plugin folder is created inside it. This is all about configuration that is required for such testing.
Now let’s start with how to test using this framework. Let’s test the IBN Live website, where we’ll use the keyword ‘link’ to drive our test. So to do this, we need to place this keyword ‘link’ in the data sheet. This will decide the action when the ‘link’ keyword is passed to the program. The corresponding cell values for that particular row will be used for different operations on the same. Below is the data sheet that we are going to use.
| testData | property | xPath | value | expectedResult | permission | name | |
| pagetitle | CNN-IBN, Live India News,Top Breaking News,World,India,Business,Sports, Entertainment & Health News | ||||||
| link | link=News | click | News | ||||
| link | link=Politics | click | Politics | ||||
| link | link=Movies | click | Movies | ||||
| testData |
Here using selenium, we are going to test the page title of the landing page and use the link property to navigate to different pages. So first let me explain the data table. “testData” is the table marker which will tell the start and end point of the table. The column headers will be used as variables. Here property defines the property on which we are going to perform certain actions. xPath will be used to locate the properties, value will be used to enter some data or select any object, expected result will be used to compare the actual value to the expected value, permission will determine the course of action and name will be used to give meaningful name while generating result. Below is the sample code that will drive our Hybrid test.
import com.thoughtworks.selenium.*;
import org.junit.AfterClass;
import org.openqa.selenium.server.SeleniumServer;
import org.testng.annotations.*;
import java.io.File;
import jxl.*;
public class DataDrivenTest extends SeleneseTestCase{
@BeforeClass
public void setUp() throws Exception {
setUp("http://ibnlive.in.com/", "*iexplore");
selenium.open("/");
selenium.setTimeout("60000");
selenium.waitForPageToLoad("60000");
selenium.windowMaximize();
selenium.windowFocus();
}
@DataProvider(name = "DP")
public Object[][] createData() throws Exception{
Object[][] retObjArr=getTableArray("D:\\Work\\Data Driven Testing\\Data Driven Test\\Resources\\Data Sheet.xls",
"Data", "testData");
return(retObjArr);
}
@Test (dataProvider = "DP")
public void testElements(String property, String xPath, String value, String expectedResult, String permission, String name) throws Exception {
if(property.equals("pagetitle")){
if(selenium.getTitle().equals(expectedResult)){
System.out.println("The page title is displaying properly");
}
else
System.out.println("The page title is not correct");
}
if(property.equals("link")){
if(selenium.isElementPresent(xPath))
System.out.println("The link "+name+" is present");
else
System.out.println("The link "+name+" is not present");
if(permission.equals("click"))
{
selenium.click(xPath);
selenium.waitForPageToLoad("60000");
}
}
}
@AfterClass
public void tearDown(){
selenium.close();
selenium.stop();
}
public String[][] getTableArray(String xlFilePath, String sheetName, String tableName) throws Exception{
String[][] tabArray=null;
Workbook workbook = Workbook.getWorkbook(new File(xlFilePath));
Sheet sheet = workbook.getSheet(sheetName);
int startRow,startCol, endRow, endCol,ci,cj;
Cell tableStart=sheet.findCell(tableName);
startRow=tableStart.getRow();
startCol=tableStart.getColumn();
Cell tableEnd= sheet.findCell(tableName, startCol+1,startRow+1, 100, 64000, false);
endRow=tableEnd.getRow();
endCol=tableEnd.getColumn();
System.out.println("startRow="+startRow+", endRow="+endRow+", " +
"startCol="+startCol+", endCol="+endCol);
tabArray=new String[endRow-startRow-1][endCol-startCol-1];
ci=0;
for (int i=startRow+1;i<endRow;i++,ci++){
cj=0;
for (int j=startCol+1;j<endCol;j++,cj++){
tabArray[ci][cj]=sheet.getCell(j,i).getContents();
}
}
return(tabArray);
}
}//end of class
The createData method will create a virtual copy of the data sheet in memory. Inside it, we need to specify the data sheet path along with its name, the sheet name, the table marker that we discussed earlier. Here, the testElements method is driving the test depending on the input, it’s getting from the excel sheet. It can be customized to accommodate more types of properties like drop down, text box, text area, etc. according to user needs.
This is a way how we can data drive our test. I hope that I made some people happy with this post. Please leave a reply in case of doubts
.

Pingback: Keyword Driven Testing with Selenium RC.
any chance of getting that .xls to use to run this?
The code here is written for selenium RC. To make it work with webdriver, the structure will remain same, but the syntax will change… very soon, I will post how to do the same with webdriver….
that would be great! I seem to be moving faster than expected with this! I will be able to replace my QTP framework with webdriver driven one
I have a framework that reads rows while yours reads columns – I’d like to send you that framework and see if you can use it instead – how to attach a file?
Also could I use the selenium backed webdriver to use with the code above?
you can send it me by email. my id is sudeep_liku15@yahoo.com. You can use selenium backed webdriver, but your test will be slow if you use it.
The table available here read the table row by row. You just have to use the table indicators in your data sheet. I’ll send you the sheet adding the indicators. You can try with that. In the mean while today i’ll post the same hybrid test approach using webdriver.
just sold the datadriven webdriver to a few of the testers here so its looking good! now they want to see it work……
I am trying to run the same test in Web driver ,Do u have any idea:(As the following code is webdriver backed)
if(driver.findElementsBy(xPath)) -Line 37 I a getting Error
driver.click(xPath); -Line 43 in the code getting the error and Everything else is fine.
Can you be more specific… could you please post a snippet of your code…
Hi Sudeep,
Nice framework
I am getting this error-
FAILED CONFIGURATION: @BeforeClass setUp
java.lang.NoClassDefFoundError: org/openqa/selenium/net/NetworkUtils
Can u pliz help me out in debugging this?
Regards,
Arbind
Have you done the configuration properly? Can you elaborate what you are trying to do?
Hi,
Yes I have done the configuration properly.does this mean I need the add the jar files again?
I am just trying to create the same framework like yours, and once it starts running properly, then I can implement this for some of my projects.
Are you using eclipse? If yes, is there any cross mark appearing for the class file?
Yes I am using eclipse. surprisingly no error in the class file (no red cross marks)only after running the code, its failing. This is what I am getting:
FAILED CONFIGURATION: @BeforeClass setUp
java.lang.NoClassDefFoundError: org/openqa/selenium/net/NetworkUtils
at org.openqa.selenium.server.SeleniumServer.(SeleniumServer.java:203)
at Test.DataDrivenTest.setUp(DataDrivenTest.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:551)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107)
at org.testng.TestRunner.privateRun(TestRunner.java:768)
at org.testng.TestRunner.run(TestRunner.java:617)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
at org.testng.SuiteRunner.run(SuiteRunner.java:240)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:87)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1185)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1110)
at org.testng.TestNG.run(TestNG.java:1022)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:109)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:202)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:173)
Caused by: java.lang.ClassNotFoundException: org.openqa.selenium.net.NetworkUtils
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
… 26 more
SKIPPED CONFIGURATION: @AfterClass tearDown
SKIPPED: TestDataProviderExample on null(Test.DataDrivenTest)
java.lang.RuntimeException: java.lang.NullPointerException
at org.testng.internal.MethodInvocationHelper.invokeDataProvider(MethodInvocationHelper.java:143)
at org.testng.internal.Parameters.handleParameters(Parameters.java:426)
at org.testng.internal.Invoker.handleParameters(Invoker.java:1371)
at org.testng.internal.Invoker.createParameters(Invoker.java:1068)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1171)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
at org.testng.TestRunner.privateRun(TestRunner.java:768)
at org.testng.TestRunner.run(TestRunner.java:617)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
at org.testng.SuiteRunner.run(SuiteRunner.java:240)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:87)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1185)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1110)
at org.testng.TestNG.run(TestNG.java:1022)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:109)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:202)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:173)
Caused by: java.lang.NullPointerException
at Test.DataDrivenTest.getTableArray(DataDrivenTest.java:93)
at Test.DataDrivenTest.createData(DataDrivenTest.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
at org.testng.internal.MethodInvocationHelper.invokeDataProvider(MethodInvocationHelper.java:117)
… 20 more
===============================================
Default test
Tests run: 1, Failures: 0, Skips: 1
Configuration Failures: 1, Skips: 1
can u paste the code snippet you have written?
All set,
am using eclipse and getting error in below code,
Cell tableEnd= sheet.findCell(tableName, startCol+1,startRow+1, 100, 64000, false);
eclipse showing a red underlined on findCell
pls provide proper solution for this code,
have you downloaded the jxl properly? This is a jxl property. I would advise to use the latest version of the jxl to overcome this problem.
yes i downloaded the jxl.jar properly from below link,
mirrors.ibiblio.org/pub/mirrors/maven2/net/sourceforge/jexcelapi/jxl/2.6.10/jxl-2.6.10.jar
but still the error exist in below code,
Cell tableEnd= sheet.findCell(tableName, startCol+1,startRow+1, 100, 64000, false);
noted the red underlined on findCell in eclipse,
Anyhow i place the code here you can check it
import com.thoughtworks.selenium.*;
import org.junit.AfterClass;
import org.testng.annotations.*;
import java.io.File;
import jxl.*;
public class datadriven extends SeleneseTestCase{
@SuppressWarnings(“deprecation”)
@BeforeClass
public void setUp() throws Exception {
setUp(“http://ibnlive.in.com/”, “*iexplore”);
selenium.open(“/”);
selenium.setTimeout(“60000″);
selenium.waitForPageToLoad(“60000″);
selenium.windowMaximize();
selenium.windowFocus();
}
@DataProvider(name = “DP”)
public Object[][] createData() throws Exception{
Object[][] retObjArr=getTableArray(“E:\\Edwin\\Selenium\\Automation\\Data Sheet\\Data Sheet.xls”,
“Data”, “testData”);
return(retObjArr);
}
@SuppressWarnings(“deprecation”)
@Test (dataProvider = “DP”)
public void testElements(String property, String xPath, String value, String expectedResult, String permission, String name) throws Exception {
if(property.equals(“pagetitle”)){
if(selenium.getTitle().equals(expectedResult)){
System.out.println(“The page title is displaying properly”);
}
else
System.out.println(“The page title is not correct”);
}
if(property.equals(“link”)){
if(selenium.isElementPresent(xPath))
System.out.println(“The link “+name+” is present”);
else
System.out.println(“The link “+name+” is not present”);
if(permission.equals(“click”))
{
selenium.click(xPath);
selenium.waitForPageToLoad(“60000″);
}
}
}
@SuppressWarnings(“deprecation”)
@AfterClass
public void tearDown(){
selenium.close();
selenium.stop();
}
public String[][] getTableArray(String xlFilePath, String sheetName, String tableName) throws Exception{
String[][] tabArray=null;
Workbook workbook = Workbook.getWorkbook(new File(xlFilePath));
Sheet sheet = workbook.getSheet(sheetName);
int startRow,startCol, endRow, endCol,ci,cj;
Cell tableStart=sheet.findCell(tableName);
startRow=tableStart.getRow();
startCol=tableStart.getColumn();
Cell tableEnd= sheet.findCell(tableName, startCol+1,startRow+1, 100, 64000, false);
endRow=tableEnd.getRow();
endCol=tableEnd.getColumn();
System.out.println(“startRow=”+startRow+”, endRow=”+endRow+”, ” + “startCol=”+startCol+”, endCol=”+endCol);
tabArray=new String[endRow-startRow-1][endCol-startCol-1];
ci=0;
for (int i=startRow+1;i<endRow;i++,ci++){
cj=0;
for (int j=startCol+1;j<endCol;j++,cj++){
tabArray[ci][cj]=sheet.getCell(j,i).getContents();
}
}
return(tabArray);
}
}//end of class
Finally i fix the error,
Now i run the test the error shows in eclipse, “The input type of launch configuration does not exit”
Pls calrify,