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!
You are perhaps looking for something like this:
Note:
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.String
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 (cedric@beust.com)
...
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