Search code examples
seleniumtestngbeanshelltestng.xml

"Executing a test in testNG based on condition"


i have a testNG xml which will execute a (one)test case 2 times. the difference between each time is the test level parameter. so i have to execute the test case with 2 different parameter (2 user).

Now i will be creating new xml (suite of xml) from which i will call the existing xml. i will define a new parameter in suite xml for the User.

Expectation is if suite xml parameter="user2", then the child xml should execute the test case only once which has parameter as user2.

i tried beanshell scripting and found it useful for method-selector. but i want to make decision for test level and not method level.

Below is the testNG.xml which calls the test case 2 times with different user value. TestCase will be called first time with User="USER1" and second time with User="USER2".

<?xml version="1.0"?>
<suite name="TestLoad">
    <test verbose="10" name="TestForUser1" preserve-order="true">
        <parameter name="User" value="USER1"/>
        <classes>
            <class name="com.dummy.test.TestCase"/>
        </classes>
    </test>
    <test verbose="10" name="TestForUser2" preserve-order="true">
        <parameter name="User" value="USER2"/>
        <classes>
            <class name="com.dummy.test.TestCase"/>
        </classes>
    </test>
</suite>

Below is the Suite of xml which i will be newly creating to call many testng.xml described as above.

<?xml version="1.0"?>
<suite name="suiteOfXml">
    <parameter name="User" value="USER1"/>
    <suite-files>
        <suite-file path="TestLoad.xml"/>
        <suite-file path="TestStage.xml"/>
    </suite-files>
</suite>

Expectation is something like:

  • if the suiteOfXml has User="USER1" then each testNG xml should run the TestCase only once with User=USER1.
  • if the suiteOfXml has User="USER2" then each testNG xml should run the TestCase only once with User=USER2.
  • if the suiteOfXml has User="ALL" then each testNG xml should run the TestCase twice. once with User=USER1 and next time with User=USER2.

I cannot make any changes to the TestCase (java class level). condition should be made at xml only.

Kindly provide a possible solution. Thanks in advance


Solution

  • Here's what you need to be doing to get past this issue (You dont need a suite of suites etc., )

    • Create an implementation of the TestNG listener interface org.testng.IAlterSuiteListener within which you basically read the value of the parameter and then based on it, you decide which <test> should be created and how it would look like etc.,
    • You create a suite xml file that only contains the parameter which would help you decide what <test> should be there and also a reference to the newly created listener from the previous step.

    That should do. Using this approach you can basically do all the things that you have listed out.

    Here's how a sample listener would look like (In this example, we are getting the packages to be executed via a JVM argument and then based on that, we are building our <test> tag)

    package com.rationaleemotions.wordpress;
    
    import org.testng.IAlterSuiteListener;
    import org.testng.xml.XmlPackage;
    import org.testng.xml.XmlSuite;
    import org.testng.xml.XmlTest;
    
    import java.util.Collections;
    import java.util.List;
    
    public class SimpleSuiteAlterer implements IAlterSuiteListener {
        @Override
        public void alter(List suites) {
            XmlSuite suite = suites.get(0);
            XmlTest xmlTest = new XmlTest(suite);
            xmlTest.setName("CommandLine_Test");
            String packages = System.getProperty("package", suite.getParameter("package"));
            XmlPackage xmlPackage = new XmlPackage(packages);
            xmlTest.setXmlPackages(Collections.singletonList(xmlPackage));
        }
    }
    

    And here's how the suite xml would look like

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
    <suite name="Package-Suites" verbose="2">
        <parameter name="package" value="com.rationaleemotions"/>
        <listeners>
            <listener class-name="com.rationaleemotions.wordpress.SimpleSuiteAlterer"/>
        </listeners>
    </suite>
    

    For a more detailed explanation and some code samples, refer to my blog post https://rationaleemotions.com/building_dynamic_testng_suites/