本帖已被设为精华帖!
缘由
之前有基于testNG+okHttp 封装了一个接口自动化测试的执行器,将测试用例都放在json文件中: [接口测试平台一期] 接口测试用例参数化方案
但是一直都是按顺序执行的,现在想要实现同时执行多个用例,但是因为我的执行器就一个类文件,
如果想要同时执行,基于testNG的话,需要多个类,那么问题来了,如何自动生成多个类文件呢?
解决思路(主要是动态代理)
- cglib
- javassist
这两者都支持继承实现动态代理,
cglib在继承注解时,存在一定的问题,自定义注解中未加入@Inherited, 是不会继承该注解的,或者是我没找到解决的方法
javassist更强大,字节码级别的,可在运行时修改方法,注解参数等
两个坑都踩了,最后还是用javassist实现了
实现
引入javassist
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.24.1-GA</version>
</dependency>
生成类
CtClass cc = pool.makeClass("TestExecutor" + caseSetIndex);
CtClass superClass = pool.getCtClass("com.wz.exec.BaseExecutor");
cc.setSuperclass(superClass);
CtMethod method = CtNewMethod.make("public void executor() { run();}", cc);
ConstPool methodPool = method.getMethodInfo().getConstPool();
AnnotationsAttribute attribute = new AnnotationsAttribute(methodPool, AnnotationsAttribute.visibleTag);
Annotation annotation = new Annotation("org.testng.annotations.Test", methodPool);
annotation.addMemberValue("invocationCount", new IntegerMemberValue(methodPool, 1));
annotation.addMemberValue("description", new StringMemberValue(apiTestCase.getCaseInfo().getCaseName(), methodPool));
attribute.addAnnotation(annotation);
method.getMethodInfo().addAttribute(attribute);
cc.addMethod(method);
Class executor = cc.toClass();
塞到testNG中
# 实际这里我塞进去的是一个列表
testNG.setTestClasses(executor);
更多思考
因为最近在看《Java程序性能优化 让你的Java程序更快、更稳定》,接触到javassist,
但在百度查的时候发现,这个套路在12年的时候就有人玩过
还是自己太无知了因为是动态生成的,如果生成了很多的类,会存在内存耗尽的问题,
所以可以更进一步,思考内存消耗的问题,
可以自定义classloader来加载这些动态生成的类,用完就释放
参考
Book:《Java程序性能优化 让你的Java程序更快、更稳定》
javassist官网:http://www.javassist.org/tutorial/tutorial2.html#add
「All right reserved, any unauthorized reproduction or transfer is prohibitted」
TesterHome 为用户提供「保留所有权利,禁止转载」的选项。
除非获得原作者的单独授权,任何第三方不得转载标注了「All right reserved, any unauthorized reproduction or transfer is prohibitted」的内容,否则均视为侵权。
具体请参见TesterHome 知识产权保护协议。
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!