原创:testng 参数化(2)- 使用 @DataProvider
简介
前篇提到,使用@Parameters只能处理非常简单的参数,且使用场景非常少,无法满足实际的测试需求。
测试过程中,经常需要传递非常复杂的测试用例参数,testng提供了另外一种方式 @DataProvider。
该方式必须返回类型 Object[][] 或者 Object[] 或者 Iterator<Object[]> 或者 Iterator<Object>
参考testng源码:
protected static Iterator<Object[]> invokeDataProvider(Object var0, Method var1, ITestNGMethod var2, ITestContext var3, Object var4, IAnnotationFinder var5) {
List var6 = getParameters(var1, var2, var3, var4, var5);
Object var7 = invokeMethodNoCheckedException(var1, var0, var6);
if (var7 == null) {
throw new TestNGException("Data Provider " + var1 + " returned a null value");
} else if (var7 instanceof Object[][]) {
return new ArrayIterator((Object[][])((Object[][])var7));
} else if (var7 instanceof Object[]) {
return new OneToTwoDimArrayIterator((Object[])((Object[])var7));
} else if (var7 instanceof Iterator) {
Type var8 = var1.getGenericReturnType();
if (var8 instanceof ParameterizedType) {
ParameterizedType var9 = (ParameterizedType)var8;
Class var10 = (Class)var9.getActualTypeArguments()[0];
return (Iterator)(var10.isArray() ? (Iterator)var7 : new OneToTwoDimIterator((Iterator)var7));
} else {
return (Iterator)var7;
}
} else {
throw new TestNGException("Data Provider " + var1 + " must return either Object[][] or Object[] or Iterator<Object[]> or Iterator<Object>, not " + var1.getReturnType());
}
}
@DataProvider 的四种写法
@DataProvider 的四种写法分别对应不同的数据类型,参考代码
public class Liang6DemoDataProvider {
/**
* 方式一
* Object[] 类型
*/
@DataProvider(name = "dataArray1")
public Object[] dataArray1(){
return new Object[]{
"jerry","mouse"
};
}
/**
* 方式二
* Object[][] 类型
*/
@DataProvider(name = "dataArray2")
public Object[][] dataArray2(){
return new Object[][]{
{"jerry","mouse"},
{"tom","cat"}
};
}
/**
* 方式三
* Iterator<Object> 类型
*/
@DataProvider(name = "dataIterator1")
public Iterator<Object> dataIterator1(){
List<Object> list = new ArrayList<Object>(){};
list.add("tom");
list.add("cat");
return list.iterator();
}
/**
* 方式四
* Iterator<Object[]> 类型
*/
@DataProvider(name = "dataIterator2")
public Iterator<Object[]> dataIterator2(){
List<Object[]> arrList = new ArrayList<Object[]>();
arrList.add(new Object[]{"tom","cat"});
arrList.add(new Object[]{"jerry","mouse"});
return arrList.iterator();
}
}
四种数据集合的说明
方式一: 返回Object[] 类型的数组,数组的的每一个元素对应一个用例
方式二: 返回Object[][] 类型的二维数组,二维数组中的每一行对应一个用例
方式三: 返回Iterator<Object> 类型,迭代器中的每一个Oject对应一个用例
方式四: 返回Iterator<Object[]> 类型,迭代器中的每一个Object[]对应一个用例
** 通常情况,“方式二”和“方式四”使用最多,最容易描述测试用例**
** 当测试用例很多的时候,可以使用“方式四”,使用迭代器,一次生成一个测试用例,迭代完成,这样可以节约系统资源**
使用@DataProvider中的数据
- 构造test函数,引入数据集,例如 @Test(dataProvider = "dataArray1")
- 测试函数增加对应的参数或者数组来接受数据集
参考代码
/**
* 方式一
* 使用变量参数来接受测试数据
*/
@Test(dataProvider = "dataArray1")
public void doDataArray1(String strName){
System.out.println("测试用例:" + strName);
}
/**
* 方式二
* 使用变量参数来接受测试数据
*/
@Test(dataProvider = "dataArray2")
public void doDataArray2(String strName, String strHobby){
System.out.println("测试用例:" + strName + " " + strHobby);
}
/**
* 方式二
* 使用数组来接受测试数据
*/
@Test(dataProvider = "dataArray2")
public void doDataArray2(Object[] arrData){
System.out.println("测试用例:" + arrData[0] + " " + arrData[1]);
}
/**
* 方式三
* 使用变量来接受测试数据
*/
@Test(dataProvider = "dataIterator1")
public void dodataIterator1(String strData){
System.out.println("测试用例:" + strData);
}
/**
* 方式四
* 使用数组来接受测试数据
*/
@Test(dataProvider = "dataIterator2")
public void dodataIterator2(Object[] arrData){
System.out.println("测试用例:" + arrData[0] + " " + arrData[1]);
}
运行结果
测试用例:jerry
测试用例:mouse
测试用例:jerry mouse
测试用例:tom cat
测试用例:jerry mouse
测试用例:tom cat
测试用例:tom
测试用例:cat
测试用例:tom cat
测试用例:jerry mouse
===============================================
Default Suite
Total tests run: 10, Failures: 0, Skips: 0
===============================================
版权所有,本文为原创文章,转载请注明出处
https://www.cnblogs.com/liang6/p/14395142.html
总结
-
使用Object[][]来创建数据集合,一行数据为一个测试用例,测试函数中获取到行数据然后执行
-
使用Object[][]管理测试数据,基本上满足了测试数据和测试逻辑相分离的原则
-
测试用例的数据修改并不影响测试逻辑
-
但是,当一行数据列比较多的时候,管理起来比较费眼睛,不容易知道每一个列字段的含义,维护较难。
浙公网安备 33010602011771号