接口和协议组成 [接口测试][TestNG] 基于 testNG 的并发测试

bauul · 2018年12月31日 · 最后由 bauul 回复于 2019年06月27日 · 3555 次阅读

缘由

因为业务中是以任务流的方式交互的,而某些任务同时产生的,没有先后顺序的依赖关系,
这就要求在测试时,去关注不同的任务,先后提交是否有影响?
如果要并发执行一条以上的用例,又该怎么做呢?

问题点

  1. 这里主要讨论的是接口,因之前的接口自动化是基于 testNG 框架的,所以主要问题是查看 testNG 对用例执行顺序的支持
  2. 另一个问题点是,原来的用例执行器只支持一条一条的执行,testNG 的并发执行怎么玩的

原执行逻辑

for (Map.Entry<Integer, APITestCase> oneTC : JsonTestUtils.getAllTestCaseMap().entrySet()) {
    log.debug(oneTC.getValue().getName() + " : " + oneTC.getValue().getDescription());
    TestNG testNG = new TestNG(false);
    testNG.setSuiteThreadPoolSize(1);
    testNG.setThreadCount(1);
    testNG.setTestClasses(new Class[]{TestExecutor.class});
    JsonTestUtils.getTestCase();
    testNG.run();
}

这里是一条一条按顺序执行的,如果想要不按顺序执行,怎么搞?

方法一

将用例解析出来后,自己再写一个随机调用的方法,随机调用用例执行

方法二

TestNG testNG = new TestNG(false);
//        testNG.setSuiteThreadPoolSize(5);
testNG.setPreserveOrder(false);
testNG.setParallel(XmlSuite.ParallelMode.CLASSES);
testNG.setTestClasses(new Class[]{calzz1, clazz});
testNG.run();

在 testNG 中是可以指定测试类的执行顺序的,
如上代码所示,preserveOrder 是指定执行顺序的,默认是 true,按字母顺序排列
此外,设计线程池的数量在一定程度上,也能达到类似的效果,因为是并发执行的,执行的顺序并不固定
另外这里的 clazz 和 clazz1 是在用例执行前动态生成的,参考:使用 java 动态加载机制模拟脚本语言的效果

扩展

把这里的顺序执行与并发支持做成参数,开放给用户在 web 页面上勾选,以提高用例执行的灵活度

参考

JAVA 测试新技术-TestNG 和高级概念

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 9 条回复 时间 点赞

testNG.setTestClasses(new Class[]{calzz1, clazz});这里的 clazz 和 clazz1 是在用例执行前动态生成的。
想问一下 TestNG 运行一个用例的时候可以运行内存中的.class 文件吗? 比如一个 java 的测试用例我使用 cglib 动态生成的,没有保存到磁盘中,那么这个.java 的测试用例使用 TestNG 要如何运行呢?

shandongdong 回复

可以的,使用 cglib 动态生成的,可以通过 Class.forName 进行加载,也可以借助 javassist 进行动态生成类,参看我的另一篇文章:https://testerhome.com/topics/18811

bauul 回复

不好意思,不太明白的是就算使用 Class.forName 的方式,也需要有具体的类全名才可以吧?通过 javassist 进行动态生成类应该是在内存中的,那不是找不到这个类么?

shandongdong 回复

在使用 javassist 时,调用 cc.toClass() 方法就拿到类实例了,你再好好看看吧,去敲了试试

Class executor = cc.toClass();

请教楼主一个问题:
背景是这样的:发布集群过程中希望通过调用接口测试用例的方式验证单台服务器发布是否成功。通过读取 jenkins 传过来的 ip list,来判断测试用例要执行多少次,以及执行在哪些服务上
问题:用 testng 如何动态的调度用例的执行次数,并控制好所访问的服务器 ip?请楼主不吝赐教
是否方便价格微信。

Maokq 回复

是可以动态控制执行次数的,不过相对会复杂一些。
首先要弄清楚是怎么个调整次数,是整个测试集的次数,还是单个用例的次数,
如果是整个测试集应该比较简单,
如果是单个测试用例的话,在 testNG 中,可以在@test注解中加一个 invocationCount 参数,可以控制次数

到于服务器 ip 这个可以做一个全局参数来读取吧?当然也可以作为用例的参数传给用例,这里的差别就是一种是在用例中主动读取其他信息,另一种是被动接收信息

bauul · #7 · 2019年06月26日 Author
仅楼主可见

谢谢楼主这么快回我。
是整个测试集的执行,包括 Before,需要动态调整执行次数,因为每次发布的服务数量是不定的

Maokq 回复

整个测试集的话,就在执行的外边增加一个读取 ip 服务器的个数,然后来调这个测试集的用例就可以了吧

比如下面是执行所有用例,再在外面加一个循环就可以了

for (Map.Entry<Integer, APITestCase> oneTC : JsonTestUtils.getAllTestCaseMap().entrySet()) {
    log.debug(oneTC.getValue().getName() + " : " + oneTC.getValue().getDescription());
    TestNG testNG = new TestNG(false);
    testNG.setSuiteThreadPoolSize(1);
    testNG.setThreadCount(1);
    testNG.setTestClasses(new Class[]{TestExecutor.class});
    JsonTestUtils.getTestCase();
    testNG.run();
}
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册