基于testNg的测试框架设计(一)数据驱动

所谓的数据驱动是指测试的逻辑时一样的,发生改变的仅仅是数据,期望不同的测试数据输出不同或者相同的测试结果。

测试数据和测试脚本的分离,有利于分别维护测试数据和脚本,使得逻辑更加清晰,更容易交接和维护。

testNg本身提供了@DataProvider的注解去加载测试数据,还有通过testng.xml配置参数的方式进行。我在此基础上做改动,达到更号的效果。


实现目标:

1、测试脚本和测试数据分离,达到不脚本和数据分开维护。

2、测试脚本需要的测试数据,通过@DataProvider加载进来。

3、测试数据使用csv文件来维护,包括测试编号,测试描述,测试输入数据,测试期望数据


测试框架的大概结构如下:

基于testNg的测试框架设计(一)数据驱动_第1张图片



从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 csvList = new ArrayList();
		// 将读取的数据,按行存入到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/


你可能感兴趣的:(工作经验杂谈)