Kicking off parallel runs in TestNG from comma separated jenkins string paramater

40 Views Asked by At

Currently I am using data provider like this

static Object[][] dataProvider() {
       return new Object[][]{
                [a],
                [b],
                [c],
       }
}

Have testNG Options like this in build.gradle,

 useTestNG() {
        options ->
            options.parallel = 'tests'
            options.threadCount = 3
}

and have test like this,

 @Test(dataProvider = "dataProvider", dataProviderClass = RunIdProvider.class)
void testFunction(String variable) {
 // do something
}

Doing this allows me to kick off 3 tests in parallel each using data a or b or c.

I want to pass in a string parameter in jenkins say - a,b,c and that should kick off 3 tests in parallel from testNG each using one of the values a or b or c.

More specifically the number of parallel tests kicked off should be based on number of comma separated values in the string - meaning if I pass in a,b,c,d - it should kick off 4 tests in parallel.

Is this possible ? Has anyone done this before ? Will greatly appreciate any example. Thanks!

1

There are 1 best solutions below

4
Krishnan Mahadevan On BEST ANSWER

You are perhaps looking for something like this:

Note:

  • The data provider tries to look for a parameter named csv_values in the suite file and tries to parse it as a csv only if it is found. If its not found it defaults to some default values.
  • The data provider assumes that the test method which is going to be consuming its data requires only 1 parameter and the parameter type is a String
  • Your data provider now works in parallel and its data set is based on the parameter passed from the suite.

Here's how the test class that contains a dynamic data provider which is capable of transforming a csv into a data set would look like:

import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

public class SampleTestCase {

    @DataProvider(name = "dp", parallel = true)
    public static Object[][] dataProvider(ITestContext context) {
        Map<String, String> parameters = context.getCurrentXmlTest().getAllParameters();
        String value = Optional.ofNullable(parameters.get("csv_values")).orElse("");
        if (value.isEmpty()) {
            return new Object[][]{
                    {"z"}
            };
        }
        List<String> csv = Arrays.stream(value.split(",")).collect(Collectors.toList());
        Object[][] result = new Object[csv.size()][1];
        AtomicInteger index = new AtomicInteger(0);
        csv.forEach(it -> result[index.getAndIncrement()][0] = it);
        return result;
    }

    @Test(dataProvider = "dp")
    public void testMethod(String value) {
        System.err.println("Thread Id: " + Thread.currentThread().getId()  + ", Value = " + value);
    }
}

Here's how the suite file looks like:

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="78111465_suite" verbose="2">
    <parameter name="csv_values" value="a,b,c,d,e,f"/>
    <test name="78111465_test">
        <classes>
            <class name="com.rationaleemotions.so.qn78111465.SampleTestCase"/>
        </classes>
    </test>
</suite>

Here's the execution output

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
...
... TestNG 7.9.0 by Cédric Beust ([email protected])
...

Thread Id: 20, Value = f
Thread Id: 19, Value = e
Thread Id: 15, Value = a
Thread Id: 17, Value = c
Thread Id: 16, Value = b
Thread Id: 18, Value = d
PASSED: com.rationaleemotions.so.qn78111465.SampleTestCase.testMethod("f")
PASSED: com.rationaleemotions.so.qn78111465.SampleTestCase.testMethod("e")
PASSED: com.rationaleemotions.so.qn78111465.SampleTestCase.testMethod("b")
PASSED: com.rationaleemotions.so.qn78111465.SampleTestCase.testMethod("d")
PASSED: com.rationaleemotions.so.qn78111465.SampleTestCase.testMethod("c")
PASSED: com.rationaleemotions.so.qn78111465.SampleTestCase.testMethod("a")

===============================================
    78111465_test
    Tests run: 1, Failures: 0, Skips: 0
===============================================


===============================================
78111465_suite
Total tests run: 6, Passes: 6, Failures: 0, Skips: 0
===============================================


Process finished with exit code 0