API自动化-碰到的坑
今天写了个API自动化的代码,然后碰到了一堆坑,只怪自己没有理解清楚,所以搞了大半天才完全解决。。不过代码量是不是略大啊 o_O
很早就实现了单个接口的自动化测试,但是我们不可能每个接口都写一遍代码,所以必须整合在一起,解放劳动力
首先,我们的目标是“没有蛀牙”。噗,被广告荼毒了。回归正题,我们想实现一套流程:从excel读取各个数据(包括请求方法-get/post,路径,参数,校验的参数,校验的值);然后自动测试该条记录;然后生成报告
声明ApiCell类(把需要用到的各个参数声明出来)
public classApiCell {
privateStringmethod;
privateStringpath;
privateStringpara;
privateStringass;
privateStringassVal;
publicStringgetMethod() {
returnmethod;
}
public voidsetMethod(String method) {
this.method= method;
}
publicStringgetPath() {
returnpath;
}
public voidsetPath(String path) {
this.path= path;
}
publicStringgetPara() {
returnpara;
}
public voidsetPara(String para) {
this.para= para;
}
publicStringgetAss() {
returnass;
}
public voidsetAss(String ass) {
this.ass= ass;
}
publicStringgetAssVal() {
returnassVal;
}
public voidsetAssVal(String assVal) {
this.assVal= assVal;
}
}
通过poi读取xls格式的excel文件
/**
*读取给定路径的excel文件
*@paramfilePath
*@return
*/
public staticListreadExcel(String filePath) {
//创建workbook
File file =newFile(filePath);
try{
workbook=newHSSFWorkbook(newFileInputStream(file));
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
List> result=newArrayList>();
//声明Api格式。ApiCell是声明的一个类,用来存放excel中需要用到的各个参数
List list=newArrayList();
//遍历excel表格中各个Sheet
for(intnumSheet=0;numSheet
HSSFSheet hssfSheet=workbook.getSheetAt(numSheet);
if(hssfSheet==null){
continue;
}
ApiCell apiCell=null;
//遍历每个Sheet下的各个数据
for(introwNum=1;rowNum<=hssfSheet.getLastRowNum();rowNum++){
//获取每一行数据
HSSFRow hssfRow=hssfSheet.getRow(rowNum);
//如果该行不为空,获取该行下的各个单元格
if(hssfRow !=null) {
apiCell=newApiCell();
//根据excel表格中每列对应的数据保存到相应的变量中
HSSFCell method=hssfRow.getCell(0);
HSSFCell path=hssfRow.getCell(1);
HSSFCell para=hssfRow.getCell(2);
HSSFCell ass=hssfRow.getCell(3);
HSSFCell assVal=hssfRow.getCell(4);
// System.out.println("ExcelUtil:"+method+":"+path+":"+para+":"+ass+":"+assVal);
apiCell.setMethod(getValue(method));
apiCell.setPath(getValue(path));
apiCell.setPara(getValue(para));
apiCell.setAss(getValue(ass));
apiCell.setAssVal(getValue(assVal));
list.add(apiCell);
}
}
}
returnlist;
}
读取Excel表格中各个单元格数据
/**
*根据类型读取excel中数据
*@paramhssfCell
*@return
*/
@SuppressWarnings("static-access")
private staticStringgetValue(HSSFCell hssfCell) {
//必须判断excel中的数据是否为空数据,不然会报空指针
if(hssfCell!=null&&(hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN)) {
returnString.valueOf(hssfCell.getBooleanCellValue());
}else if(hssfCell!=null&&(hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC)) {
returnString.valueOf((int)hssfCell.getNumericCellValue());//poi读取数值时默认为double型,必须强制转换为int型
}else if(hssfCell!=null&&(hssfCell.getCellType()==hssfCell.CELL_TYPE_STRING)){
returnString.valueOf(hssfCell.getStringCellValue());
}else{
returnEMPTY;
}
}
从excel读取数据,参数为String类型,但是我们接口写的是Map类型,要转换一下
/**
*把String类型转为map类型
*/
public classString2Map {
public staticMapstringMap(String para){
Map parameter=newHashMap();
JSONObject jsonObject= JSONObject.fromObject(para);
parameter=(Map)jsonObject;
returnparameter;
}
}
好了,可以写测试代码了。。看到这么长的代码,也是怕怕的o_O
public classTestReadExcel {
@Test
public voiddataFromExcelApi() {
String pathFile="C:\\Users\\Administrator\\Desktop\\api.xls";
List re=ExcelUtil.readExcel(pathFile);
if(re !=null){
for(ApiCell cell : re){
String method = cell.getMethod();
String path = cell.getPath();
String para = cell.getPara();
String ass = cell.getAss();
String assVal = cell.getAssVal();
// System.out.println("00000000"+method+":"+path+":"+para+":"+ass+":"+assVal);
if(method.equalsIgnoreCase("get") && para ==""){
Response response = ApiUntils.get(path);
String actual = JsonUtils.json(response,ass);
Assert.assertEquals(actual,assVal);
}else if(method.equalsIgnoreCase("get") && para !=""){
Document doc = JsoupApiUtils.getByParameter(path,String2Map.stringMap(para));
Elements elements = doc.select(ass);
String actual = elements.get(0).text();
Assert.assertEquals(actual,assVal);
}else if(method.equalsIgnoreCase("post") && para !=null){
String contentType ="application/x-www-form-urlencoded";
Response response = ApiUntils.postByParameter(path,contentType,String2Map.stringMap(para));
String json = response.asString();
String json01 = json.substring(15,json.length() -15);
JsonPath jp =newJsonPath(json01);
String actual = jp.get(ass).toString();
Assert.assertEquals(actual,assVal);
}
}
}
}
}
还需要自己写不同类型的接口实现方式。我同时用了rest-assured和jsoup两种(有的接口返回的是html代码,所以用到jsoup)。这里不贴代码啦。
好了。。跑吧。。试跑了三个接口,耗时5.7s,速度有提升,再加点数据进去试试。
给自己做个笔记
1.读excel单元格数据的时候,必须判断单元格是否为空,为空会报空指针的错误。自己没有理解这个问题,有条记录是有个单元格为空的,没有加判断,一运行就报空指针,但是自己不明白为啥会报空指针,后面搞清楚了,加了判断就通过了
2.poi读取数值会返回为double类型,必须强制转换为int型。不然通过这个点进行校验就通不过了
3.maven引用jar包时,如果在pom文件中不报错,但是在Dependencies中报错的话,应该是文件下载不完全导致的。我是在导入json-lib包的时候出现问题。解决办法:本地C:\Users\Administrator\.m2\repository\net\sf\json-lib\json-lib中相应版本中,查看jar包是否下载了,如果没有的话,在pom文件中加入<classifier>jdk15</classifier>即可,原因是 json-lib是需要区分jdk版本的。
pom Dependencies报告,用的是testng的格式。运行结束后把报告导出,打开是这个样子的。。蛮好看的有木有啊^_^
testng报告大概就是这样子了