如何通过代码进行对接口的性能测试,其实基本的原理就是通过开多个线程并发调用接口来实现的。由于Junit本身并不支持,所以我们测试时需要自己写一些代码,建立个主线程,在主线程控制启动指定子线程的数目来进行测试。有没有什么其它的方式能使这个过程更简单一点呢?有!TestNG!
TestNG提供了丰富的Annotation为测试提供更强大,更细致的控制,比如用于并发测试的invocationCount和threadPoolSize。他们都是 @Test的两个属性,使用的时候只要写到测试方法的上面就可以了,比如:
@Test(invocationCount=100,threadPoolSize=5) public void testMethod(){} |
testMethod testMethod[1] testMethod[2] … |
threadPoolSize 这个属性表示的是开启线程数的多少,例子中表示的就是启动5个线程来运行100次,threadPoolSize的设定要依赖 invocationCount的设定,如果invocationCount的设定值小于threadPoolSize的设定值,多于的设定是无效的,举个极端的例子,如果你threadPoolSize设定是100,而invocationCount没有设定(默认为1次),那么系统只有开启一个线程来运行。反过invocationCount的设定不依赖threadPoolSize,testNG会以默认值1来运行。
说到这或者有人会说它真的是并发执行的吗?一开始我也怀疑过,于是我做了测试,我写了下面一个测试方法:
@Test(invocationCount=10,threadPoolSize=5) public void testMethod() throws Exception{ int i = 0; while(i < 10){ System.out.println(i++); Thread.sleep(100); } } |
开始时我将threadPoolSize设置去掉,然后执行,发现输出结果都是顺序的,而加上threadPoolSize设定后输出开始有些错乱,表明确实是多线程在执行。
下面介绍一下我在性能测试中两种用法:
一、 有明确的执行次数的场景,如这个方法要求并发执行1w次,这个很简单,只要将invocationCount设定为1w就可以了,线程数可以根据实际情况调整。
二、 要执行一段时间,如这个方法并发执行2小时,这时我们可以稍微调整一下程序,将invocationCount与threadPoolSize设为一致,方法中增加对时间的控制:
@Test(invocationCount=25,threadPoolSize=25) public void testMethod() throws Exception{ while(true){ long start = System.currentTimeMillis(); doSomeThing(); if((System.currentTimeMillis()- startTime) > 3000*20) { break; } } } |
程序运行可以通过 eclipse 的插件与mvn的插件来运行。