TestNG:将参数从 Maven 传递给 DataProvider
TestNG: Pass parameter to DataProvider from Maven
似乎我尝试了所有可能的方法来实现这一目标,但没有成功。我在 DataProvider 中有一段复杂的代码(它确实以一种复杂的方式收集数据),我希望它最终被 CI.
参数化
这里的第一个问题是如何在DataProvider 中读取读取 参数。
1 一种方法是通过这种方式从 testng.xml 获取参数:
String lolo = context.getCurrentXmlTest().getParameter("testcases");
但这并不能解决问题,因为.xml文件必须是静态的,我想从Maven向它传递参数。
2 在我的例子中,另一种方法是从@Factory 读取参数:
String testCaseDataFilename = (method.getAnnotation(Factory.class)).parameters()[0];
@Factory 所在位置:
@Factory(dataProvider="dataProviderMethod", parameters = {"authentication-testcases.json"})
它也能工作,但还是没有解决问题,因为现在必须在 java 测试文件中对参数进行硬编码,而我的@Factory 自己使用了@DataProvider,它无法接收来自 Maven 的隐式参数。
另外,我还有其他的测试参数,是Maven传过来的,但是只在@Test测试中使用,没有在DataProvider中使用,@BeforeSuite成功接收。
我会尽量简化:
我正在调用 maven
-Dtestname=signUp -Dmyparam=1 test
并且我希望我的 DataProvider 接收 Dmyparam 的这个值并使用它来收集数据。我所取得的成就是使用@BeforeSuite 接收此数据并将其全局设置,但问题是在设置数据之前 调用了 DataProvider。
-D
正在设置系统 属性.
您可以使用 System.getProperty("MyParam")
在您的代码中获取它。
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.
我无法确认这一点。
如果您能够在测试中声明 DataProvider class,您可以让 TestNG 将套件参数注入 @BeforeSuite
方法,然后将值存储为实例字段:
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);
}
}
有了这个 suite.xml
和 VM 参数 -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>
它打印:
# test: str1=1: moo
# test: str2=2: far
# test: str3=3: buzz
您还可以让 TestNG 将参数注入工厂:
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;
}
}
您的测试可以这样接收数据:
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;
}
// ...
}
这至少适用于 TestNG 6.9.10 和更新版本。
似乎我尝试了所有可能的方法来实现这一目标,但没有成功。我在 DataProvider 中有一段复杂的代码(它确实以一种复杂的方式收集数据),我希望它最终被 CI.
参数化这里的第一个问题是如何在DataProvider 中读取读取 参数。
1 一种方法是通过这种方式从 testng.xml 获取参数:
String lolo = context.getCurrentXmlTest().getParameter("testcases");
但这并不能解决问题,因为.xml文件必须是静态的,我想从Maven向它传递参数。
2 在我的例子中,另一种方法是从@Factory 读取参数:
String testCaseDataFilename = (method.getAnnotation(Factory.class)).parameters()[0];
@Factory 所在位置:
@Factory(dataProvider="dataProviderMethod", parameters = {"authentication-testcases.json"})
它也能工作,但还是没有解决问题,因为现在必须在 java 测试文件中对参数进行硬编码,而我的@Factory 自己使用了@DataProvider,它无法接收来自 Maven 的隐式参数。
另外,我还有其他的测试参数,是Maven传过来的,但是只在@Test测试中使用,没有在DataProvider中使用,@BeforeSuite成功接收。
我会尽量简化:
我正在调用 maven
-Dtestname=signUp -Dmyparam=1 test
并且我希望我的 DataProvider 接收 Dmyparam 的这个值并使用它来收集数据。我所取得的成就是使用@BeforeSuite 接收此数据并将其全局设置,但问题是在设置数据之前 调用了 DataProvider。
-D
正在设置系统 属性.
您可以使用 System.getProperty("MyParam")
在您的代码中获取它。
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.
我无法确认这一点。
如果您能够在测试中声明 DataProvider class,您可以让 TestNG 将套件参数注入 @BeforeSuite
方法,然后将值存储为实例字段:
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);
}
}
有了这个 suite.xml
和 VM 参数 -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>
它打印:
# test: str1=1: moo
# test: str2=2: far
# test: str3=3: buzz
您还可以让 TestNG 将参数注入工厂:
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;
}
}
您的测试可以这样接收数据:
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;
}
// ...
}
这至少适用于 TestNG 6.9.10 和更新版本。