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

发表于:2022-1-21 09:30

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Zee_7D    来源:博客园

  前言
  做性能的同学一定遇到过这样的场景:应用级别的性能测试发现一个操作的响应时间很长,然后要花费很多时间去逐级排查,最后却发现罪魁祸首是代码中某个实现低效的底层算法。这种自上而下的逐级排查定位的方法,效率通常都很低,代价也很高。所以,我们就需要在项目早期,对一些关键算法进行代码级别的性能测试,以防止此类在代码层面就可以被发现的性能问题,遗留到最后的系统性能测试阶段才被发现。但是,从实际执行的层面来讲,代码级性能测试并不存在严格意义上的测试工具,通常的做法是:改造现有的单元测试框架
  而最常使用的改造方法是:
  ·将原本只会执行一次的单元测试用例连续执行 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
  @Service
  public 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.test
  samples: 10000
  max: 331
  average: 33.3522
  median: 30
  同时访问:target/contiperf-report/index.html,会生成图表: 
  图表中的指标:
  ·Execution time: 执行时间
  · Throughput: TPS
  · Min. latency: 最小响应时间
  · Average latency: 平均响应时间
  · Median: 响应时间中位数
  · 90%: 90%响应时间范围
  · Max latency: 最大响应时间
  小结
  这里主要是对 Junit 和 ContiPerf 的使用简单的示例,在单元测试阶段的时候考虑做这种代码级性能测试,肯定会提高 ROI(投入产出比)的,而且代价非常小,希望本文对各位同学都能有所启发。

  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号