






















一、是什么?
二、为什么?
pitest不同版本的编译器可能不同,在执行时日志里会打印当前版本可用的编译器:
点击查看代码version 1.20.7
[INFO] Available mutators : EXPERIMENTAL_ARGUMENT_PROPAGATION,FALSE_RETURNS,TRUE_RETURNS,CONDITIONALS_BOUNDARY,CONSTRUCTOR_CALLS,EMPTY_RETURNS,INCREMENTS,INLINE_CONSTS,INV
ERT_NEGS,MATH,NEGATE_CONDITIONALS,NON_VOID_METHOD_CALLS,NULL_RETURNS,PRIMITIVE_RETURNS,REMOVE_CONDITIONALS_EQUAL_IF,REMOVE_CONDITIONALS_EQUAL_ELSE,REMOVE_CONDITIONALS_ORDE
R_IF,REMOVE_CONDITIONALS_ORDER_ELSE,VOID_METHOD_CALLS,EXPERIMENTAL_BIG_DECIMAL,EXPERIMENTAL_BIG_INTEGER,EXPERIMENTAL_MEMBER_VARIABLE,EXPERIMENTAL_NAKED_RECEIVER,REMOVE_INCREMENTS,EXPERIMENTAL_SWITCH
1)核心内置变异器(默认开启)
这是 PITest 最常用的变异操作,覆盖 Java 代码最易出错的场景.
> ↔ <、>= ↔ <=、== ↔ !=),验证测试是否覆盖条件的所有分支。示例:| 原始代码(多签判断) | 变异体(故意错误) | 测试验证目标 |
|---|---|---|
+ ↔ -、* ↔ /、% ↔ *、++ ↔ --),验证数值计算逻辑的测试有效性。| 原始代码(手续费计算) | 变异体(故意错误) | 测试验证目标 |
|---|---|---|
&& ↔ ||、! 新增 / 删除),验证多条件组合判断的测试完整性。| 原始代码(多条件校验) | 变异体(故意错误) | 测试验证目标 |
|---|---|---|
| 原始代码 | 变异体 | 测试验证目标 |
|---|---|---|
| 原始代码 | 变异体 | 测试验证目标 |
|---|---|---|
| 原始代码 | 变异体 | 测试验证目标 |
|---|---|---|
| 原始代码 | 变异体 | 测试验证目标 |
|---|---|---|
另外还有:
2)进阶变异器(需手动开启,补充场景)
这类变异器默认关闭,需在 PITest 配置中手动指定,覆盖核心场景外的边缘错误类型。
3)实验性变异器(慎用)
这类变异器处于实验阶段,可能不稳定,仅适用于特定场景(如 lambda、注解、并发代码)。

三、怎么用?
完整的流程:项目代码 → 单元测试 → 集成 PITest → 分析报告 → 优化测试。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Test3</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<!-- 统一指定项目编码为 UTF-8 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 统一指定项目报告编码(可选,避免报告乱码) -->
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!-- JUnit 5 核心依赖 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
<!-- 参数化测试依赖 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
<!-- Mockito 核心依赖 -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.11.0</version>
<scope>test</scope>
</dependency>
<!-- Mockito 适配 JUnit 5 的扩展 -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>4.11.0</version>
<scope>test</scope>
</dependency>
<!-- 可选:静态方法Mock依赖(如需Mock静态工具类) -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.11.0</version>
<scope>test</scope>
</dependency>
<!-- pitest适配JUnit5依赖 必要 -->
<dependency>
<groupId>org.pitest</groupId>
<artifactId>pitest-junit5-plugin</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 执行快速、独立的单元测试(失败会直接中断构建)-->
<!--<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version>
</plugin>-->
<!-- 专门用于执行集成测试(Integration Tests) -->
<!--<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.1.2</version>
</plugin>-->
<!-- 1. JaCoCo 核心插件(生成覆盖率报告) -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.12</version> <!-- 最新稳定版 -->
<configuration>
<excludes>
<!-- 排除配置类 -->
<exclude>com/multisig/config/**/*</exclude>
<!-- 排除工具类常量 -->
<exclude>com/multisig/constants/**/*</exclude>
<!-- 排除测试专用代码 -->
<exclude>**/*Test*.class</exclude>
</excludes>
</configuration>
<executions>
<!-- 执行测试时收集覆盖率数据 -->
<execution>
<id>jacoco-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<!-- 测试完成后生成覆盖率报告 -->
<execution>
<id>jacoco-report</id>
<phase>test</phase> <!-- 绑定到 mvn test 阶段 -->
<goals>
<goal>report</goal>
</goals>
</execution>
<!-- 可选:强制执行覆盖率规则(如行覆盖率≥80%) -->
<execution>
<id>jacoco-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<!-- 对所有代码的行覆盖率要求 ≥80% -->
<rule>
<element>BUNDLE</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.8</minimum> <!-- 80% 行覆盖 -->
</limit>
<!-- 分支覆盖率 ≥70% -->
<limit>
<counter>BRANCH</counter>
<value>COVEREDRATIO</value>
<minimum>0.7</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<!-- 2. 确保 Maven Surefire 插件适配 JUnit 5 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<includes>
<include>**/*Test.java</include> <!-- 执行所有测试类 -->
</includes>
</configuration>
</plugin>
<!-- PITest 核心插件(变异测试) -->
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.20.7</version> <!-- 最新稳定版 -->
<configuration>
<!-- 1. 适配 JUnit 5(必须) -->
<testPlugin>junit5</testPlugin> <!-- 使用 JUnit 5 时必须指定 -->
<!-- 2. 配置测试范围(可选) -->
<targetClasses>
<param>org.example.*</param> <!-- 只测试多签服务包 -->
</targetClasses>
<targetTests>
<param>org.example.*Test</param> <!-- 只执行多签测试类 -->
</targetTests>
<!-- 3. 排除无需变异的代码(可选,如配置类) -->
<excludedClasses>
<param>org.example.config.*</param>
<param>org.example.constants.*</param>
</excludedClasses>
<!-- 4. 配置变异操作(可选,默认全开启) -->
<mutators>
<mutator>CONDITIONALS_BOUNDARY</mutator> <!-- 条件边界修改 -->
<mutator>MATH</mutator> <!-- 算术操作符修改 -->
<mutator>NEGATE_CONDITIONALS</mutator> <!-- 逻辑操作符修改 -->
</mutators>
<!-- 5.性能优化(JDK 11 多线程加速) -->
<threads>4</threads> <!-- 按CPU核心数配置,如4/8 -->
<timeoutFactor>1.5</timeoutFactor> <!-- 超时因子(缩短超时) -->
<skipFailingTests>true</skipFailingTests> <!-- 跳过失败的测试 -->
<!-- 6.报告配置(生成HTML+XML) -->
<outputFormats>
<format>HTML</format>
<format>XML</format>
</outputFormats>
</configuration>
</plugin>
</plugins>
</build>
</project>
package org.example;
public class MultisigService {
private int threshold = 2; // 多签门限
// 核心方法:判断签名数是否满足门限
public boolean isSignatureEnough(int signatureCount) {
// 核心判断(易出错点)
if (signatureCount > threshold) {
return true;
} else {
return false;
}
}
// 核心方法:计算交易手续费(算术操作)
public long calculateFee(long gasPrice, long gasLimit) {
return gasPrice * gasLimit; // 算术操作(易出错)
}
}
(2)初始测试代码
点击查看代码package org.example;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class MultisigServiceTest {
private MultisigService service = new MultisigService();
// 只测了 signatureCount > threshold 的场景(true分支)
@Test
void testIsSignatureEnough_Enough() {
assertTrue(service.isSignatureEnough(3));
}
// 只测了正常算术计算,未测边界
@Test
void testCalculateFee() {
assertEquals(2100000, service.calculateFee(100, 21000));
}
}
第三步:执行变异测试(PITest 命令)
执行变异测试并生成报告mvn clean test org.pitest:pitest-maven:mutationCoverage
第四步:分析 PITest 报告(核心)
打开 target/pit-reports/index.html,核心内容如下:
(1)概览页(关键指标)

PITest Line Coverage = (被测试执行的变异行数量) / (总变异行数量) × 100% Mutation Coverage = (总变异体数量 - 未覆盖的变异体数量) / (总变异体数量 - 等价变异体数量) × 100%Test Strength = (被杀死的变异体数量) / (总变异体数量 - 等价变异体数量) × 100% (2)变异体详情(存活的变异体)

PITest 会精准定位存活的变异体:
浅绿色的代码行表示已经被测试用例覆盖;
深绿色的代码行表示已经被变异测试覆盖;
浅粉红色的代码行表示没有被测试用例覆盖;
深粉红色的代码行表示还没有被变异测试覆盖;
// 补充测试:覆盖 signatureCount < threshold 的场景(false分支)
@Test
void testIsSignatureEnough_NotEnough() {
assertFalse(service.isSignatureEnough(1)); // 测false分支
}
mvn clean test org.pitest:pitest-maven:mutationCoverage四、PITest 高级配置(适配区块链开发场景)
<configuration>
<excludedClasses>
<param>com.multisig.config.*</param> <!-- 排除配置类 -->
<param>com.multisig.constants.*</param> <!-- 排除常量类 -->
<param>com.multisig.utils.*</param> <!-- 排除工具类 -->
</excludedClasses>
</configuration>
<configuration>
<targetClasses>
<param>com.multisig.MultisigService</param>
<param>com.multisig.TimelockService</param>
</targetClasses>
</configuration>
<configuration>
<mutators>
<mutator>CONDITIONALS_BOUNDARY</mutator> <!-- 条件边界(门限判断) -->
<mutator>ARITHMETIC</mutator> <!-- 算术操作(手续费计算) -->
<mutator>RETURN_VALS</mutator> <!-- 返回值修改(RPC结果) -->
</mutators>
</configuration>
<configuration>
<threads>4</threads> <!-- 多线程执行(CPU核心数) -->
<timeoutFactor>1.5</timeoutFactor> <!-- 超时因子(缩短超时时间) -->
<skipFailingTests>true</skipFailingTests> <!-- 跳过失败的测试 -->
</configuration>
学习技术不是用来写HelloWorld和Demo的,而是要用来解决线上系统的真实问题的.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。