ContiPerf是一个轻量级的测试工具,它能很轻易的让用户使用Junit4的测试用例进行联系的性能测试。其设计的灵感来自于Junit4利用注释进行简单的测试配置还来自于JUnitPerf用包装单元测试用于性能测试的思路。
ContiPerf目前最新的版本是2.1,它的依赖少,只需要 Java 5和Junit4.7以上。而且可以很轻松的通过maven导入,只需在pom文件中加入以下内容:以下是一个简单的例子:
首先,我们从上面的例子可以看到要使用ContiPerf必须现在@Rule的注释下生成一个ContiPerfRule的对象。ContiPerfRule的构造函数有三个,分别为:
public ContiPerfRule()、public ContiPerfRule(ExecutionLogger executionLogger)和public ContiPerfRule(ReportModule... modules)。
@PerfTest
用户可以在这个注释中添加性能测试的执行要求。
Invocations:方法的执行次数,例:@PerfTest(invocations = 300)重复执行300次;
Threads:同时执行的线程数,例:@PerfTest(invocations = 30, threads = 2)两个线程并发执行,每个线程执行15次,总共执行30次;
Duration:在指定时间范围内一直执行测试,例:@PerfTest(duration = 300)在300毫秒内反复执行。
三个属性可以组合使用,其中Threads必须和其他两个属性组合才能生效。当Invocations和Duration都有指定时,以执行次数多的为准。
例,@PerfTest(invocations = 300, threads = 2, duration = 100),如果执行方法300次的时候执行时间还没到100ms,则继续执行到满足执行时间等于100ms,如果执行到50次的时候已经100ms了,则会继续执行之100次。
如果你不想让测试连续不间断的跑完,可以通过注释设置等待时间,例,@PerfTest(invocations = 1000, threads = 10, timer = RandomTimer.class, timerParams = { 30, 80 }) ,每执行完一次会等待30~80ms然后才会执行下一次调用。
在开多线程进行并发压测的时候,如果一下子达到最大进程数有些系统可能会受不了,ContiPerf还提供了“预热”功能,例,@PerfTest(threads = 10, duration = 60000, rampUp = 1000) ,启动时会先起一个线程,然后每个1000ms起一线程,到9000ms时10个线程同时执行,那么这个测试实际执行了69s,如果只想衡量全力压测的结果,那么可以在注释中加入warmUp,即@PerfTest(threads = 10, duration = 60000, rampUp = 1000, warmUp = 9000) ,那么统计结果的时候会去掉预热的9s。
当执行的测试类中包括了多个测试方法的时候,如下图
则执行是顺序的,先执行test1,再执行test2。结果如图:
如果想让一个测试类中的方法也是并发执行,那么只要在类的前面加一个注释@RunWith(ParallelRunner.class)。
@Required
通过这个注释可以添加一些对性能期望,如果达到期望值则测试通过,如果没有达到期望值则执行失败。
@Required(throughput = 20) :每秒钟至少执行20次
@Required(average = 50):测试全部完成平均执行时间为20ms
@Required(median = 45):至少50%次执行的时间在45ms内
@Required(max = 2000) :所有执行的执行时间没有超过2s
@Required(totalTime = 5000) :测试完成执行时间少于5s
@Required(percentile90 = 3000) :所有执行中90%的执行时间少于3s
@Required(percentile95 = 5000):所有执行中95%的执行时间少于5s
@Required(percentile99 = 10000):所有执行中99%的执行时间少于10s
@Required(percentiles = "66:200,96:500"):所有执行中66%的执行时间少于200ms,96%的执行时间少于500ms
@PerfTest和@Required不仅可以指定某一个方法,也可以至于类的前面指定某一个类的执行参数。例,
同时ContiPerf还支持推Test Suites的性能测试,只需在类的最前面加注释@RunWith和@SuiteClasses ,例如:在每次执行完测试的时候,ContiPerf会自动生成测试报告,报告放在target/contiperf-report/index.html下。
PS:如果在对类指定了执行的参数,对类中的方法也执行了执行参数,那么实际执行的结果是什么?
通过简单的实验来解答这个问题: