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

简介: 【2月更文挑战第23天】性能工具之代码级性能测试工具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

@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,会生成图表:

image.png

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

图表中的指标:

  • Execution time: 执行时间
  • Throughput: TPS
  • Min. latency: 最小响应时间
  • Average latency: 平均响应时间
  • Median: 响应时间中位数
  • 90%: 90%响应时间范围
  • Max latency: 最大响应时间

四、小结

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

示例代码:

参考资料:

目录
相关文章
|
11天前
|
机器学习/深度学习 人工智能 测试技术
EdgeMark:嵌入式人工智能工具的自动化与基准测试系统——论文阅读
EdgeMark是一个面向嵌入式AI的自动化部署与基准测试系统,支持TensorFlow Lite Micro、Edge Impulse等主流工具,通过模块化架构实现模型生成、优化、转换与部署全流程自动化,并提供跨平台性能对比,助力开发者在资源受限设备上高效选择与部署AI模型。
130 9
EdgeMark:嵌入式人工智能工具的自动化与基准测试系统——论文阅读
|
18天前
|
Java 测试技术 API
自动化测试工具集成及实践
自动化测试用例的覆盖度及关键点最佳实践、自动化测试工具、集成方法、自动化脚本编写等(兼容多语言(Java、Python、Go、C++、C#等)、多框架(Spring、React、Vue等))
62 6
|
2月前
|
前端开发 Java jenkins
Jmeter压力测试工具全面教程和使用技巧。
JMeter是一个能够模拟高并发请求以检查应用程序各方面性能的工具,包括但不限于前端页面、后端服务及数据库系统。熟练使用JMeter不仅能够帮助发现性能瓶颈,还能在软件开发早期就预测系统在面对真实用户压力时的表现,确保软件质量和用户体验。在上述介绍的基础上,建议读者结合官方文档和社区最佳实践,持续深入学习和应用。
509 10
|
18天前
|
测试技术 UED 开发者
性能测试报告-用于项目的性能验证、性能调优、发现性能缺陷等应用场景
性能测试报告用于评估系统性能、稳定性和安全性,涵盖测试环境、方法、指标分析及缺陷优化建议,是保障软件质量与用户体验的关键文档。
|
2月前
|
监控 Java 数据挖掘
利用Jmeter工具进行HTTP接口的性能测试操作
基础上述步骤反复迭代调整直至满足预期目标达成满意水平结束本轮压力评估周期进入常态监控阶段持续关注系统运转状态及时发现处理新出现问题保障服务稳定高效运作
294 0
|
3月前
|
敏捷开发 运维 数据可视化
DevOps看板工具中的协作功能:如何打破开发、测试与运维之间的沟通壁垒
在DevOps实践中,看板工具通过可视化任务管理和自动化流程,提升开发与运维团队的协作效率。它支持敏捷开发、持续交付,助力团队高效应对需求变化,实现跨职能协作与流程优化。
|
4月前
|
数据可视化 测试技术 Go
Go 语言测试与调试:`go test` 工具用法
`go test` 是 Go 语言内置的测试工具,支持单元测试、基准测试、示例测试等功能。本文详解其常用参数、调试技巧及性能测试命令,并提供实际项目中的应用示例与最佳实践。
|
4月前
|
Java 测试技术 容器
Jmeter工具使用:HTTP接口性能测试实战
希望这篇文章能够帮助你初步理解如何使用JMeter进行HTTP接口性能测试,有兴趣的话,你可以研究更多关于JMeter的内容。记住,只有理解并掌握了这些工具,你才能充分利用它们发挥其应有的价值。+
750 23
|
3月前
|
人工智能 数据可视化 测试技术
UAT测试排程工具深度解析:让验收测试不再失控,项目稳稳上线
在系统交付节奏加快的背景下,“测试节奏混乱”已成为项目延期的主因之一。UAT测试排程工具应运而生,帮助团队结构化拆解任务、清晰分配责任、实时掌控进度,打通需求、测试、开发三方协作闭环,提升测试效率与质量。本文还盘点了2025年热门UAT工具,助力团队选型落地,告别靠表格和群聊推进测试的低效方式,实现有节奏、有章法的测试管理。
|
11月前
|
监控 网络协议 Java
一些适合性能测试脚本编写和维护的工具
一些适合性能测试脚本编写和维护的工具
408 59

热门文章

最新文章