原创: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中的数据

  1. 构造test函数,引入数据集,例如 @Test(dataProvider = "dataArray1")
  2. 测试函数增加对应的参数或者数组来接受数据集

参考代码

      /**
     * 方式一
     * 使用变量参数来接受测试数据
     */
    @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[][]管理测试数据,基本上满足了测试数据和测试逻辑相分离的原则

  • 测试用例的数据修改并不影响测试逻辑

  • 但是,当一行数据列比较多的时候,管理起来比较费眼睛,不容易知道每一个列字段的含义,维护较难。

posted @ 2021-02-10 14:55  嘉良空间  阅读(241)  评论(0)    收藏  举报