数据驱动概念:
- 数据驱动测试是相同的测试脚本使用不同的测试数据执行,测试数据和测试行为
完全分离
数据驱动测试用设计步骤:
- 编写测试脚本,脚本需要支持程序对象、文件或者数据库读入测试数据。
- 将测试脚本使用的测试数据存入程序对象、文件或者数据库等外部介质中
- 运行脚本,循环调用存储在外部介质的测试数据
- 验证所有的测试结果是否符合期望的结果
代码示例:
testNG DataProvider接口测试实践:
测试数据结构:
- 序号:测试报告中使用
- 用例名称:code中对应的测试用例方法名
- 用例描述:测试数据描述(报告中使用)
- 接口地址:请求地址(get,post)
- 请求参数:格式{param=value,…}
- 预期结果:json格式
- 是否执行:Y—执行,N—不执行
整体测试用例Demo:
@Test(dataProvider= ExcelDataProvider.providerName,dataProviderClass= ExcelDataProvider.class,description="登陆测试集")
public void accountInfoTest(CaseInfo c){
//获取接口名称
url = ExcelDataProvider.getRequestUrl(c);
//获取用例需要的参数
requestparam = ExcelDataProvider.getRequestParam(c);
//发起请求请求
String res = APIMthod.sendPostByHttpCient(url, requestparam);
//获取预期结果
String expect = ExcelDataProvider.getExpect(c);
//断言
Assert.assertEquals(expect, actual);
}
数据参数化:
- ExcelDataProvider.class:
public class ExcelDataProvider extends CaseHelper{
public static String caseExcelPath = constant.caseExcelPath;
public static String sheetName;
public static String domain;
public static final String providerName = "excelDataProvider";
@SuppressWarnings("static-access")
public ExcelDataProvider(String dataPath, String sheetName, String domain) {
this.caseExcelPath = dataPath;
this.sheetName = sheetName;
this.domain = domain;
}
@DataProvider(name = providerName)
public static Object[][] dataInfo(Method m) throws IOException {
Object[][] object = null;
List<Map<String, String>> list = ExcelReader.getExcelToList(caseExcelPath, sheetName);
object = CaseHelper.getObjArrByList(list, m);
return object;
}
}
- caseHelper帮助类:
public class CaseHelper {
// 根据文件的map 转换为数组 第一个为 入参 map 第二个为用例说明,第三个参数为执行用例的预置条件
private static Object[] getObjArrByMap(Map<String, String> caseInfoMap) {
Map<String, String> caseNo = new HashMap<String, String>();
Map<String, String> caseName = new HashMap<String, String>();
Map<String, String> caseDesc = new HashMap<String, String>();
Map<String, String> caseUrl = new HashMap<String, String>();
Map<String, String> caseParam = new HashMap<String, String>();
Map<String, String> caseExpect = new HashMap<String, String>();
CaseInfo ci = new CaseInfo();
for (String key : caseInfoMap.keySet()) {
if (key.equals(constant.caseNo)) {
caseNo.put(key, caseInfoMap.get(key));
}
if (key.equals(constant.caseName)) {
caseName.put(key, caseInfoMap.get(key));
}
if (key.equals(constant.caseDesc)) {
caseDesc.put(key, caseInfoMap.get(key));
}
if (key.equals(constant.caseUrl)) {
caseUrl.put(key, caseInfoMap.get(key));
}
if (key.equals(constant.caseParam)) {
caseParam.put(key, caseInfoMap.get(key));
}
if (key.equals(constant.caseExpect)) {
caseExpect.put(key, caseInfoMap.get(key));
}
}
ci.setCaseNo(caseNo);
ci.setCaseName(caseName);
ci.setCaseDesc(caseDesc);
ci.setCaseUrl(caseUrl);
ci.setCaseParam(caseParam);
ci.setCaseExpect(caseExpect);
return new Object[] { ci };
}
// /获取的list转换为 Object[][]
public static Object[][] getObjArrByList(List<Map<String, String>> caseExcelList, Method m) {
List<Map<String, String>> caseExcuteList = getExcuteList(caseExcelList, m);
Object[][] objArray = new Object[caseExcuteList.size()][];
for (int i = 0; i < caseExcuteList.size(); i++) {
objArray[i] = getObjArrByMap(caseExcuteList.get(i));
}
return objArray;
}
// 筛选出需要执行的用例
private static List<Map<String, String>> getExcuteList(List<Map<String, String>> caseExcelList, Method method) {
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
for (Map<String, String> m : caseExcelList) {
String exec = m.get(constant.Isexec).trim().toLowerCase();
if (exec.equals("y") && (m.get(constant.caseName).equals(method.getName()))) {
list.add(m);
}
}
return list;
}
//获取测试用例序号
public static String getCaseNo(CaseInfo caseNo) {
if (caseNo.getCaseNo().isEmpty()) {
throw new NestedBusinessException("测试用例序号不能为空!");
}
return caseNo.getCaseNo().get(constant.caseNo);
}
//获取测试用例名称
public static String getCaseName(CaseInfo caseName) {
if (caseName.getCaseName().isEmpty()) {
throw new NestedBusinessException("测试用例名称不能为空!");
}
return caseName.getCaseName().get(constant.caseName);
}
//获取测试用例描述
public static String getCaseDesc(CaseInfo caseDesc) {
if (caseDesc.getCaseDesc().isEmpty()) {
throw new NestedBusinessException("测试用例描述不能为空!");
}
return caseDesc.getCaseDesc().get(constant.caseDesc);
}
//获取请求地址
public static String getRequestUrl(CaseInfo caseUrl) {
if (caseUrl.getCaseUrl().get(constant.caseUrl).isEmpty()) {
throw new NestedBusinessException("接口地址不能为空!");
}
return caseUrl.getCaseUrl().get(constant.caseUrl);
}
// 获取用例需要的参数
public static Map<String, String> getRequestParam(CaseInfo caseParam) {
Map<String, String> requestparam = new HashMap<String, String>();
for (String t : caseParam.getCaseParam().keySet()) {
String request = caseParam.getCaseParam().get(t);
//约定以{}开始结束,{}为空参数
if (!request.startsWith("{") && !request.endsWith("}")) {
throw new NestedBusinessException("测试用例参数格式有误,请检查参数格式!");
}
String realStr = request.substring(1, request.length() - 1);
if (realStr.isEmpty() || !realStr.contains("=")) {
continue;
}
String[] res = realStr.split(",");
for (String str : res) {
if (str.split("=").length == 1) {
if (str.split("=")[0].isEmpty()) {
continue;
}else {
requestparam.put(str.split("=")[0],"");
}
}else{
requestparam.put(str.split("=")[0], str.split("=")[1]);
}
}
}
return requestparam;
}
//获取预期结果
public static String getExpect(CaseInfo caseParam) {
if (caseParam.getCaseExpect().get(constant.caseExpect).isEmpty()) {
throw new NestedBusinessException("预期結果不能为空!");
}
return caseParam.getCaseExpect().get(constant.caseExpect);
}
}
数据utils:
public class CaseInfo {
//测试用例序号
private Map<String,String> caseNo;
//测试用例名称(与case中方法名一致)
private Map<String,String> caseName;
//测试用例描述
private Map<String,String> caseDesc;
//测试用例url
private Map<String,String> caseUrl;
//测试用例参数
private Map<String,String> caseParam;
//预期结果(断言)
private Map<String,String> caseExpect;
//是否执行
private Map<String,String> caseIsExec;
public Map<String, String> getCaseNo() {
return caseNo;
}
public void setCaseNo(Map<String, String> caseNo) {
this.caseNo = caseNo;
}
public Map<String, String> getCaseName() {
return caseName;
}
public void setCaseName(Map<String, String> caseName) {
this.caseName = caseName;
}
public Map<String, String> getCaseDesc() {
return caseDesc;
}
public void setCaseDesc(Map<String, String> caseDesc) {
this.caseDesc = caseDesc;
}
public Map<String, String> getCaseUrl() {
return caseUrl;
}
public void setCaseUrl(Map<String, String> caseUrl) {
this.caseUrl = caseUrl;
}
public Map<String, String> getCaseParam() {
return caseParam;
}
public void setCaseParam(Map<String, String> caseParam) {
this.caseParam = caseParam;
}
public Map<String, String> getCaseExpect() {
return caseExpect;
}
public void setCaseExpect(Map<String, String> caseExpect) {
this.caseExpect = caseExpect;
}
public Map<String, String> getCaseIsExec() {
return caseIsExec;
}
public void setCaseIsExec(Map<String, String> caseIsExec) {
this.caseIsExec = caseIsExec;
}
public String toString(){
return getCaseDesc().get(constant.caseDesc) + "|" + getCaseUrl() + "," + getCaseParam() ;
}
}