基于testNg的测试框架设计(一)数据驱动
2014-08-21 16:08
691 查看
所谓的数据驱动是指测试的逻辑时一样的,发生改变的仅仅是数据,期望不同的测试数据输出不同或者相同的测试结果。
测试数据和测试脚本的分离,有利于分别维护测试数据和脚本,使得逻辑更加清晰,更容易交接和维护。
testNg本身提供了@DataProvider的注解去加载测试数据,还有通过testng.xml配置参数的方式进行。我在此基础上做改动,达到更号的效果。
实现目标:
1、测试脚本和测试数据分离,达到不脚本和数据分开维护。
2、测试脚本需要的测试数据,通过@DataProvider加载进来。
3、测试数据使用csv文件来维护,包括测试编号,测试描述,测试输入数据,测试期望数据
测试框架的大概结构如下:
从csv文件中读取数据并返回的代码实现过程:
/**
*
* @author kaifeng.shi
* @version $Id: DataProviderFromCsv.java, v 0.1 2014年8月24日 下午10:52:14 Exp $
* @return Object[][] 返回一个二维数组,第一维代表行号,第二维代表每行数据
*/
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import au.com.bytecode.opencsv.CSVReader;
public class DataProviderFromCsv {
// 定义csv文件的分割符
public static char csvSeprator = ',';
// 定义@DataProvider的name
public static final String dataProviderName = "dataProviderName";
@DataProvider(name = dataProviderName)
public static Object[][] getCsvData(Method method, ITestContext context)
throws IOException {
// 获取当前文件编译后的绝对路径
DataProviderFromCsv dataProviderFromCsv = new DataProviderFromCsv();
String retPath = dataProviderFromCsv.getPath();
// 获取调用方法的方法名
String methodName = method.getName();
// 获取调用方法的类名
String className = null;
String[] packageName = method.getDeclaringClass().getName().toString()
.split("\\.");
className = packageName[packageName.length - 1];
// 指定当前类当前方法对应的csv文件
String csvPath = retPath + className + "." + methodName + ".csv";
// 从CSV文件中读取数据
CSVReader reader = new CSVReader(new FileReader(csvPath), csvSeprator);
// 不读第一行,第一行统一为参数的字段名字
reader.readNext();
// csv中每行的数据都是一个string数组
String[] csvRow = null;
ArrayList<Object[]> csvList = new ArrayList<Object[]>();
// 将读取的数据,按行存入到csvList中
while ((csvRow = reader.readNext()) != null) {
csvList.add(csvRow);
}
// 定义返回值
Object[][] results = new Object[csvList.size()][];
// 设置二维数组每行的值,每行是个object对象
for (int i = 0; i < csvList.size(); i++) {
results[i] = csvList.get(i);
}
return results;
}
public String getPath() {
String absolutePath = null;
try {
absolutePath = this.getClass().getResource("").getPath();
} catch (Exception e) {
e.printStackTrace();
}
return absolutePath;
}
}
以上代码做了几件事情:
1)获取测试数据(csv文件)的路径,约定csv文件的命名方式为 ----类名+方法名+csv后缀。@Dateprovider 的入参中有个Method method参数,可以获取调用方法的方法名。
2)获取数据文件的路径和文件名称后,通过opencsv提供的方法,读取文件的内容。需要添加opencsv的jar文件。
2.1)csv文件的第一行一般用于填写列名,不作为测试数据,所以不返回第一行的内容。
2.2)csv文件每行是一个object,这个object包含每列的列值,所以每行时个string[]数组。一行数据是一个object对象,里面为每行的内容,而每行的内容都按列对应的值存入。
3)@Dataprovider要求返回一个Object[][]的二维数组,第一维表示的是行号(第几行),第二维表示的每行里面的内容值。所以将csv中每行的内容放入第二维中返回。
通过上述代码就简单的在testng的@dataprovider基础上进行了优化,实现了数据驱动,测试脚本和数据分离的功能。
testng本身实现的相关资料可参考:
http://www.shenyanchao.cn/blog/2013/06/05/deep-in-testng/
测试数据和测试脚本的分离,有利于分别维护测试数据和脚本,使得逻辑更加清晰,更容易交接和维护。
testNg本身提供了@DataProvider的注解去加载测试数据,还有通过testng.xml配置参数的方式进行。我在此基础上做改动,达到更号的效果。
实现目标:
1、测试脚本和测试数据分离,达到不脚本和数据分开维护。
2、测试脚本需要的测试数据,通过@DataProvider加载进来。
3、测试数据使用csv文件来维护,包括测试编号,测试描述,测试输入数据,测试期望数据
测试框架的大概结构如下:
从csv文件中读取数据并返回的代码实现过程:
/**
*
* @author kaifeng.shi
* @version $Id: DataProviderFromCsv.java, v 0.1 2014年8月24日 下午10:52:14 Exp $
* @return Object[][] 返回一个二维数组,第一维代表行号,第二维代表每行数据
*/
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import au.com.bytecode.opencsv.CSVReader;
public class DataProviderFromCsv {
// 定义csv文件的分割符
public static char csvSeprator = ',';
// 定义@DataProvider的name
public static final String dataProviderName = "dataProviderName";
@DataProvider(name = dataProviderName)
public static Object[][] getCsvData(Method method, ITestContext context)
throws IOException {
// 获取当前文件编译后的绝对路径
DataProviderFromCsv dataProviderFromCsv = new DataProviderFromCsv();
String retPath = dataProviderFromCsv.getPath();
// 获取调用方法的方法名
String methodName = method.getName();
// 获取调用方法的类名
String className = null;
String[] packageName = method.getDeclaringClass().getName().toString()
.split("\\.");
className = packageName[packageName.length - 1];
// 指定当前类当前方法对应的csv文件
String csvPath = retPath + className + "." + methodName + ".csv";
// 从CSV文件中读取数据
CSVReader reader = new CSVReader(new FileReader(csvPath), csvSeprator);
// 不读第一行,第一行统一为参数的字段名字
reader.readNext();
// csv中每行的数据都是一个string数组
String[] csvRow = null;
ArrayList<Object[]> csvList = new ArrayList<Object[]>();
// 将读取的数据,按行存入到csvList中
while ((csvRow = reader.readNext()) != null) {
csvList.add(csvRow);
}
// 定义返回值
Object[][] results = new Object[csvList.size()][];
// 设置二维数组每行的值,每行是个object对象
for (int i = 0; i < csvList.size(); i++) {
results[i] = csvList.get(i);
}
return results;
}
public String getPath() {
String absolutePath = null;
try {
absolutePath = this.getClass().getResource("").getPath();
} catch (Exception e) {
e.printStackTrace();
}
return absolutePath;
}
}
以上代码做了几件事情:
1)获取测试数据(csv文件)的路径,约定csv文件的命名方式为 ----类名+方法名+csv后缀。@Dateprovider 的入参中有个Method method参数,可以获取调用方法的方法名。
2)获取数据文件的路径和文件名称后,通过opencsv提供的方法,读取文件的内容。需要添加opencsv的jar文件。
2.1)csv文件的第一行一般用于填写列名,不作为测试数据,所以不返回第一行的内容。
2.2)csv文件每行是一个object,这个object包含每列的列值,所以每行时个string[]数组。一行数据是一个object对象,里面为每行的内容,而每行的内容都按列对应的值存入。
3)@Dataprovider要求返回一个Object[][]的二维数组,第一维表示的是行号(第几行),第二维表示的每行里面的内容值。所以将csv中每行的内容放入第二维中返回。
通过上述代码就简单的在testng的@dataprovider基础上进行了优化,实现了数据驱动,测试脚本和数据分离的功能。
testng本身实现的相关资料可参考:
http://www.shenyanchao.cn/blog/2013/06/05/deep-in-testng/
相关文章推荐
- 基于数据驱动的接口测试框架设计
- 基于testNG框架的分层式数据驱动自动化测试设计与研发(一)
- 基于testNg的测试框架设计(二)---使用ant运行testNg
- 基于python3在nose测试框架的基础上添加测试数据驱动工具
- 基于任务驱动的第三方测试服务平台设计与实现
- 一个通用的单元测试框架的思考和设计06-实现篇-自动管理测试数据-如何临时关闭数据外键约束
- 一个通用的单元测试框架的思考和设计07-实现篇-自动管理测试数据-如何为自增长主键id赋值
- 一个通用的单元测试框架的思考和设计04-实现篇-自动管理测试数据
- 基于TestNG 与Selenium 的自动化测试设计与实施
- 设计自己的基于Selenium 的自动化测试框架-Java版(1) - 为什么selenium还需要测试框架?
- 基于python的REST框架eve测试与mongodb的数据操作 推荐
- 基于数据访问的集合类型-领域驱动设计的又一种特定对象
- 基于前后端交互的自动化测试框架设计
- 基于“事件”驱动的领域驱动设计(DDD)框架分析
- Jasmine-基于JavaScript的行为驱动单元测试框架简介
- 基于Ant+Selenium+TestNG的测试框架配置
- 转载:基于Lua的自动化测试框架设计
- 基于Lua脚本的自动化测试框架设计
- 一个通用的单元测试框架的思考和设计06-实现篇-自动管理测试数据-如何临时关闭数据外键约束
- 以Python为基础的REST(JSON为交换数据)接口的测试框架设计(二)-JSON的修改