Hybrid Testing (Data + Keyword Driven) using Selenium

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

  1. 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
  2. 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/
  3. Latest Junit: this will be required to verify certain condition and can be downloaded from https://github.com/KentBeck/junit/downloads
  4. 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 :) .

About sudeepmoharana
A geek eager to learn new technologies.

20 Responses to Hybrid Testing (Data + Keyword Driven) using Selenium

  1. Pingback: Keyword Driven Testing with Selenium RC.

  2. joe loyzaga says:

    any chance of getting that .xls to use to run this?

  3. 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….

  4. joe loyzaga says:

    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

  5. joe loyzaga says:

    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?

  6. 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.

  7. 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.

  8. joe loyzaga says:

    just sold the datadriven webdriver to a few of the testers here so its looking good! now they want to see it work……

  9. raju says:

    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.

  10. Arbind says:

    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?

      • Arbind says:

        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?

  11. Arbind says:

    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

  12. Edwin Antony says:

    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,

  13. Edwin Antony says:

    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

  14. Edwin Antony says:

    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,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 498 other followers