打造全方位接口自动化测试平台:用户角色功能实现
介绍
目前正在着手开发一款功能全面的接口自动化测试平台,该平台将涵盖登录、用户管理、权限控制、项目管理、用例管理、测试数据管理、测试报告生成、任务调度、缺陷跟踪以及系统配置等多个核心模块。为了方便调用被测接口,我们要封装一个公共的接口调用工具
接口调用工具详解
技术选型
-
后端:采用Java作为主要开发语言。
-
前端:使用VUE框架进行界面展示。
-
行为记录:Java服务负责记录用户行为,而VUE则用于展示这些行为记录。
工具设计
调用接口前,需要判断该接口是否需要登录,如果需要登录,先登录后将登录验签添加到接口请求的headers中。为了防止重复的请求登录接口,可以把验签放到redis缓存中,需要的时候从redis中查询,如果过期,再次进行登录保存,代码如下:
@Slf4j
public class ApiTool {
public ResponseEntity<Map<String, Object>> apiTest(ApiDTO apiDTO, ProjectVO projectVo) throws IOException {
String response;
Map<String, Object> headerMap = new HashMap<>();
if (projectVo.getIs_login() == 1) {
if (projectVo.getLogin_type().equals("json")) {
OkHttpClient okHttpClient = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json;charset=utf-8");
RequestBody requestBody = RequestBody.create(mediaType, ByteString.encodeUtf8(projectVo.getLogin_data()));
Request request = new Request.Builder().url(projectVo.getLogin_api()).method("POST",requestBody).addHeader("Content-Type", "application/json").build();
Response respBean = null;
String res = "";
try {
respBean = okHttpClient.newCall(request).execute();
res = StringEscapeUtils.unicodeToStr(respBean.toString());
}catch (Exception e) {
return RespBean.ok("执行成功",e.getMessage());
}
log.info("登录接口返回: {}",res);
if (projectVo.getHeader_type() == 0) {
List<Cookie> cookies = Cookie.parseAll(request.url(),respBean.headers());
for (Cookie cookie : cookies) {
// 获取Cookie信息
if (!cookie.name().contains("rememberMe")) {
headerMap.put(projectVo.getHeader_key(),cookie.name() +"="+cookie.value());
log.info("登录cookie:{}",cookie.name() +"="+cookie.value());
}
}
}else {
String token = findKey(JSON.parseObject(respBean.body().string()),projectVo.getResult_value());
headerMap.put(projectVo.getHeader_key(),"Bearer "+token);
}
}
}
if (null != apiDTO.getData_type()) {
switch (apiDTO.getData_type()) {
case "params":
response = params(apiDTO,headerMap);
break;
case "json":
response = json(apiDTO,headerMap);
break;
case "form-data":
response = formData(apiDTO,headerMap);
break;
case "form-urlencoded":
response = urlencoded(apiDTO,headerMap);
break;
default:
return RespBean.error("不支持的数据类型");
}
}else {
response = params(apiDTO,headerMap);
}
return RespBean.ok("执行成功",response);
}
private String urlencoded(ApiDTO apiDTO,Map<String, Object> headerMap) {
String response;
Request.Builder builder = new Request.Builder().url(apiDTO.getUrl());
OkHttpClient okHttpClient = new OkHttpClient().newBuilder().connectTimeout(60, TimeUnit.SECONDS).build();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
MultipartBody.Builder body = new MultipartBody.Builder().setType(MultipartBody.FORM);
Object headerObj = JSON.parse(apiDTO.getHeaders());
Object dataObj = JSON.parse(apiDTO.getData());
AtomicReference<String> s = new AtomicReference<>("");
if (!apiDTO.getData().isEmpty()) {
Map<String, Object> map = (Map<String, Object>) dataObj;
map.forEach((k,v) -> {
s.set(s + k + "=" + v.toString() + "&");
});
}
if (!apiDTO.getHeaders().isEmpty()) {
Map<String, Object> map = (Map<String, Object>) headerObj;
map.forEach((k,v) -> {
builder.method(apiDTO.getMethod(),body.build()).addHeader(k,v.toString());
});
}
headerMap.forEach((hk,hv) -> {
builder.method(apiDTO.getMethod(),body.build()).addHeader(hk,hv.toString());
});
try {
response = okHttpClient.newCall(builder.addHeader("Content-Type", "application/x-www-form-urlencoded").build()).execute().toString();
}catch (Exception e){
response = e.getMessage();
}
response = StringEscapeUtils.unicodeToStr(response);
log.info("response:{}",response);
return response;
}
private String formData(ApiDTO apiDTO,Map<String, Object> headerMap) {
String response;
Request.Builder builder = new Request.Builder().url(apiDTO.getUrl());
OkHttpClient okHttpClient = new OkHttpClient().newBuilder().connectTimeout(600, TimeUnit.SECONDS).readTimeout(600, TimeUnit.SECONDS).writeTimeout(600, TimeUnit.SECONDS).build();
MultipartBody.Builder body = new MultipartBody.Builder().setType(MultipartBody.FORM);
@SuppressWarnings("unchecked")
Map<String, Object> headerObj = (Map<String, Object>) JSON.parse(apiDTO.getHeaders());
Map<String, Object> dataObj = (Map<String, Object>) JSON.parse(apiDTO.getData());
Map<String, Object> fileObj = (Map<String, Object>) JSON.parse(apiDTO.getFile());
if (!fileObj.isEmpty()) {
fileObj.forEach((k,v) -> {
String fileName = v.toString().substring(v.toString().lastIndexOf("/") + 1);
body.addFormDataPart(k,fileName, RequestBody.create(MediaType.parse("application/octet-stream"), new File(v.toString())));
});
}
if (!dataObj.isEmpty()) {
dataObj.forEach((k,v) -> {
body.addFormDataPart(k,v.toString());
});
}
if (!headerMap.isEmpty()) {
headerMap.forEach((k,v) -> {
builder.addHeader(k,v.toString());
});
}
headerMap.forEach((hk,hv) -> {
builder.addHeader(hk,hv.toString());
});
try {
// Response response1 = okHttpClient.newCall(builder.method(apiTestDto.getMethod(),body.build()).build()).execute().body().string();
response = okHttpClient.newCall(builder.method(apiDTO.getMethod(),body.build()).build()).execute().body().string();
}catch (Exception e){
response = e.getMessage();
}
response = StringEscapeUtils.unicodeToStr(response);
log.info("response:{}",response);
return response;
}
private String json(ApiDTO apiDTO,Map<String, Object> headerMap) {
String response;
Request.Builder build = new Request.Builder().url(apiDTO.getUrl());
Request request;
OkHttpClient okHttpClient = new OkHttpClient().newBuilder().connectTimeout(60, TimeUnit.SECONDS).build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType,apiDTO.getData());
if (!apiDTO.getHeaders().isEmpty()) {
Object obj = JSON.parse(apiDTO.getHeaders());
Map<String, Object> map = (Map<String, Object>) obj;
for (Object o : map.entrySet()) {
Map.Entry entry = (Map.Entry) o;
build.addHeader(entry.getKey().toString(), entry.getValue().toString());
}
}
headerMap.forEach((hk,hv) -> {
build.addHeader(hk, hv.toString());
});
if (apiDTO.getMethod().equals("GET")) {
request = build
.get()
.build();
}else {
request = build
.method(apiDTO.getMethod(), body)
.build();
}
try {
response = Objects.requireNonNull(okHttpClient.newCall(request).execute().body()).string();
}catch (Exception e){
response = e.getMessage();
}
response = StringEscapeUtils.unicodeToStr(response);
log.info("response:{}",response);
return response;
}
private String params(ApiDTO apiDTO, Map<String, Object> headerMap) {
String response;
Request request = null;
if (!apiDTO.getData().isEmpty()) {
String params = "/?";
Object obj = JSON.parse(apiDTO.getData());
Map<String, Object> map = (Map<String, Object>) obj;
for (Object o : map.entrySet()) {
Map.Entry entry = (Map.Entry) o;
params = params + entry.getKey() + "=" + entry.getValue() + "&";
}
params = params.substring(0,params.length() - 1);
Request.Builder builder = new Request.Builder().url(apiDTO.getUrl() + params);
headerMap.forEach((hk,hv) -> {
builder.addHeader(hk, hv.toString());
});
OkHttpClient okHttpClient = new OkHttpClient().newBuilder().connectTimeout(60, TimeUnit.SECONDS)
.build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = RequestBody.create(mediaType, "");
switch (apiDTO.getMethod()) {
case "POST":
request = builder
.method("POST", body)
.build();
break;
case "GET":
request = builder
.get()
.build();
break;
case "PUT":
request = builder
.method("PUT", body)
.build();
break;
case "DELETE":
request = builder
.method("DELETE", body)
.build();
break;
}
try {
response = Objects.requireNonNull(okHttpClient.newCall(request).execute().body()).string();
}catch (Exception e){
response = e.getMessage();
}
response = StringEscapeUtils.unicodeToStr(response);
log.info("response:{}",response);
return response;
}else {
return null;
}
}
public static String findKey(JSONObject json, String key) {
String result = null;
for (String k : json.keySet()) {
if (k.equals(key)) {
return json.get(key).toString();
} else {
Object value = json.get(k);
if (value instanceof JSONObject) {
result = findKey((JSONObject) value, key);
if (result != null) {
return result;
}
} else if (value instanceof JSONArray) {
JSONArray array = (JSONArray) value;
int length = array.size();
for (int i = 0; i < length; i++) {
Object obj = array.get(i);
if (obj instanceof JSONObject) {
result = findKey((JSONObject) obj, key);
if (result != null) {
return result;
}
}
}
}
}
}
return result;
}
}