1.Java web接口自動化框架
框架名稱:Java+Maven+httpClients+TestNg+Allure
(因本次只講解java部分,未包括git和jenkins,如果是包括git和jenkins可參考Java自動化框架總篇)
框架圖:

框架思路:

2.分析接口
CASB接口參考:
https://10.1.1.104/uim/doc.html
https://10.1.1.104/sem/doc.html
https://10.1.1.104/kms/doc.html
2.1.Post方法(例如查詢角色)
這里需要多收集和了解一些接口,可以通過Chrome工具或MeterSphere去調(diào)用。
獲取到多個接口進(jìn)行對比,例如把所有的用戶權(quán)限的接口執(zhí)行一遍,拿到入?yún)⒑突貐⑦M(jìn)行分析。
以下舉例:
查詢角色和登錄,都是POST接口。
1.登錄接口地址:/uim/v1/login請求方式:POST請求示例:? ? {"username":"","password":"","ukeySn":"","serverRandom":"","ukeySign":""}返回結(jié)果:{"code":0,"data": {"accessToken":"","expiresDate":"","expiresIn":0,"refreshExpiresDate":"","refreshExpiresIn":0,"refreshToken":"","scope":"","tokenType":""},"msg":"成功"}2.查詢角色:接口地址:/uim/v1/role/list請求方式:POST請求示例:{"page":1,"limit":10,"sidx":"","order":""}響應(yīng)示例:{"code":0,"data": {"currPage":0,"list": [? ? ? ? ? ? {"createTime":"","permissionIdList": [],"permissionList": [? ? ? ? ? ? ? ? ? ? {"childPermissionList": [? ? ? ? ? ? ? ? ? ? ? ? ? ? {"childPermissionList": [? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {}? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ],"createTime":"","parentId":"","parentPermission": {},"permissionId":"","resourceDescribe":"","resourceIcon":"","resourceName":"","resourceOrder":0,"resourceRouter":"","resourceType":0,"resourceUrls":""}? ? ? ? ? ? ? ? ? ? ? ? ],"createTime":"","parentId":"","parentPermission": {},"permissionId":"","resourceDescribe":"","resourceIcon":"","resourceName":"","resourceOrder":0,"resourceRouter":"","resourceType":0,"resourceUrls":""}? ? ? ? ? ? ? ? ],"roleDescribe":"","roleId":"","roleName":""}? ? ? ? ],"pageSize":0,"totalCount":0,"totalPage":0},"msg":"成功"}
2.2.Get方法(例如刪除角色)
請求地址:/uim/v1/role/delete
請求方式:GET
請求參數(shù):id= ? ? ?
響應(yīng)示例:
{
"code": 0,
"data": {},
"msg": "成功"
}
接口都有請求頭信息,輸入?yún)?shù),接口請求,輸出參數(shù)
1、輸入?yún)?shù):POST接口,這里全部都是JSON格式
GET接口,都是參數(shù)入?yún)?/p>
2、發(fā)送和處理請求
3、輸出參數(shù):所有CASB的接口,都是JSON格式
3.選擇工具/語言
這里用到的工具類:可參考0.CASB2.0接口自動化培訓(xùn)計劃.md文檔中的《框架工具類用到的Java基礎(chǔ)知識》。
3.1.語言選擇
這里選擇Java語言是因為加解密的緣故,過插件需要通過java語言+插件jar包對數(shù)據(jù)庫插入數(shù)據(jù)加密和查詢數(shù)據(jù)解密。
單純的web接口自動化,其實用python或meterSphere學(xué)習(xí)成本更低些。
Python語言支持testng和allure報告也更友好一些。
3.2.針對接口的工具選取
3.2.1. 發(fā)送請求(HttpClient)
該框架使用的是CloseableHttpClient。
工具類:HttpsClientUtils
這里是我寫的HttpClient工具類,舉例的Get和Post方法
/**
* 發(fā)送HttpGet請求,不帶請求頭和請求參數(shù)
* @param url 請求地址
* @return doGet(url,null,null)
*/
public ?HttpClientResult doGet(String url) throws Exception {
}
/**
* 發(fā)送HttpGet請求,帶請求頭和請求參數(shù)
* @param url 請求地址
* @param headers ,params
*/
public ?HttpClientResult doGet(String url,Map<String, String> headers,Map<String,String> params) throws Exception{}
/**
* 發(fā)送POST請求,不帶請求參數(shù)
* @param url 請求地址
* @return doPost(url,headers,null)
*/
public ?HttpClientResult doPost(String url,Map<String, String> headers) throws Exception {
}
/**
* 發(fā)送POST請求,帶請求參數(shù)
* @param url 請求地址
* @param headers 請求頭
* @param jsonStr 請求json
*/
public ?HttpClientResult doPost(String url, Map<String, String> headers,String jsonStr) throws Exception {}
3.2.2.接口的入?yún)?/p>
3.2.2.1.如果入?yún)⒅苯訉懺诖a里,那么就不需2
3.2.2.2.通過Excel獲取接口的入?yún)⒉鲄?/p>
那么這里就需要學(xué)習(xí)讀取Excel的工具,本次框架里介紹的是:阿里的easyexcel
工具類:ExcelUtil
寫入Excel的方法:
/**
* 寫excel
* @param fileName 寫入excel的文件名稱
* @param sheetName
* @param dataList 數(shù)據(jù)
*/
public static void writeExcel(String fileName, String sheetName, List<ApiDataBean> dataList) {}
讀取excel的方法:
/**
* 讀取excel,放入caseDataBean
* @param fileName 讀取excel的文件名稱
* @return datalist
*/
public static List<ApiDataBean> readExcel(String fileName, String sheetName){}
3.2.2.3.入?yún)⑹褂米兞啃枰矃?shù)替換變量
工具類:ParamUtil
調(diào)用:String reqUrl = host + url;
Map<String, String> headers=getHeader(token);
String reqData=paramUtil.getCommonParam(data.getParam());
//發(fā)送請求
HttpsClientUtils httpUtil = new HttpsClientUtils();
HttpClientResult httpResult = httpUtil.doPost(reqUrl, headers,reqData);
/**
* 取公共參數(shù) 并替換參數(shù),處理${}
* @param param @description 參數(shù)
* @return param
*/
public String getCommonParam(String param) {}
3.2.3.接口的出參解析
3.2.3.1.接口簡單回參解析,可以直接用Java的JsonPath
參考:?GitHub - json-path/JsonPath: Java JsonPath implementation
3,2.3.2.接口復(fù)雜的回參解析
需要自己編寫(Json解析有4種方法,我這里選取使用的Gson)
調(diào)用例如:StringroleId = JsonUtil.getTargetValue(resultContent, roleName,"roleName","roleId");/**
? ? * 解析一層json樹結(jié)構(gòu),只有JsonObject,獲取第1層json中某個key的值
? ? * @param jsonString json字符串
? ? * @param dataKey key
? ? */publicstaticStringgsonParserString(StringjsonString,StringdataKey){}/**
? ? * 解析二層json樹結(jié)構(gòu),只有JsonObject,獲取第2層json中某個key的值
? ? * @param jsonString? json字符串
? ? * @param dataKey key
? ? */publicstaticStringgsonParserString_2(StringjsonString,StringdataKey){}/**
? ? * 解析三層樹結(jié)構(gòu)并帶有1個JsonArray(list),獲取第3層json中列表中第1個json指定key的值
? ? * @param jsonString json字符串
? ? * @param dataKey (獲取data中l(wèi)ist的里String類型)
? ? */publicstaticStringgsonParserString_3l(StringjsonString,StringdataKey){}/**
? ? * 解析四層樹結(jié)構(gòu)并帶有2個JsonArray,獲取第4層json列表中指定key的所有值
? ? * @param jsonString json字符串
? ? * @param dataKey (獲取data中l(wèi)ist的里String類型)
? ? *///for (JsonElement element : jsonArray) 遍歷數(shù)據(jù)publicstaticList gsonParserString_4l(StringjsonString,Stringlist1,Stringlist2,StringdataKey){}/**
? ? * 解析三層樹結(jié)構(gòu)并帶有1個JsonArray(list),第3層json中找到符合key1值的同json中的key2的值
? ? * @param jsonString json字符串
? ? * @param targetKey (獲取data中l(wèi)ist的里String類型)
? ? */publicstaticStringgetTargetValue(StringjsonString,StringsourceName,StringsourceKey,StringtargetKey){}
其他的3種Json處理可參考:?JAVA中的四種JSON解析方式詳解 - 道理我都懂Zz - 博客園
3.3.單一接口調(diào)工具類
3.3.1.POST接口
例如:login
StringloginUrl ="https://10.1.1.104/uim/v1/login";StringjsonStr ="{\"username\":\"YWRtaW4=\",\"password\":\"bGlhblNoaTIwMjA=\"}";//請求頭Map headers=newHashMap<>();? ? headers.put("Content-Type","application/json;charset=UTF-8");//發(fā)送請求HttpsClientUtils httpUtils =newHttpsClientUtils();? ? HttpClientResult result=httpUtils.doPost(loginUrl,headers, jsonStr);
全部代碼:
package com.ciphergateway.server;importcom.ciphergateway.bean.HttpClientResult;importcom.ciphergateway.utils.Base64Util;importcom.ciphergateway.utils.HttpsClientUtils;importcom.ciphergateway.utils.JsonUtil;importcom.ciphergateway.utils.PropertiesUtil;importorg.apache.logging.log4j.LogManager;importorg.apache.logging.log4j.Logger;//import java.util.Base64;importjava.util.HashMap;importjava.util.Map;importjava.util.Properties;publicclassLogin{? ? privatestaticfinalLogger log= LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);/**? ? * 獲取login的token? ? */publicStringgetToken() throws Exception{//獲取配置文件Stringfilename="config.properties";? ? ? ? PropertiesUtil pro=newPropertiesUtil(filename);Stringhost=pro.readProperty("HOST");Stringusername=pro.readProperty("USER_NAME");Stringpassword=pro.readProperty("USER_SECRET");? ? ? ? Base64Util base64=newBase64Util();Stringuser_base64 = base64.getBase64(username);Stringpassword_base64 = base64.getBase64(password);//測試HTTPSHttpsClientUtils httpUtils =newHttpsClientUtils();StringloginUrl = host+"/uim/v1/login";StringjsonStr ="{\"username\":\""+ user_base64 +"\",\"password\":\""+ password_base64 +"\"}";//System.out.println(jsonStr);//請求頭Map headers=newHashMap<>();? ? ? ? headers.put("Content-Type","application/json;charset=UTF-8");? ? ? ? HttpClientResult httpResult=null;try{? ? ? ? ? ? httpResult = httpUtils.doPost(loginUrl, headers,jsonStr);? ? ? ? }catch(Exception e) {? ? ? ? ? ? e.printStackTrace();? ? ? ? ? ? log.error(e);? ? ? ? }//System.out.println(httpResult.getCode());//System.out.println(httpResult.getContent());intcode=httpResult.getCode();StringresultContent=httpResult.getContent();? ? ? ? log.info(code+" "+resultContent);Stringtoken =JsonUtil.gsonParserString_2(resultContent,"accessToken");returntoken;? ? }/*? ? public static void main(String[] args) throws Exception {
? ? ? ? Login lo=new Login();
? ? ? ? String token=lo.getToken();
? ? ? ? System.out.println(token);
? ? }*/}
3.3.2.GET方法(刪除角色)
StringreqUrl ="https://10.1.1.104/uim/v1/role/delete";Map map_delete =newHashMap<>();? ? map_delete.put("id","1234567890212222");Map headers=newHashMap<>();? ? headers.put("Content-Type","application/json;charset=UTF-8");? ? headers.put("Authorization",token);//發(fā)送請求HttpsClientUtils httpUtils =newHttpsClientUtils();? ? HttpClientResult httpResult = httpUtils.doGet(reqUrl, headers, map_delete);
3.4.斷言(TestNg單元測試框架)
需要使用TestNg單元測試框架進(jìn)行批量測試,斷言和初始化數(shù)據(jù)和清理數(shù)據(jù)。3.
批量測試:testng.xml初始化數(shù)據(jù):@BeforeTest測試:@Test清理數(shù)據(jù):@AfterTest斷言:Assert例如:1、TestNg默認(rèn)的斷言:Assert.assertEquals(code, expectData,data.getDesc());2、為了異常場景新增的斷言:Assertion.verifyEquals(code, expectData,data.getDesc());
3.5。結(jié)果和報告展示
3.5.1Excel測試結(jié)果
備注:dataList_w是List參數(shù)//調(diào)用excel方法寫入數(shù)據(jù)StringexcelFile_result="src/data/testcase/apiData_result.xlsx";? ? ? ? privateStringsheet1="用戶權(quán)限接口用例";? ? ? ? ExcelUtil.writeExcel(excelFile_result,sheet1,dataList_w);
3.5.2.Allure報告
參考《 Web接口自動化Allure報告的配置和使用》
https://blog.csdn.net/fen_fen/article/details/122020651
4.總結(jié)
4.1.web接口框架使用的工具/框架
序號工具或框架名版本
1Mavenapache-maven-3.8.1
2httpClienthttpClient 4.5.3
3TestNGTestng 6.11
4Allure測試報告Allure 2.13.2
5Git煉石 git
4.2.框架的優(yōu)點
1、采用數(shù)據(jù)驅(qū)動方式來解決大量功能重復(fù)性接口的測試
2、代碼分層
3、針對返回JSON字符串,采用JSONPath和Gson結(jié)合的模式來精準(zhǔn)判定JSON的內(nèi)容。
4、可以生成比較直觀的報告。
5、后期可以跟Jenkins持續(xù)集成,執(zhí)行結(jié)果生成測試報告并發(fā)送郵件告知相關(guān)人員