javamaventestngcustomizing

TestNG test control with maven -Dparameter (groups?)


I have project divided into modules, each module have single XML suite with test classes to run. I run tests with maven command on different environments by passing a variable -Denv=ENV_ALIAS, handle them with System.getProperty("env").

I am rescaling my solution to handle different country versions of application (different version would have some features disabled or some flows are different). I pass a variable -DcountryCode=COUNTRY_ALIASso tests use different URLs but all tests are being run by default.

I would like to disable some tests depending on countryCode value on suite level rather than implementing in each test method a switching mechanism. I thought of Groups as the native testNG solution, but they are rather static as I need to hard-code them inside suite file. Is there a way to make it more dynamic? Alternatively I can create suite inside each module dedicated to each country but I will need to point TestNG to run a single proper suite (how can I do that?).

What would be the best way to handle? Are there any better ways to handle it?

My parent pom most important sections:

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="http://maven.apache.org/POM/4.0.0"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.autoqa</groupId>
<artifactId>autoqa-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>autoqa-parent</name>

<modules>
    <module>autoqa-common</module>
    <module>autoqa-newcrm</module>
    <module>autoqa-website</module>
    <module>autoqa-giftshop</module>
    <module>autoqa-unlimited</module>
    <module>autoqa-booking</module>
</modules>
 <build>
    <pluginManagement>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${surefireVersion}</version>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.maven.surefire</groupId>
                        <artifactId>surefire-testng</artifactId>
                        <version>${surefireVersion}</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <suiteXmlFiles>
                        <suiteXmlFile>src/test/resources/${file.name}.xml</suiteXmlFile>
                    </suiteXmlFiles>
                    <systemPropertyVariables>
                        <browserName>${browserName}</browserName>
                        <suiteName>${suiteName}</suiteName>
                        <countryCode>${countryCode}</countryCode>
                        <env>${env}</env>
                    </systemPropertyVariables>
                    <properties>
                        <property>
                            <name>surefire.testng.verbose</name>
                            <value>10</value>
                        </property>
                    </properties>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

Solution

  • The easiest way to handle this would be via groups.

    Yes by default group names have to be hard-wired into your suite xml file.

    But TestNG also lets you define your own method selectors that can be used to pick and choose what test to run and what to skip.

    One of the easiest way of building a method selector would be to leverage Beanshell scripting which TestNG supports.

    You basically can create a Beanshell method selector that looks like this and then continue to pass the group name to run via JVM arguments.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
    <suite name="Suite" parallel="false">
        <test name="Test">
            <method-selectors>
                <method-selector>
                    <script language="beanshell">
                    <![CDATA[whatGroup = System.getProperty("groupToRun");
                    groups.containsKey(whatGroup);
                    ]]>
                    </script>
                </method-selector>
            </method-selectors>
            <classes>
                <class name="organized.chaos.GroupsPlayGround" />
            </classes>
        </test> <!-- Test -->
    </suite> <!-- Suite -->
    

    In the above example, you would specify the group name to run via the JVm argument -DgroupToRun.

    You can very easily enhance this to consider multiple group names, handle scenarios wherein no group is provided etc.,

    For more information, please refer to my blog post here.