写点什么

性能工具之代码级性能测试工具 ContiPerf

作者:zuozewei
  • 2021 年 12 月 30 日
  • 本文字数:2582 字

    阅读完需:约 8 分钟

性能工具之代码级性能测试工具ContiPerf

一、前言

做性能的同学一定遇到过这样的场景:应用级别的性能测试发现一个操作的响应时间很长,然后要花费很多时间去逐级排查,最后却发现罪魁祸首是代码中某个实现低效的底层算法。这种自上而下的逐级排查定位的方法,效率通常都很低,代价也很高。所以,我们就需要在项目早期,对一些关键算法进行代码级别的性能测试,以防止此类在代码层面就可以被发现的性能问题,遗留到最后的系统性能测试阶段才被发现。但是,从实际执行的层面来讲,代码级性能测试并不存在严格意义上的测试工具,通常的做法是:改造现有的单元测试框架


而最常使用的改造方法是:


  • 将原本只会执行一次的单元测试用例连续执行 n 次,这个 n 的取值范围通常是 2000~5000;

  • 统计执行 n 次的平均时间。如果这个平均时间比较长(也就是单次函数调用时间比较长)的话,比如已经达到了秒级,那么通常情况下这个被测函数的实现逻辑一定需要优化。


这里之所以采用执行 n 次的方式,是因为函数执行时间往往是毫秒级的,单次执行的误差会比较大,所以采用多次执行取平均值的做法。


那么有没有现成的这样的测试工具呢?当然也是有的,比如今天我们介绍的主角-- ContiPerf

二、ContiPerf 简介

ContiPerf 是一个轻量级的测试工具,基于 JUnit 4 开发,可用于效率测试等。可以指定在线程数量和执行次数,通过限制最大时间和平均执行时间来进行性能测试。


官网地址:https://sourceforge.net/p/contiperf/wiki/Home/

三、ContiPerf 使用

接下来我们一起来实践一个例子,


首先,加入 pom 依赖包:


   <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter</artifactId>        </dependency>
<!--引入 ContiPerf 测试工具--> <dependency> <groupId>org.databene</groupId> <artifactId>contiperf</artifactId> <version>2.3.4</version> <scope>test</scope> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency><dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency>
复制代码


这里为了演示,编写了一个简单的测试接口:UnitTestService.java


/** * 测试接口类 * @author zuozewei * */public interface UnitTestService {    public String process(String msg);
}
复制代码


实现类:UnitTestServiceImpl.java


@Servicepublic class UnitTestServiceImpl implements UnitTestService {
/** * 为了测试,这里直接返回传入的值 */ @Override public String process(String msg) { // TODO Auto-generated method stub return msg; }}
复制代码


编写 UnitTestServiceTest 测试类,进入 ContiPerfRule。


/** * 编写接口性能测试类 * @author zuozewei * */@RunWith(SpringRunner.class)@SpringBootTest //SpringBootTest 是springboot 用于测试的注解,可指定启动类或者测试环境等,这里直接默认。public class UnitTestServiceTest {    @Autowired  UnitTestService testService;    // 引入 ContiPerf 进行性能测试  @Rule  public ContiPerfRule contiPerfRule = new ContiPerfRule();
@Test @PerfTest(invocations = 10000,threads = 100) //100个线程 执行10000次 public void test() { String msg = "this is a test"; String result = testService.process(msg); //断言 是否和预期一致 Assert.assertEquals(msg,result); }}
复制代码


注意:@Rule 是 J unit 提供的一个扩展接口注解,其接口类为:org.junit.rules.MethodRule,注意在 Junit5 中,已经被 TestRule 所替代了。也可以通过对类指定 @PerfTest 和 @Required,表示类中方法的默认设置。


@PerfTest 注解:

  • invocations:执行次数 n,与线程数量无关,默认值为 1

  • threads:线程池数量 n,并发执行 n 个线程

  • duration:重复地执行时间 n,测试至少执行 n 毫秒


@Required 注解:

  • @Required(throughput = 20):要求每秒至少执行 20 个测试;

  • @Required(average = 50):要求平均执行时间不超过 50ms;

  • @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。


运行测试,控制台会生成结果:


com.zuozewei.springbootcontiperfdemo.service.UnitTestServiceTest.testsamples: 10000max:     331average: 33.3522median:  30
复制代码


同时访问:target/contiperf-report/index.html,会生成图表:



注意:图表需要科学上网才能显示


图表中的指标:

  • Execution time: 执行时间

  • Throughput: TPS

  • Min. latency: 最小响应时间

  • Average latency: 平均响应时间

  • Median: 响应时间中位数

  • 90%: 90%响应时间范围

  • Max latency: 最大响应时间

四、小结

这里主要是对 Junit 和 ContiPerf 的使用简单的示例,在单元测试阶段的时候考虑做这种代码级性能测试,肯定会提高 ROI(投入产出比)的,而且代价非常小,希望本文对各位同学都能有所启发。


示例代码:


  • https://github.com/zuozewei/blog-example/tree/master/Performance-testing/00-code-performance/contiperf/springboot-contiperf-demo


参考资料:


  • [1]:https://sourceforge.net/p/contiperf/wiki/Home

  • [2]:《软件测试 52 讲》

发布于: 刚刚
用户头像

zuozewei

关注

测试及性能 | 公众号@7DGroup 2017.12.23 加入

「7DGroup」公号作者,CSDN博客专家、测试领域优质创作者,华为云·云享专家,掘金2021年度人气作者No.12,极客时间《全链路压测实战30讲》专栏作者之一,《性能测试实战30讲》、《高楼的性能工程实战课》专栏编委。

评论

发布
暂无评论
性能工具之代码级性能测试工具ContiPerf