测试方法不全是无参数的。您可以在每个测试方法上使用任意数量的参数,并指示 TestNG 使用@Parameters注释向您传递正确的参数。
有两种方法可以设置这些参数:使用testng.xml或以编程方式。

testng.xml 中的参数

简单的参数值

  1. @Parameters({ "first-name" })
  2. @Test
  3. public void testSingleString(String firstName) {
  4. System.out.println("Invoked testString " + firstName);
  5. assert "Cedric".equals(firstName);
  6. }

在这段代码中,我们指定Java 方法的参数firstName应该接收名为first-name的 XML 参数的值此 XML 参数在testng.xml中定义:

  1. <suite name="My suite">
  2. <parameter name="first-name" value="Cedric"/>
  3. <test name="Simple example">
  4. <-- ... -->

@Before/After和@Factory注释可以使用相同的技术:

  1. @Parameters({ "datasource", "jdbcDriver" })
  2. @BeforeMethod
  3. public void beforeTest(String ds, String driver) {
  4. m_dataSource = ...; // look up the value of datasource
  5. m_jdbcDriver = driver;
  6. }

2个 Java 参数dsdriver将分别接收赋予属性datasource 和jdbc-driver的值。

可以使用Optional注释将参数声明为可选

  1. @Parameters("db")
  2. @Test
  3. public void testNonExistentParameter(@Optional("mysql") String db) { ... }

如果在您的testng.xml文件中没有找到名为“db”的参数,您的测试方法将接收在@Optional注释中指定的默认值:“mysql”。

@Parameters可以防止在下列位置:

  • 在任何已经有@Test、@Before/After 或@Factory注释的方法上。
  • 在您的测试类的最多一个构造函数上。在这种情况下,只要需要实例化您的测试类,TestNG 将使用初始化为testng.xml 中指定的值的参数调用这个特定的构造函数。此功能可用于将类中的字段初始化为值,然后您的测试方法将使用这些值。

笔记:

  • XML 参数映射到 Java 参数的顺序与它们在注解中的顺序相同,如果顺序不匹配,TestNG 将发出错误。
  • 参数是有范围的。在testng.xml中,您可以在 标记或下声明它们。如果两个参数具有相同的名称,则中定义的参数具有优先权。如果您需要指定适用于所有测试的参数并仅针对某些测试覆盖其值,这很方便。

带有 DataProviders 的Parameters
需要传递复杂参数或需要从 Java 创建的参数(复杂对象、从属性文件或数据库读取的对象等),在testng.xml 中指定参数可能还不够。在这种情况下,您可以使用数据提供者来提供您需要测试的值。数据提供者是您的类上的一个方法,它返回一个对象数组。此方法使用@DataProvider注释:

  1. //This method will provide data to any test method that declares that its Data Provider
  2. //is named "test1"
  3. @DataProvider(name = "test1")
  4. public Object[][] createData1() {
  5. return new Object[][] {
  6. { "Cedric", new Integer(36) },
  7. { "Anne", new Integer(37)},
  8. };
  9. }
  10. //This test method declares that its data should be supplied by the Data Provider
  11. //named "test1"
  12. @Test(dataProvider = "test1")
  13. public void verifyData1(String n1, Integer n2) {
  14. System.out.println(n1 + " " + n2);
  15. }
  16. //打印
  17. Cedric 36
  18. Anne 37

在@Test标注的方法指定了dataProvider属性,此名称必须对应于同一个类上的一个方法,该方法用@DataProvider(name=”…”)注释 并具有匹配的名称。
默认情况下,将在当前测试类或其基类之一中查找数据提供者。如果要将数据提供者放在不同的类中,它需要是静态方法或具有非参数构造函数的类,并在dataProviderClass属性中指定可以找到它的类:

  1. public class StaticProvider {
  2. @DataProvider(name = "create")
  3. public static Object[][] createData() {
  4. return new Object[][] {
  5. new Object[] { new Integer(42) }
  6. };
  7. }
  8. }
  9. public class MyTest {
  10. @Test(dataProvider = "create", dataProviderClass = StaticProvider.class)
  11. public void test(Integer n) {
  12. // ...
  13. }
  14. }

数据提供者也支持注入。TestNG 将使用测试上下文进行注入。Data Provider 方法可以返回以下类型之一:

  • 对象数组 ( Object[][] )的数组,其中第一个维度的大小是调用测试方法的次数,第二个维度的大小包含必须与测试的参数类型兼容的对象数组方法。上面的例子就是这种情况。
  • 一个Iterator。与Object[][]的唯一区别是Iterator允许您懒惰地创建测试数据。TestNG 将调用迭代器,然后使用该迭代器返回的参数一一调用测试方法。如果您有很多参数集要传递给方法并且您不想预先创建所有参数集,这将特别有用。
    • 对象数组(Object[])。这与Iterator类似,但会导致对源数组的每个元素调用一次测试方法。
    • 一个Iterator>。Object[]的懒惰替代品。导致为迭代器的每个元素调用一次测试方法。

      必须说,返回类型不仅限于Object ,因此MyCustomData[][]或Iterator 也是可能的。唯一的限制是,在迭代器的情况下,它的参数类型本身不能显式参数化。这是此功能的示例:

      1. @DataProvider(name = "test1")
      2. public Iterator<Object[]> createData() {
      3. return new MyIterator(DATA);
      4. }
      5. @DataProvider(name = "test1")
      6. public MyCustomData[] createData() {
      7. return new MyCustomData[]{ new MyCustomData() };
      8. }
      9. @DataProvider(name = "test1")
      10. public Iterator<MyCustomData> createData() {
      11. return Arrays.asList(new MyCustomData()).iterator();
      12. }
      13. @DataProvider(name = "test1")
      14. public Iterator<Stream> createData() {
      15. return Arrays.asList(Stream.of("a", "b", "c")).iterator();
      16. }

      如果您将@DataProvider声明为将java.lang.reflect.Method 作为第一个参数,TestNG 将传递此第一个参数的当前测试方法。当多个测试方法使用相同的@DataProvider并且您希望它根据它提供数据的测试方法返回不同的值时,这特别有用。
      例如,以下代码在其@DataProvider中打印测试方法的名称:

      1. @DataProvider(name = "dp")
      2. public Object[][] createData(Method m) {
      3. System.out.println(m.getName()); // print test method name
      4. return new Object[][] { new Object[] { "Cedric" }};
      5. }
      6. @Test(dataProvider = "dp")
      7. public void test1(String s) {
      8. }
      9. @Test(dataProvider = "dp")
      10. public void test2(String s) {
      11. }
      12. //打印
      13. test1
      14. test2

      数据提供者可以与属性parallel 并行运行:

      1. @DataProvider(parallel = true)
      2. // ...

      从 XML 文件运行的并行数据提供程序共享相同的线程池,默认大小为 10。您可以在 XML 文件的标记中 修改此值:

      1. <suite name="Suite1" data-provider-thread-count="20" >
      2. ...

      如果要在不同的线程池中运行一些特定的数据提供程序,则需要从不同的 XML 文件中运行它们。

      报告中的参数

      用于调用测试方法的参数显示在 TestNG 生成的 HTML 报告中。这是一个例子:
      image.png