TestNG数据驱动

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

@DataProvider注解简介:

@DataProvider标记专门为测试方法提供参数的方法。这类方法必须返回Object[ ][ ]类型的二维数组或者Iterator<Object>[],每一行的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<Object[]> {

private BufferedReader br        = null;

//行数

private int            rowNum    = 0;

//获取次数

private int            curRowNo  = 0;

//列数

private int            columnNum = 0;

//key名

private String[]       columnName;

//csv中所有行数据

private List<String>   csvList;

//实际想要的行数据

private List<String>   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<String>();

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<String>();

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<String, String> s = new TreeMap<String, String>();

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<Object[]>迭代器,TestNG调用此类实现的hasNext()、next()方法得到一行数据,在next()方法中可以看到,我把数据是放在Map<String, String>中的,再把map放在Object[]里,所以测试方法的参数就必须是一个Map<String, String>。我这里改成了只读取一行,因为一个csv文件的一个caseId只应该有一行。

数据驱动类:

import java.lang.reflect.Method;

import java.util.Iterator;

import org.testng.annotations.DataProvider;

public class DataProviderTest {

/**

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

*

@param method

@return

*/

@DataProvider

public Iterator<Object[]> dataSource(Method method) {

return (Iterator<Object[]>) new CSVData(method.getDeclaringClass().getSimpleName(), method.getName());

}

}

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

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

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

return (Iterator<Object[]>) new CSVData(…)就是将CSV读取类读取的结果返回,返回的类型是Iterator<Object[]>的,符合@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<String, String> data) {

System.out.println(data);

}

@Test(dataProvider = "dataSource")

public void id1(Map<String, String> data) {

System.out.println(data);

}

}

DataTest.csv文件如下:

输出结果如下:

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>[],最后测试方法获得的参数都是Object[ ]里放的东西,第一个例子里放了两列String,第二个例子里放了Map<String, String>,所以第一个测试类的测试方法的参数是两个String,第二个测试类的测试方法的参数是Map<String, String>,必须保持一致才行。

TestNG数据驱动相关推荐

  1. testng数据驱动_TestNG数据提供者

    testng数据驱动 DataProvider is one of the best features of TestNG framework. We can use TestNG DataProvi ...

  2. java移动端接口测试_走进Java接口测试之测试框架TestNG数据驱动(入门篇)

    前言 我们在前面的文章中,和大家分享过接口自动化测试一些基本的实现方法,但是,你很快就会发现,如果在测试脚本中硬编码测试数据的话,测试脚本灵活性会非常低.而且,对于那些具有重复的请求,而只是测试入参不 ...

  3. 接口自动化集成TestNG框架

    目录 1. 接口概念 2. HTTP接口 3. TestNG介绍 4. TestNG注解 4.1 dependsOnMethods标签 4.2 alwaysRun标签 4.2.1 alwaysRun ...

  4. 基于Spring开发的DUBBO服务接口测试

    基于Spring开发的DUBBO服务接口测试 知识共享主要内容: 1. Dubbo相关概念和架构,以及dubbo服务程序开发步骤. 2. 基于Spring开发框架的dubbo服务接口测试相关配置. 3 ...

  5. python测试框架untest怎么循环执行_unittest如何在循环遍历一条用例时生成多个测试结果...

    引用自:http://blog.csdn.net/kaku21/article/details/42124593 参考网址:http://programmaticallyspeaking.com/te ...

  6. 自动化测试实施流程与规范

    一 目的:基于Selenium 自动化回归测试解决方案. Selenium简介:ThroughtWorks 公司一个强大的开源 Web 功能测试工具系列,包括Selenium-IDE.Selenium ...

  7. 技术文章系列整理(持续更新)

    本博客有很多关于技术的文章,我试着对你可能感兴趣的一些重要文章进行分类. 文章目录 一.基础 二.性能 三.Java接口测试 四.移动端测试 五.DevOps 六.运维 七.团队管理 八.大数据 九. ...

  8. selenium Grid2环境搭建和基本使用

    Selenium Grid简介 利用Selenium Grid可以使主节点(hub)的测试用例在不同主机即分支点(node)运行.可以使一份测试用例在不同环境下(操作系统.浏览器)执行自动化测试.Se ...

  9. 数据驱动测试之——CSV+TestNG

    对于利用Webdriver做自动化的童鞋,对于如何将元素或者输入数据如何和编码分离都应该不会太陌生,本着一边学习一边分享的心态,大概总结了一下关于利用CSV.XML以及Excel来存放数据,然后在结合 ...

最新文章

  1. 票房破五十亿!用Python分析李焕英为啥能逆袭《唐探3》
  2. 自定义分辨率软件_苹果剪辑软件Final Cut Pro X导出竖屏视频教程
  3. 中国首个火星探测器天问一号发射成功!
  4. mysql update用not in太慢了_MySQL 加锁和死锁解析
  5. BugkuCTF-Misc:Linux
  6. Java web对试卷进行单选多选答题进行打分_2020年大学慕课Java程序设计作业答案...
  7. java中Class对象详解
  8. centos 6.9 +nginx 配置GIT HTTPS服务器(证书采用自签名)
  9. C#中Dictionary的用法及用途(转)
  10. python爬取晋江小说排行榜_【含代码】Python爬虫实战:爬取全站小说排行榜
  11. 离散概率分布的介绍及Python运用
  12. 大学生数学竞赛资料目录20190403更新
  13. 零基础学DevOps必看教程,带你10分钟快速实战入门DevOps
  14. 如何让地面不起灰_水泥地面起灰怎么办?老师傅6招搞定了
  15. 新开业和新签约酒店 | 上海世茂皇家艾美酒店开业;福州滨海新城那迪广场、Casa Cook桂山岛度假酒店等顺利签约...
  16. Python中的类、实例以及方法,MRO继承解析顺序以及Mixin类
  17. Visual C++黑白棋游戏项目开发一:需求分析、系统架构设计(附源码和资源 可用于大作业)
  18. 没想到华为P20的投屏功能,还可以这么强大!
  19. 2018年浙江省网络安全技能竞赛ctf部分解题思路writeup
  20. 网络基础知识——交换机路由器

热门文章

  1. 设置Word文档密码的两种方式
  2. windows下载Android系统源码
  3. Android点选下拉列表框选项,获取选项内容
  4. CTF网络安全大赛学习笔记1010
  5. SVN客户端TortoiseSVN基本使用方法步骤-初人指南
  6. 计算机休眠状态播放音乐,怎么设置win10中关村系统进入睡眠状态后音乐继续播放...
  7. OCP问题debug
  8. 【视频编码压制】关于近两年的视频压制学习总结种种
  9. Gitlab 设置页面语言为简体中文
  10. 【数据结构】理解二叉树的三种遍历--前序、中序、后序 +层序(简明易懂)