0

0

TestNG数据驱动简介

(*-*)浩

(*-*)浩

发布时间:2019-08-26 16:19:02

|

2863人浏览过

|

来源于CSDN

转载

testng数据驱动

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

TestNG数据驱动简介

@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等文件):

Procys
Procys

AI驱动的发票数据处理

下载
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.length; i++) {
                columnName[i] = stringValue[i].toString();
            }
            this.curRowNo++;
            csvListNeed = new ArrayList();
            for (int i = 1; i < rowNum; i++) {
                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.columnNum; i++) {
            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);
    }
}

输出结果如下:

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,必须保持一致才行。

相关文章

驱动精灵
驱动精灵

驱动精灵基于驱动之家十余年的专业数据积累,驱动支持度高,已经为数亿用户解决了各种电脑驱动问题、系统故障,是目前有效的驱动软件,有需要的小伙伴快来保存下载体验吧!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

pdf怎么转换成xml格式
pdf怎么转换成xml格式

将 pdf 转换为 xml 的方法:1. 使用在线转换器;2. 使用桌面软件(如 adobe acrobat、itext);3. 使用命令行工具(如 pdftoxml)。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1878

2024.04.01

xml怎么变成word
xml怎么变成word

步骤:1. 导入 xml 文件;2. 选择 xml 结构;3. 映射 xml 元素到 word 元素;4. 生成 word 文档。提示:确保 xml 文件结构良好,并预览 word 文档以验证转换是否成功。想了解更多xml的相关内容,可以阅读本专题下面的文章。

2085

2024.08.01

xml是什么格式的文件
xml是什么格式的文件

xml是一种纯文本格式的文件。xml指的是可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。想了解更多相关的内容,可阅读本专题下面的相关文章。

998

2024.11.28

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

75

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

32

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

59

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

36

2025.11.27

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

8

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.5万人学习

C# 教程
C# 教程

共94课时 | 6.7万人学习

Java 教程
Java 教程

共578课时 | 46.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号