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

Advertisements

50 comments

  1. Pingback: Keyword Driven Testing with Selenium RC.

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

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

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

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

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

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

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

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

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

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

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

  13. Using this I am able to run a single test with multiple methods. How to alter this framework to run multiple tests that inputs from the same excel.

  14. Hi Edwin, I am facing the same problem for findcell function…..
    Q. Can you please help me that how did you fix this error?

    • HI Varun and Edwin Antony,

      can you please create a new project and use latest jxl.jar and in the reference libraries add only this jar. remove duplicate jxl jars.

  15. Hi,

    It is a good tutorial, I have a doubt in driving a test with different set of data parallel.

    Assume my test case is as follows,
    1. Login to Gmail
    2. Compose an email with Subject “Hi Receiver
    3. Signout

    My Test Data is like this,
    1. Login with user ”u1” who performs compose with Subject ”Hi Receiver1”
    2. Login with user ”u2” who performs compose with Subject ”Hi Receiver2′

    if i Try to use Dataprovider the test will run sequentially, but what If I need it need to done in parallel like one in firefox and another in IE in a same machine ?

    Thanks.

  16. im unable to run it properly.. please explain it clearly what the jar’s have to be used.. and whether the above codes run in selenium web driver or not.

  17. what is difference between data-driven, keyword-driven and hybrid frameworks.. how they vary from each other and how to implement them

    • data driven is something where your code has all the logic and you are just passing different test data. keyword driven is something where you pass some keyword from outside source and based on the keyword some operation is performed. Hybrid the mixture of both.

  18. sudeepmoharana : do you have any sample examples for that, if you have please forward them to me. il learn from them and then il work on new things based on them.

  19. Hello,
    Great script. Your script goes through a section of the excel file where the starting cell is testdata and end cell is testdata. So we can this think of this as one testcase.

    I wanted to know if you could help me modify this script so that I could do the following:

    Testdate x x x
    x x x testdata

    Testdate2 x x x
    x x x testdata2

    I want the datadriver to iterate thorugh each of these “sections” and run the test.This will be basically running the same test with two sets of data set.

    Thanks

    • Hi Rayhan, with this approach this is the limitation. To achieve what you are trying, you need use data driven framework. Follow the page object model of designing your test where you abstract out the code in your test program. Use testNG to provide the data using dataProvider to your test methods. I’ll posting a solution very soon.

      Regards,
      Sudeep

  20. Hi help me out from this problem.. im trying to automate http://www.databasejournal.com/ website.. in that I took login and registration as two different classes to automate.. im unable to enter values into the fields of email and password in registration page.. when im trying find the xpath of Email and Password in registration page using firebug, in the html code they are pointing to the xpath’s of Email and password in sign in page.. how can i resolve this..

    • Hi Kalyan, that’s quite simple. Since these two elements are in an iFrame, selenium is not able to find them. First you need to select the iFrame. Then you should perform any operation on them.

  21. I did it.. i think you didnt get my problem.. il try to explain in breif.. so tat u wil understand it clearly..!
    created two classes in eclipse java and they are registration and signin.
    using firebug i written a script for both the classes, and im entering values into the fields
    im successfully entering values into signin frame and all the fields in registration frame except email and password.. when im finding the xpaths of those elements, in the firepath block its showing the xpaths of email and password of signin class.. when i run the script its showing an run time error saying element no visible.. if i removed the block of code of email and password in registration class then it is working with no errors.

  22. two web elements have same id, xpath and evrything is common, but they are in different frames.. when im trying to access the second element because of the first element its saying the second element is invisible..

  23. im automating a website when im opening its url.. it will ask for username and password(security concern).. firebug was not dispalying the xpath of those variables.. how to handle those variables

  24. Hi Sudeep, This is useful . Am using the similar pattern for DDF. But I need to write the results as well in the same excel sheet. Pls let me know the possiblity.

  25. can anyone help me in keyword driven automation framework with Hybrid framework
    if i want to click 15 links from the same page(using x-path) as a loop in keyword and Hybrid framework,
    How to loop the x-path in excel sheet
    Scenarios follows as,
    Open a Browser
    Navigate to URL
    Click on Department links (15 department links)
    Get the title of the page after each click
    Navigate back after fetching the title
    Close the Browser


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 )

Google+ photo

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

Connecting to %s