TestNG数据驱动

TestNG数据驱动TestNG 数据驱动 testng 的功能很强大 利用 DataProvider 可以做数据驱动 数据源文件可以是 EXCEL XML YAML 甚至可以是 TXT 文本 DataProvider 注解简介 DataProvider 标记专门为测试方法提供参数的方法 这类方法必须返回 Object 类型的二维数组或者 Iterator Object 每一行的 Object Object

TestNG数据驱动

testng的功能很强大,利用@DataProvider可以做数据驱动,数据源文件可以是EXCEL,XML,YAML,甚至可以是TXT文本。

@DataProvider注解简介:

@DataProvider标记专门为测试方法提供参数的方法。这类方法必须返回Object[ ][ ]类型的二维数组或者Iterator[],每一行Object[],都是测试方法的一个测试数据集,测试方法会为每个测试数据集执行一次。如果没有指定参数的名称,则默认为方法的名称,方法的名称没有限制。

 

@DataProvider的小例子:

import java.lang.reflect.Method;

 

import org.testng.annotations.DataProvider;

import org.testng.annotations.Test;

 

public class test {

    @DataProvider(name = “user”)

    public Object[][] createUser(Method m) {

        System.out.println(m.getName());

        return new Object[][] { { “root”“root” }, { “test”“root” }, { “test”“test” } };

    }

 

    @Test(dataProvider = “user”)

    public void verifyUser(String username, String password) {

        System.out.println(“Verify User : “ + username + “:” + password);

        assert username.equals(password);

    }

 

}

如上所示@DataProvider注解了createUser方法,返回的二位数组里有三行数据,每行两列。所以@Test(dataProvider = “user”)注解的verifyUser方法有两个参数,用来接收每一行的两个数据,如果createUser返回的数据数组的列数和verifyUser的参数个数不同就会报错的。因为返回的有三行,所以verifyUser会被执行三次。结果如下:

PASSED: verifyUser(“root”, “root”)

FAILED: verifyUser(“test”, “root”)

PASSED: verifyUser(“test”, “test”)

CSV文件数据读取和@DataProvider

我自己做了一个以csv为例的测试架子,部分代码可通用。

 

CSV文件读取类(可通用,目录自己可以修改,也可改变成读取EXCEL、TXT等文件):

import java.io.BufferedReader;

import java.io.File;

import java.io.FileReader;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.TreeMap;

import java.util.regex.Matcher;

 

public class CSVData implements Iterator
 {

 

    private BufferedReader br        = null;

    //行数

    private int            rowNum    = 0;

    //获取次数

    private int            curRowNo  = 0;

    //列数

    private int            columnNum = 0;

    //key名

    private String[]       columnName;

    //csv中所有行数据

    private List

   
csvList;

    //实际想要的行数据

    private List

   
csvListNeed;

 

    /*

    * 在TestNG中由@DataProvider(dataProvider = “name”)修饰的方法

    * 取csv时,调用此类构造方法(此方法会得到列名并将当前行移到下以后)执行后,转发哦

    * TestNG自己的方法中去,然后由它们调用此类实现的hasNext()、next()方法

    * 得到一行数据,然后返回给由@Test(dataProvider = “name”)修饰的方法,如此

    * 反复到数据读完为止

    * 

    * 

    * @param filepath CSV文件名

    * @param casename 用例名

    */

    public CSVData(String fileName, String caseId) {

        try {

            File directory = new File(“.”);

            String ss = “resources.”;

            File csv = new File(directory.getCanonicalFile() + “\\src\\test\\” + ss.replaceAll(“\\.”, Matcher.quoteReplacement(“\\”))

                                + fileName + “.csv”);

 

            br = new BufferedReader(new FileReader(csv));

            csvList = new ArrayList

();

            while (br.ready()) {

                csvList.add(br.readLine());

                this.rowNum++;

            }

            String stringValue[] = csvList.get(0).split(“,”);

            this.columnNum = stringValue.length;

 

            columnName = new String[stringValue.length];

 

            for (int i = 0; i < stringValue.lengthi++) {

 

                columnName[i] = stringValue[i].toString();

 

            }

            this.curRowNo++;

            csvListNeed = new ArrayList

();

            for (int i = 1; i < rowNumi++) {

                String values[] = csvList.get(i).split(“,”);

                if (caseId.equals(values[0])) {

                    csvListNeed.add(csvList.get(i));

                }

            }

            this.rowNum = 2;//就取一行

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

 

    @Override

    public boolean hasNext() {

        if (this.rowNum == 0 || this.curRowNo >= this.rowNum) {

            try {

                br.close();

            } catch (Exception e) {

                e.printStackTrace();

            }

            return false;

        } else {

            return true;

        }

    }

 

    @Override

    public Object[] next() {

        /*

        * 将数据放入map 

        */

        Map

 
s = 
new TreeMap

();

        String csvCell[] = csvListNeed.get(0).split(“,”);

        for (int i = 0; i < this.columnNumi++) {

            String temp = “”;

            try {

                temp = csvCell[i].toString();

            } catch (ArrayIndexOutOfBoundsException ex) {

                temp = “”;

            }

            s.put(this.columnName[i], temp);

        }

        Object r[] = new Object[1];

        r[0] = s;

        this.curRowNo++;

        return r;

    }

 

    @Override

    public void remove() {

        throw new UnsupportedOperationException(“remove unsupported”);

    }

 

}

 

这个类实现了Iterator
迭代器,TestNG调用此类实现的hasNext()、next()方法得到一行数据,在next()方法中可以看到,我把数据是放在Map

中的,再把map放在Object[]里,所以测试方法的参数就必须是一个Map

。我这里改成了只读取一行,因为一个csv文件的一个caseId只应该有一行。


 

数据驱动类:

import java.lang.reflect.Method;

import java.util.Iterator;

 

import org.testng.annotations.DataProvider;

 

public class DataProviderTest {

 

    /

     * @DataProvider的返回值类型只能是Object[][]与Iterator[]

     * 

     * @param method

     * @return

     */

    @DataProvider

    public Iterator
 dataSource(Method 
method) {

        return (Iterator
) new CSVData(method.getDeclaringClass().getSimpleName(), method.getName());

    }

 

}

Method方法是通过反射获取的,总之哪个方法调用我Method就是那个方法。

method.getDeclaringClass().getSimpleName()可以获取方法所属的类的类名。

我这里规定了csv的文件名就是测试类的类名,用例名就是方法名。

return (Iterator
) new CSVData(…)就是将CSV读取类读取的结果返回,返回的类型是Iterator
的,符合
@DataProvider的返回值类型要求。当@Test(dataProvider = “dataSource”)注解的测试方法执行时就会调用Iterator的hasNext()判断是否有数据和next()获取数据。

 

测试类:

 

import java.util.Map;

 

import org.testng.annotations.Test;

 

public class DataTest extends DataProviderTest {

    @Test(dataProvider = “dataSource”)

    public void id2(Map

 
data) {

        System.out.println(data);

    }

 

    @Test(dataProvider = “dataSource”)

    public void id1(Map

 
data) {

        System.out.println(data);

    }

 

}

 

DataTest.csv文件如下:

TestNG数据驱动

 

输出结果如下:

PASSED: id1({caseId=id1, flag=Y, property=flowModel, type=com.mybank.bkloanapply.core.model.BaseModel, value=BaseModel.csv@1})

PASSED: id2({caseId=id2, flag=M, property=context, type=java.util.Map, value=a:Object.csv@1})

 

总结

通过以上例子可以看到,无论@DataProvider注解的方法返回的是Object[ ][ ]还是Iterator[],最后测试方法获得的参数都是Object[ ]里放的东西,第一个例子里放了两列String,第二个例子里放了Map
,所以第一个测试类的测试方法的参数是两个String,第二个测试类的测试方法的参数是Map
,必须保持一致才行。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/198562.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午2:55
下一篇 2026年3月26日 下午2:56


相关推荐

  • 曼昆 《经济学原理》(第5版)_曼昆经济学原理第几版好

    曼昆 《经济学原理》(第5版)_曼昆经济学原理第几版好第一章经济学十大原理在本章中你将——知道经济学研究稀缺性资源配置考察人们面临的一些交替关系知道机会成本的含义懂得在作出决策时如何运用边际推理讨论激励如何影响人们的行为考虑为什么人们或国家之间的交易可以使各方面受益-9经济学原理第五版 讨论为什么市场是一种良好的、但并不是完善的资源配置方式了解是什么因

    2026年1月22日
    4
  • 数码视讯Q5刷armbian+squeezelite

    数码视讯Q5刷armbian+squeezelite数码视讯Q5刷armbian+squeezelite数码视讯Q5机顶盒介绍:数码视讯Q5CPU:晶晨S905M4核1.5G内存:1g存储:8G显卡:Mali-450接口:HDMIUSB2.0(两个)AVTF卡槽RJ45(1000M)带2.4无线电源:DC12V1A目前闲鱼的售价在:50-70元。购买数码视讯Q5时,必须问清楚,是否可以插tf卡打游戏,可以插tf卡打游戏才买,可以插tf卡打游戏才买,可以插tf卡打游戏才买,以…

    2025年6月13日
    6
  • LVDS接口定义详解

    LVDS接口定义详解LVDS 接口 1 LVDS 接口概述 液晶显示器驱动板输出的数字信号中 除了包括 RGB 数据信号外 还包括行同步 场同步 像素时钟等信号 其中像素时钟信号的最高频率可超过 28MHz 采用 TTL 接口 数据传输速率不高 传输距离较短 且抗电磁干扰 EMI 能力也比较差 会对 RGB 数据造成一定的影响 另外 TTL 多路数据信号采用排线的方式来传送 整个排线数量达几十路 不但连接不便 而且不适合超薄

    2026年3月16日
    2
  • 清华大学生命科学博士就业_已拥有的是全部的生命

    清华大学生命科学博士就业_已拥有的是全部的生命不错的组合数学题。同时这也驱使我去看积灰好久的《具体数学》(看了yu大的blog后)。然后看得头秃……得到一个不等式前缀和大于等于取了的个数。所以如果把每个卡的值减一,问题就变成了求一个排列,使得前

    2022年8月2日
    7
  • 操作系统中的同步和异步

    操作系统中的同步和异步操作系统中同步、异步性概念首先我们从操作系统的发展中学习什么是异步性。在操作系统发展的初期阶段,CPU处理的是作业,而且是单道批处理。什么意思呢?就是一个作业从提交到结束,程序员都不能干预,此时整台计算机就为这一个作业服务(可想有多少资源被”浪费”),这样有一点好处就是整个程序是”封闭的”。这样的操作表明人和机器是没有交互的。那我们怎么实现人机交互呢?这个答案是中断。中断的引入,使得工作人员能…

    2025年7月5日
    4
  • pycharm 解决控制台中文乱码[通俗易懂]

    pycharm 解决控制台中文乱码[通俗易懂]改为GBK即可

    2022年8月27日
    9

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号