//
you're reading...
TestNG

Dynamic parameterization in TestNG

TestNG provides us users with two  ways in you can achieve data driven tests.

  1. You make use of the @DataProvider annotation wherein you bind your @Test method with a data source.
  2. You make use of the @Parameters annotation and have your @Test method read values from a suite xml file.

There are enough blogs and documentation pages that talk about both these aspects of data driven support that TestNG provides.

We will look at one unique aspect of @Parameters annotation which is not documented anywhere.

Lets say we have a test class which looks like below :

package com.rationaleemotions.wordpress.params;

import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class ParameterisedSampleTestClass {
    @Test
    @Parameters("name")
    public void hello(String name) {
        System.err.println("Hello " + name + " !");
    }
}

As seen above the test method “hello()” is expecting a parameter named “name” to be passed in via the suite xml file.

The suite file would look like below :

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="sample_suite" verbose="1" parallel="false" thread-count="2">
  <test name="sample_test">
    <parameter name="name" value="Krishnan"/>
    <classes>
      <class name="ParameterisedSampleTestClass" />
    </classes>
  </test>
</suite>

The straight forward way of changing the parameter “name” is by altering it in the TestNG suite xml.

But this can be cumbersome because we have to keep changing the suite xml file every time.

We could otherwise consider building a listener that implements org.testng.ISuiteListener or org.testng.ITestListener and then within these listener implementations build logic of reading the parameters either from within the ITestContext (or) from within the ISuite and then change the values.

Certainly doable.. But it also looks a bit too complicated, considering the fact that all we wanted to do was change the value of the parameter at runtime without changing our suite xml.

Well, today when I was fixing an issue in the TestNG codebase, I stumbled into this little treasure chest, which shows a much easier way of doing this in TestNG.

The easiest way of changing the values of parameters at runtime is to pass them via the JVM argument.

TestNG has the capability built into it wherein it also queries the System properties (JVM arguments) and tries to read the values of parameters whose name matches with what was given in the suite xml file.

Here’s how you run it via Maven

mvn clean test -Dname="John Rambo" -Dtest=ParameterisedSampleTestClass

Here’s how you run it if you were using Gradle
gradle clean test -Dname="John Rambo" -Dtest.single=ParameterisedSampleTestClass

Just remember to add
systemProperties(System.getProperties()) to your gradle build’s test section. This is because it seems Gradle doesn’t by default pass the JVM arguments it receives from the user to the test JVM. You can read more about this behavior in this stackoverflow thread.

If you were to be running them via an IDE such as IntelliJ, your run configuration would look like below:

IDE

Now isn’t that easy ?

Discussion

5 thoughts on “Dynamic parameterization in TestNG

  1. Hello,

    How can set dynamically value for a parameter of a test case?

    I have a xml file such as :

    Posted by Dana | April 12, 2018, 12:28 am
  2. How can we run the specific methods to the specific number of times in a single class in TestNG?

    Posted by akankshajain18 | June 19, 2018, 5:39 pm
  3. Hello Sir,
    Please help me in resolving my query –

    I have a bunch of test cases in TestNG. At present I have used @groups to execute test cases based on environment. What I am trying to achieve is , I will be putting down all the test case name and group in a CSV file. For eg –

    TestCaseName Group Test_Case1 Smoke,Sanity Test_Case2 Regression

    So before executing a test, user will provide input parameter as Smoke and only the Smoke test will get executed.

    I tried ‘annotation transformer’ but it can restricts only at method level. When I tried for class, it was throwing Null Pointer Exception.

    Another issue is my test class contains both test method as well as some other non test methods which calls reusable methods. As a result I can’t provide @Test in class level.

    I want a way to read my class name (Simple Class Name) from CSV along with group and based on that the test class should be enabled / disabled.

    Posted by Sanjay | March 13, 2019, 11:33 am

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 )

Google photo

You are commenting using your Google 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

%d bloggers like this: