java开发接口自动化测试jar包(初步)
文章目录
文章仅仅是提供了一个初步的实现方式和思路,还有很多地方要完善。
项目信息
项目目标:在开发者无需关心的情况下,使用切面技术,对特定类进行增强,,最终将拦截到的数据上传到指定测试网站上。可以收集每次的测试用例,从而大大减少了人工录入的时间。
技术选型:asm字节码操作框架(core api) + httpClient 网络请求框架, jdk 1.8+ ,spring 4.x+
项目架构:maven非web项目,最终会打包为一个jar
选用理由: 虽然asm开发上有一定难度,但开发完成后使用简单,配置正确后启动即可。而且以后可以利用同种思想,对service或者dao进行拦截,来完成某些用例收集需求。
下载地址见文章尾部
平台网址
yapi_cvte
成果展示
使用前
目标平台
接口列表(测试前)
测试集合列表(测试前)
使用本jar代理启动目标jar
启动postman
结果
可以观察每个接口的详细数据都被录入了,与postman信息一致
详细信息也是
测试集合也是一样,与接口是一对多的关系
这边是测试接口的界面.可以看见数据也是成功录入的
增强的字节码内容
植入后的字节码文件:
增强Controller:
@PostMapping({"{roomCode}/join"})
public Response connectRoom(@PathVariable("roomCode") String roomCode, @RequestHeader("systemId") String systemId, HttpServletRequest request) {
if(ObjectUtils.isEmpty(roomCode)) {
throw new ServiceException("roomCode不能为空", Integer.valueOf(ErrorStatus.PARAMS_NOT_MATCHED.getCode()));
} else {
RoomConnectRequestVo roomConnect = new RoomConnectRequestVo();
inputValueFromReq(roomConnect, request);
roomConnect.setRoomCode(roomCode);
roomConnect.setSystemId(systemId);
Response var10000 = this.connectionService.joinRoom(roomConnect);
//====================增强部分
String var6 = "ConnectController.connectRoom";
ArrayList var8 = new ArrayList();
var8.add("POST");
ArrayList var10 = new ArrayList();
StringBuffer var12 = new StringBuffer();
var10.add(var12.append("/roomcenter/rooms").
.append("/").append(roomCode).append("/join").toString());
HashMap var14 = new HashMap();
var14.put("systemId", systemId);
ControllerWeavingUtils.doMock(var10000, var6, var8, var10, (HashMap)null, (Object)null, request, var14);
//====================增强部分
return var10000;
}
}
添加Interceptor:
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
//====================增强部分
public HandlerInterceptorAdapter getWeavingHandler_() {
MyClassLoader myClassLoader = new MyClassLoader();
try {
Class<?> UploadInterceptor = myClassLoader.loadClass("UploadInterceptor");
Object o = UploadInterceptor.newInstance();
if(o instanceof HandlerInterceptorAdapter) {
HandlerInterceptorAdapter weavingHandler = (HandlerInterceptorAdapter)UploadInterceptor.newInstance();
System.out.println(o);
return weavingHandler;
}
} catch (Exception var4) {
var4.printStackTrace();
}
System.out.println("拦截器加载异常.......");
return null;
}
//====================增强部分
public InterceptorConfig() {
}
public void addInterceptors(InterceptorRegistry registry) {
//====================增强部分
registry.addInterceptor(this.getWeavingHandler_()).addPathPatterns(new String[]{"/**"});
//====================增强部分
InterceptorRegistration registration = registry.addInterceptor(this.getTokenHandler());
registration.addPathPatterns(new String[]{"/roomcenter/**"});
super.addInterceptors(registry);
}
@Bean
public TokenHandlerInterceptorAdapter getTokenHandler() {
return new TokenHandlerInterceptorAdapter();
}
//...
}
增强ControllerAdvice
@ControllerAdvice
public class GlobalExceptionHandler implements ResponseBodyAdvice {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
//====================增强部分
public boolean supports(MethodParameter methodParameter, Class aClass) {
System.out.println("-----------------------我是拦截-------------------------");
return true;
}
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
ServletServerHttpRequest sshr = (ServletServerHttpRequest)serverHttpRequest;
HttpServletRequest request = sshr.getServletRequest();
ConAdviceWeavingUtils.doMock(request, o, methodParameter, mediaType);
return o;
}
//====================增强部分
public GlobalExceptionHandler() {
}
@ExceptionHandler({ServiceException.class})
@ResponseBody
public Response serviceException(ServiceException exception) {
log.error("code = {}, message = {}", exception.getCode(), exception.getMessage());
return Response.error(exception);
}
//...
}
执行流程图:
这里不支持mermaid格式流程图,所以显示不出来了,有需要的人可以在别的md编辑器上打开查看
asm相关部分
代理模式启动流程图
ControllerAdapter or ConAdviceAdapter
以下全为ControllerAdapter举例
类增强的流程图
aspect的asm操作流程图
其中getInsertPosList()为获取之前所有的插入的局部变量在局部变量表中的位置
增强后的Controller执行流程图
InterceptorAdapter
拦截器增强的流程图
InterceptorAdapter
aspect 的asm操作流程图
不复杂,略
增强后的Interceptor执行流程图
main方式启动流程图(开发)
我们在开发时,要手动扫描类文件,即ClassTools.getClasses
Config.init()
即读取配置文件,并按照一定规则进行读取
其他 略
http相关部分
http.getHttpClient()
初始化HttpClient,并缓存数据
http.uploadCase()
项目git地址: 觉得有用就点个星星吧
参考链接:
-[asm官网]: http://asm.ow2.org/ “asm框架地址”
-[asm4中文指南]: http://www.jb51.net/books/488919.html “asm国内最高版本的翻译”
-[jvm指令集]: https://blog.youkuaiyun.com/sum_rain/article/details/39892219 “指令大全”
-[asm实现aop]: https://my.oschina.net/u/3269106/blog/1154508 “难得的原创不是抄自中文指南里的博客”