TestNG参数化有何特别之处
大家好,我是刚哥。
TestNG作为Java技术栈一个极其强大的测试框架,想必在参数化这块也有一定的特别之处,本文就来根据官方文档,对TestNG参数化进行一探究竟。
TestNG参数化有两种方式,第一种是从testng.xml读取数据,第二种是通过代码读取数据。
从testng.xml读取数据
直接看示例:
@Parameters({ "first-name" }) @Test public void testSingleString(String firstName) { System.out.println("Invoked testString " + firstName); assert "Cedric".equals(firstName); }
<suite name="My suite"> <parameter name="first-name" value="Cedric"/> <test name="Simple example"> <-- ... -->
@Parameters指定参数化名字。
测试方法入参与参数化名字一一对应。
testng.xml中
<parameter>
定义参数化的值。在testng.xml中,
<parameter>
既可以定义在<suite>
中也可以定义在<test>
中,如果有同名的,会以<test>
的覆盖<suite>
。
@Parameters既可以作用到
@Test,也可以作用到
@Before/After和
@Factory,比如:
@Parameters({ "datasource", "jdbcDriver" }) @BeforeMethod public void beforeTest(String ds, String driver) { m_dataSource = ...; // look up the value of datasource m_jdbcDriver = driver; }
也可以作用到测试类的构造方法中,但是只能最多一个构造方法,这样就能在初始化类的时候,进行参数化赋值,便于测试方法使用
@Optional用于标识参数是否可选,比如:
@Parameters("db") @Test public void testNonExistentParameter(@Optional("mysql") String db) { ... }
- 如果db这个参数取不到名字,那么就会取mysql的值。
通过代码读取数据
第一种参数化方式其实比较鸡肋,第二种方式才是TestNG参数化的灵魂,用到了@DataProvider,它会返回一个二维数组:
import org.testng.annotations.DataProvider; import org.testng.annotations.Test; public class DPTest { @DataProvider(name = "test1") public Object[][] createData1() { return new Object[][] { { "Cedric", 36}, { "Anne", 37}, }; } @Test(dataProvider = "test1") public void verifyData1(String n1, Integer n2) { System.out.println(n1 + " " + n2); } }
- @DataProvider用于生产数据,name是唯一标识。
- 在@Test中通过dataProvider属性指定name。
- 测试方法的入参跟数组中元素一一对应。
默认@DataProvider和@Test是在同一个类中,如果想放在不同的类,那么需要定义为静态方法(或者无参数构造方法的类),比如:
import org.testng.annotations.DataProvider; public class StaticProvider { @DataProvider(name = "create") public static Object[][] createData() { return new Object[][] { new Object[] {42} }; } }
import org.testng.annotations.Test; public class DiffClazzTest { @Test(dataProvider = "create", dataProviderClass = StaticProvider.class) public void test(Integer n) { System.out.println(n); } }
- createData()为static。
- 需要额外通过@Test的dataProviderClass属性指定@DataProvider所在的类。
@DataProvider的返回值(参数类型)除了已经提到的
Object[][],还可以是
Iterator<Object[]>,它不会一次性生成所有数据,而是每调用一次生成一次,节约内存,比如:
import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.util.Arrays; import java.util.Iterator; public class IterTest { @DataProvider(name = "test1") public Iterator<Object[]> createData1() { Object[][] myObjects = new Object[][]{ {"Cedric", 36}, {"Anne", 37}, }; return Arrays.asList(myObjects).iterator(); } @Test(dataProvider = "test1") public void verifyData1(String n1, Integer n2) { System.out.println(n1 + " " + n2); } }
看到这里,对@DataProvider已经有了足够的认识,它支持两种参数类型:
Object[][]
Iterator<Object[]>
假如测试方法只有一个入参,是不是只能用二维来实现:
import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.util.Arrays; import java.util.Iterator; public class IterTest { @DataProvider(name = "test1") public Iterator<Object[]> createData1() { Object[][] myObjects = new Object[][]{ {"x"}, {"y"} }; return Arrays.asList(myObjects).iterator(); } @Test(dataProvider = "test1") public void verifyData1(String n) { System.out.println(n); } }
其实不是,@DataProvider支持一维数组:
import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.util.Arrays; import java.util.Iterator; public class IterTest { @DataProvider(name = "test1") public Object[] createData1() { Object[] myObjects = new Object[]{ "x", "y" }; return myObjects; } @Test(dataProvider = "test1") public void verifyData1(String n) { System.out.println(n); } }
以及一维数组的迭代器:
import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.util.Arrays; import java.util.Iterator; public class IterTest { @DataProvider(name = "test1") public Iterator<Object> createData1() { Object[] myObjects = new Object[]{ "x", "y" }; return Arrays.asList(myObjects).iterator(); } @Test(dataProvider = "test1") public void verifyData1(String n) { System.out.println(n); } }
最精彩的来了,@DataProvider支持反射,也就是反向获取测试方法的信息:
@DataProvider(name = "dp") public Object[][] createData(Method m) { System.out.println(m.getName()); // print test method name return new Object[][] { new Object[] { "Cedric" }}; } @Test(dataProvider = "dp") public void test1(String s) { } @Test(dataProvider = "dp") public void test2(String s) { }
- createData的入参是java.lang.reflect.Method,这样就能获取到测试方法的信息,比如这里的getName()会依次拿到test1、test2。
@DataProvider还支持并发:
@DataProvider(parallel = true) // ...
默认是10个线程,可以在testng.xml中修改:
<suite name="Suite1" data-provider-thread-count="20" > ...
一个xml共享一个线程池,如果要用多个线程池,那么需要创建多个testng.xml。
锦上添花的是,TestNG的参数化会打印在测试报告中:
参考资料:
https://testng.org/doc/documentation-main.html 5.6 - Parameters
- testNG参数传递方式
- TestNG系列-第四章 testNG之命令行运行及参数详解
- ui-router,目前见过最全的。特别是route参数
- TestNG的参数化测试、共享线程池配置、参数默认值配置
- tomcat作为windows服务的参数配置,特别是PermSize的设置
- vbs所有参数都是按引用传递的,在循环里特别要注意
- TestNg参数化测试之读取csv文件
- 页面跳转,特别是struts.xml中result带参数实现
- TestNG入门笔记[4]: testng.xml 执行case —— 参数的传递
- TestNG-使用priority参数
- TestNG系列-第五章 测试方法、测试类和测试分组(续2)-参数
- testng的xml文件中包含中文参数
- 基于Java+HttpClient+TestNG的接口自动化测试框架(四)-------参数存取处理
- IDEA 使用特别卡?参数调优了解一下
- TestNG参数化测试之使用testng.xml
- tomcat作为windows服务的参数配置,特别是PermSize的设置
- c#中使用api(shfileoperation)进行文件操作,特别详解了回收站相关参数
- 如果参数为对象自己要特别小心被释放
- BMDP为常规的统计分析提供了大量的完备的函数系统,如:方差分析(ANOVA)、回归分析(Regression)、非参数分析(Nonparametric Analysis)、时间序列(Times Series)等等。此外,BMDP特别擅于进行出色的生存分析(Survival Analysis )。许多年来,一大批世界范围内顶级的统计学家都曾今参与过BMDP的开发工作。这不仅使得BMDP的权威性得到
- TestNG官方文档中文版(6)-参数