1
votes

I have developed a keyword driven framework using Selenium WebDriver and Java.Basically I have developed a master TC sheet where it reads the TCs with run mode as yes and go to the test steps sheet and reads the keywords and based on those keywords it does the actions.

enter image description here

I am using a driver script to read these test cases.

Now I would like to run these test cases parallelly using selenium grid. There were two posts I found on stackoverflow about this.

  1. Is it possible to convert a keyword driven framework using Selenium WebDriver to Selenium grid?

But in this post it's not mentioned how this can be achieved.

  1. Executing parallel tests in a Selenium keyword driven framework

Here a solution was proposed but the report is generating as one test case passed or failed.

I have added the @Test annotation for the method in my driverscript which reads the above test cases.

public class DriverScript {
    @Test
    public void startExecution() throws Exception{
    //public static void main(String[] args) throws Exception {

        excelUtilities eu = new excelUtilities();

        Properties gldata = new Properties();
        InputStream input = new FileInputStream("src/executionEngine/config.properties");
        gldata.load(input);

        List<List<String>> testcases = new ArrayList<List<String>>();
        testcases = eu.getTestCases(gldata.getProperty("WB_PATH_TESTS"), gldata.getProperty("WB_PATH_TESTS_SHEET"));
        //System.out.println(testcases);
        DriverScript.prepareKeywords(testcases);
    }

The above method reads the test cases one by one and get the keywords from the individual test cases and based on those keywords. But since I am using @Test method for the method that reads the main test cases it is thinking that it's one test case so the report is generating as 1 test case passed even though we have two test cases above.

===============================================
Suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================

So how to run the test cases parallelly when we have keyword driven framework?

The only solution I am thinking is, the way it was mentioned in the question part of the 2nd post like creating separate methods for each test case and read the test case steps.

Is there any alternative for this on how to run a keyword driven framework on selenium grid?

Thank you.

3
Did you try any of those methods? If yes, whats the problem you faced? - Abhishek_Mishra
Hi Abhishek, As mentioned in the 2nd post link, I have created @Test annotation for the method that reads the main test cases. But it is producing the report as 1 test case passed even though we have two test cases there. May be my understanding of the solution provided is wrong. I would like to get the report as 2 TCs passed or failed. Can you please let me know if we can do it with out creating a seperate method for each test case? - Subbu

3 Answers

2
votes

Make your test to run with DataProvider option in TestNg. So that each data will be consider as seperate test.

Point your data provider to @Factory option, so that new instance will be created for each data. Now we can run the test with parallel= intances. So each test case will run in different thread in parallel.

We can rewrite your driver script as below,

public class DriverScript {

List<String> testcase;

@Factory(dataProvider = "testCases")
public DriverScript(List<String> testcase) {
    this.testcase = testcase;
}


@Test
public void runTestCase() {
  // change this method run single with List<String>. Previously you passed  List<List<String>> 
  DriverScript.prepareKeywords(testcase);
}

@DataProvider
public Object[][] testCases(ITestContext context) throws InterruptedException {
    excelUtilities eu = new excelUtilities();

    Properties gldata = new Properties();
    InputStream input = new FileInputStream("src/executionEngine/config.properties");
    gldata.load(input);

    List<List<String>> testcases = new ArrayList<List<String>>();
    testcases = eu.getTestCases(gldata.getProperty("WB_PATH_TESTS"), gldata.getProperty("WB_PATH_TESTS_SHEET"));

    List<List<String>> testcases = new ArrayList<>();
    Object[][] testCasedata= new Object[testcases.size()][1];
    for (int i = 0; i < testcases.size() ; i++) {
        testCasedata[i][0]=testcases.get(i); 
    }
    return testCasedata;

}

To run the above test with parallel=instances, we have to create testuite xml like below and run testng using this xml suite,

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="KeywordDrivenSuite" thread-count="2" parallel="instances"
    preserve-order="true" configfailurepolicy="continue">
    <test name="KeywordDrivenTest">
        <classes>
            <class
                name="com.package.DriverScript" />
        </classes>
    </test>
</suite>
1
votes

The following is how I tried it and it is working.

@DataProvider(name = "maintestcases",parallel = true)
    public static String[][] startexecution() throws Exception{

        excelUtilities eu = new excelUtilities();

        Properties gldata = new Properties();
        InputStream input = new FileInputStream("src/executionEngine/config.properties");
        gldata.load(input);

        List<List<String>> testcases = new ArrayList<List<String>>();
        testcases = eu.getTestCases(gldata.getProperty("WB_PATH_TESTS"), gldata.getProperty("WB_PATH_TESTS_SHEET"));
        int no_test_cases = testcases.size();
        String testcasesobject[][] = new String[no_test_cases][3];

        for(int i=0; i<testcases.size(); i++) {
            testcasesobject[i][0] = testcases.get(i).get(0);
            testcasesobject[i][1] = testcases.get(i).get(1);
            testcasesobject[i][2] = testcases.get(i).get(2);
        }
        System.out.println(Arrays.toString(testcasesobject));
        return testcasesobject;
    }

    @Test(dataProvider = "maintestcases")
    public static void prepareKeywords(String testcase, String wbbook, String sheet) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, InterruptedException {

        Properties gldata = new Properties();
        InputStream input = new FileInputStream("src/executionEngine/config.properties");
        gldata.load(input);

        //int total_testcases = testcases.size();

        excelUtilities ecu = new excelUtilities();

            LogUtilities.startTestCase(testcase);
            List<String> keywords = new ArrayList<String>();
            keywords = ecu.getKeywordsFromTestCase(testcase,gldata.getProperty("WB_PATH_TEST_CASES")+wbbook+".xlsx", sheet);
            getDependencies(keywords);

    }

The testng xml, I have configured it as follows.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="methods" data-provider-thread-count="2" thread-count="5">
  <test  name="Test" >
    <classes>
      <class name="executionEngine.DriverScript2"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

Please check this solution and let me know if this is ok?

Thank you.

0
votes

You can also run the tests without using xml file. Use the DriverScript provided by @Navarasu and execute them from below function

void executionDriver(){
        
    TestNG test = new TestNG();
    
    XmlSuite suite = new XmlSuite();
    suite.setName("KeywordDrivenSuite");
    
    XmlTest xmlTest = new XmlTest(suite);
    xmlTest.setName("KeywordDrivenTest");
     
    List<XmlClass> xmlClasses = new ArrayList<XmlClass> ();
    String packageName = "com.package.DriverScript";
    XmlClass xmlclass = new XmlClass(packageName);
     
    xmlClasses.add(xmlclass);
     
     
    xmlTest.setXmlClasses(xmlClasses);
     
    List<XmlTest> testList = new ArrayList<XmlTest>();
    testList.add(xmlTest);
    suite.setTests(testList);
     
    List<XmlSuite> suiteList = new ArrayList<XmlSuite>();
    suiteList.add(suite);
     
    test.setXmlSuites(suiteList);
    test.test.setThreadCount(3);//Thread count can be controlled from properties file also.
    test.run();

    }