Reputation: 325
It seems I tried all the possible ways to achieve this, but no luck. I have a complex code in DataProvider (it really collects data in a complex way), which i want to be eventually parametrized by CI.
The first question here is how to even read parameters inside DataProvider.
1 One way is to get parameters from testng.xml this way:
String lolo = context.getCurrentXmlTest().getParameter("testcases");
But this doesn't solve the problem, because .xml file must be static then, and I want to pass parameters to it from Maven.
2 The other way is to read parameters from @Factory in my case:
String testCaseDataFilename = (method.getAnnotation(Factory.class)).parameters()[0];
Where @Factory is:
@Factory(dataProvider="dataProviderMethod", parameters = {"authentication-testcases.json"})
It works too, but again, doesn't solve the problem, because now parameters must be harcoded in java test files, and my @Factory uses @DataProvider for itself, and it can't receive parameters from Maven implicitly.
Additionally, I have other test parameters, which are passed by Maven, but they are used only in @Test tests, not DataProvider, and @BeforeSuite successfully receives them.
I'll try to simplify:
I am calling maven
-Dtestname=signUp -Dmyparam=1 test
and I want my DataProvider to receive this value of Dmyparam and use it to gather data. All I achieved is receiving this data with @BeforeSuite and setting it globally, but the problem is DataProvider is called before the data is set.
Upvotes: 1
Views: 2027
Reputation: 7634
All I achieved is receiving this data with @BeforeSuite and setting it globally, but the problem is DataProvider is called before the data is set.
I can't confirm this.
If you are able to declare the DataProvider within the test class you could have TestNG inject suite parameters into a @BeforeSuite
method which then stores the values as instance fields:
public class Testcase3 {
String foo;
String bar;
String baz;
// Runs before the dataprovider
@BeforeSuite
// Injected from suite.xml and VM arguments
@Parameters({"foo", "bar", "baz"})
public void init(String foo, String bar, String baz) {
this.foo = foo;
this.bar = bar;
this.baz = baz;
}
@DataProvider(name="foodp")
public Object[][] foodp(){
return new Object[][] {
new String[] { "1: " + foo, "2: " + bar, "3: " + baz }
};
}
// Injected from the data provider
@Test(dataProvider="foodp")
public void testFoo(String str1, String str2, String str3) {
System.out.println("# test: str1=" + str1);
System.out.println("# test: str2=" + str2);
System.out.println("# test: str3=" + str3);
}
}
With this suite.xml
and the VM arguments -Dbaz=buzz
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="defaultsuite">
<parameter name="foo" value="moo" />
<parameter name="bar" value="far" />
<test name="alltests">
<classes>
<class name="testng.tests.Testcase3"></class>
</classes>
</test>
</suite>
It prints:
# test: str1=1: moo
# test: str2=2: far
# test: str3=3: buzz
You can also have TestNG inject parameters into a factory:
public class TestFactory {
@Factory
@Parameters({"foo", "bar", "baz"})
public Object[] createTestInstances(String foo, String bar, String baz) {
Object[] testcases = new Object[1];
testcases[0] = new Testcase4();
((Testcase4) testcases[0]).initDataProvider(foo, bar, baz);
return testcases;
}
}
Your test could receive the data this way:
public class Testcase4 {
String foo;
String bar;
String baz;
public void initDataProvider(String foo, String bar, String baz) {
this.foo = foo;
this.bar = bar;
this.baz = baz;
}
// ...
}
This works since at least TestNG 6.9.10 and newer.
Upvotes: 0
Reputation: 5740
-D
is setting a system property.
You'll be able to get it in your code with System.getProperty("MyParam")
.
Upvotes: 2