惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - cac2020

QA之二 - 单元测试-- JaCoCo QA之二 - 单元测试-- JUnit5 + Mockito QA之二 - 单元测试--Mockito QA之二 - 单元测试--JUnit5 QA之二 -- 测试用例 QA之一 -- 常见测试类型和测试环境 密码学之三 —— MPC(TSS)、多签、时间锁 密码学之二 —— GPG、SSH、KMS 密码学之一 —— 三类算法 记录一次在线word转PDF的问题处理过程 分析Java堆Dump Java GC日志分析 Java线程Dump分析(TDA-Thread Dump Analyzer) Java可视化故障处理工具-VisualVM Java基础故障处理工具 记录Arthas在一次性能调优过程中实践 中小型系统必要可行的性能测试实践--ArtHas调优实战 中小型系统必要可行的性能测试实践--jmeter落地实践 中小型系统必要可行的性能测试实践--性能测试理论基础
QA之三 - 变异测试 -- PITest
cac2020 · 2026-03-01 · via 博客园 - cac2020

一、是什么?

  1. 定义
  • 官方:变异测试是一种测试有效性验证技术,通过对源代码注入微小的、故意的错误(“变异体”),验证现有单元测试是否能检测到这些错误 —— 能检测到则测试有效,检测不到则测试存在漏洞。
  • 大白话:把变异测试比作 “黑客攻击你的代码”—— 故意在代码里埋小 bug(比如把 > 改成 <、把 + 改成 -),如果你的单元测试没发现这个 bug,说明测试写得 “假”(覆盖率再高也没用)。
  1. 为什么需要变异测试?(覆盖率的 “致命缺陷”)
    JaCoCo 覆盖率只能告诉你 “代码有没有被执行”,但无法告诉你 “测试能不能发现错误”:
  • ❌ 反例:多签服务中 if (signatureCount > threshold) 这行被执行(覆盖率 100%),但测试只传了 signatureCount=3、threshold=2(只测了 true 分支),如果把 > 改成 <,测试依然通过 —— 覆盖率高但测试无效;
  • ✅ 变异测试:自动把 > 改成 <(生成变异体),如果测试失败,说明测试能检测到这个错误;如果测试通过,说明测试遗漏了关键场景。
  1. PITest 是 Java 生态最主流的变异测试工具。

二、为什么?

  1. 变异测试术语
  • 变异体(Mutant):对源代码的微小修改(故意的错误),如把 signatureCount > threshold 改成 signatureCount < threshold;
  • 杀死(Killed):变异体导致测试失败 → 测试有效,如改完判断逻辑后,测试失败 → 变异体被杀死;
  • 存活(Survived):变异体未导致测试失败 → 测试无效,如改完判断逻辑后,测试通过 → 变异体存活;
  • 未覆盖(Uncovered):变异体所在代码未被测试执行 → 覆盖率问题,如改了未测试的代码行 → 变异体未覆盖;
  • 等价变异体(Equivalent):变异体不改变代码逻辑 → 无法杀死,如把 a = b + 0 改成 a = b → 逻辑等价;
  1. 变异类型
    PITest 的变异操作分为核心内置变异器、进阶变异器、实验性变异器,优先级:核心变异器覆盖 80% 的业务场景,进阶变异器补充边缘场景。

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 代码最易出错的场景.

  • CONDITIONALS_BOUNDARY(条件边界修改)
    修改条件判断的边界操作符(如 > ↔ <、>= ↔ <=、== ↔ !=),验证测试是否覆盖条件的所有分支。示例:
if (signatureCount > threshold) if (signatureCount < threshold) 测试是否覆盖 signatureCount < threshold 分支 if (txId == null) if (txId != null) 测试是否覆盖 txId 非空的场景 while (gasLimit >= 21000) while (gasLimit <= 21000) 测试是否覆盖 gasLimit 低于最小值的场景
原始代码(多签判断) 变异体(故意错误) 测试验证目标
  • MATH(算术操作符修改)
    修改算术运算符(+ ↔ -、* ↔ /、% ↔ *、++ ↔ --),验证数值计算逻辑的测试有效性。
    示例:
fee = gasPrice * gasLimit fee = gasPrice / gasLimit 测试是否校验手续费计算结果的合理性 balance += amount balance -= amount 测试是否覆盖余额扣减的场景 nonce++ nonce-- 测试是否校验交易 nonce 的递增逻辑
原始代码(手续费计算) 变异体(故意错误) 测试验证目标
  • TRUE_RETURNS、FALSE_RETURNS(布尔返回值修改)
    修改逻辑运算符(&& ↔ ||、! 新增 / 删除),验证多条件组合判断的测试完整性。
    示例:
if (txId != null && !txId.isEmpty()) if (txId != null || !txId.isEmpty()) 测试是否覆盖单条件不满足的场景 return !isValid return isValid 测试是否校验返回值的取反逻辑 while (a || b) while (a && b) 测试是否覆盖多条件组合的边界
原始代码(多条件校验) 变异体(故意错误) 测试验证目标
  • INCREMENTS(增量操作修改)
    修改增量 / 减量操作(++ ↔ --、+=1 ↔ -=1),是 ARITHMETIC 的子集,专门针对自增 / 自减。示例:
nonce++ nonce-- 测试是否校验 nonce 递增逻辑 gasUsed += 100 gasUsed -= 100 测试是否校验 gas 消耗计算
原始代码 变异体 测试验证目标
  • NEGATE_CONDITIONALS(条件取反)
    对整个条件表达式取反(if (a) → if (!a)),是 CONDITIONALS_BOUNDARY 的补充。示例:
if (rpcClient.isConnected()) if (!rpcClient.isConnected()) 测试是否覆盖 RPC 断开的场景 return signatureCount >= threshold return !(signatureCount >= threshold) 测试是否校验返回值的取反逻辑
原始代码 变异体 测试验证目标
  • NULL_RETURNS(空值返回修改)
    作用:将非空返回值改为 null,验证测试是否处理空值异常。示例:
return signatureUtils.sign(txId) return null 测试是否处理签名为 null 的场景
原始代码 变异体 测试验证目标
  • PRIMITIVE_WRAPPERS(基本类型包装器修改)
    作用:修改基本类型与包装类型的转换(如 Integer.valueOf(1) → null、int → Integer),验证自动装箱 / 拆箱的测试。示例:
Integer gasLimit = 21000 Integer gasLimit = null 测试是否处理包装类型 null 的场景
原始代码 变异体 测试验证目标

另外还有:

  • EMPTY_RETURNS:集合 / 字符串返回值改空;

2)进阶变异器(需手动开启,补充场景)
这类变异器默认关闭,需在 PITest 配置中手动指定,覆盖核心场景外的边缘错误类型。

  • INVERT_NEGS:取反操作反转,新增 / 删除取反符号(!a→a、a→!a),签名有效性 !isValid → 改成 isValid,验证取反逻辑测试;
  • INLINE_CONSTS:常量内联修改,修改常量值(如 final int THRESHOLD=2 → 改成 3),多签门限常量 THRESHOLD=2 → 改成 3,验证常量依赖的测试
  • VOID_METHOD_CALLS:空方法调用移除,删除无返回值方法的调用(日志、事件发送、RPC 通知),移除 eventEmitter.sendTxEvent(txId),验证事件发送的副作用测试
  • NON_VOID_METHOD_CALLS:非空方法调用替换,替换有返回值方法的调用结果(如 rpcClient.getGasPrice() → 返回固定值),RPC 获取 gasPrice 改成固定值 0,验证依赖外部数据的测试
  • CONSTRUCTOR_CALLS:构造方法调用修改,替换 / 移除构造方法调用(如 new TxResult() → null),交易结果对象 new TxResult() → 改成 null,验证对象创建的测试
  • REMOVE_INCREMENTS:增量操作移除,删除自增 / 自减操作(nonce++ → 无操作),移除 nonce++,验证 nonce 未递增时的测试
  • REMOVE_CONDITIONALS_EQUAL_IF:等值条件 IF 分支移除,移除 if (a == b) 中的 IF 分支(直接执行 else),移除 if (txId == targetTxId) 的 IF 分支,验证条件分支的测试
  • REMOVE_CONDITIONALS_EQUAL_ELSE:等值条件 ELSE 分支移除,移除 if (a == b) 中的 ELSE 分支(直接执行 if),移除 if (signatureCount == threshold) 的 ELSE 分支,验证边界分支测试
  • REMOVE_CONDITIONALS_ORDER_IF:顺序条件 IF 分支移除 移除 if (a > b) 等顺序条件的 IF 分支,移除 if (gasLimit > 21000) 的 IF 分支,验证顺序条件测试
  • REMOVE_CONDITIONALS_ORDER_ELSE:顺序条件 ELSE 分支移除,移除 if (a > b) 等顺序条件的 ELSE 分支,移除 if (fee > maxFee) 的 ELSE 分支,验证手续费上限测试

3)实验性变异器(慎用)
这类变异器处于实验阶段,可能不稳定,仅适用于特定场景(如 lambda、注解、并发代码)。

  • EXPERIMENTAL_ARGUMENT_PROPAGATION:参数传播修改,修改方法参数的传递(如 method(a) → method(b));checkSignature(null),仅测试参数校验逻辑时开启
  • EXPERIMENTAL_BIG_DECIMAL:BigDecimal 操作修改,修改 BigDecimal 的算术操作(add→subtract、multiply→divide,手续费(BigDecimal)fee.add(priorityFee) → 改成 subtract;
  • EXPERIMENTAL_BIG_INTEGER:BigInteger 操作修改,修改 BigInteger 的算术 / 比较操作,区块高度(BigInteger)height.compareTo(maxHeight) → 反向;
  • EXPERIMENTAL_MEMBER_VARIABLE:成员变量修改,修改类成员变量的值(如 this.threshold=2 → 3),多签服务成员变量 threshold 改成 3,验证成员变量依赖测试
  • EXPERIMENTAL_NAKED_RECEIVER:裸接收者修改,修改方法调用的接收者(如 a.method() → b.method()),rpcClient.sendTx() → 改成 mockClient.sendTx();
  • EXPERIMENTAL_SWITCH:Switch 分支修改,修改 switch 分支的执行逻辑(如 case 1 → case 2)
  1. 变异测试过程
    image

三、怎么用?
完整的流程:项目代码 → 单元测试 → 集成 PITest → 分析报告 → 优化测试。

  1. 第一步:集成 PITest(Maven 配置)
    PITest 核心依赖是 pitest-maven 插件。
点击查看代码
<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>

  1. 第二步:编写被测代码与初始测试
    (1)被测代码
点击查看代码
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));
    }
}

  1. 第三步:执行变异测试(PITest 命令)
    执行变异测试并生成报告mvn clean test org.pitest:pitest-maven:mutationCoverage

  2. 第四步:分析 PITest 报告(核心)
    打开 target/pit-reports/index.html,核心内容如下:

(1)概览页(关键指标)
ScreenShot_2026-03-02_001656_503

  • Line Coverage:变异行覆盖率,你的单元测试实际执行到的、且被 PITest 注入了变异体的代码行数,占所有生成了变异体的代码总行数的比例。
    PITest Line Coverage = (被测试执行的变异行数量) / (总变异行数量) × 100%
  • Mutation Coverage:代表变异测试覆盖率,你的单元测试能够 “处理”(杀死 / 检测到)或 “执行到” 的变异体数量,占总变异体数量的比例
    Mutation Coverage = (总变异体数量 - 未覆盖的变异体数量) / (总变异体数量 - 等价变异体数量) × 100%
  • Test Strength:测试强度 是 PITest 1.20+ 版本新增的核心指标(部分旧版本叫 Mutation Score/Mutation Coverage),本质是:衡量你的单元测试能有效发现代码错误的能力强弱,数值越高,说明测试越能识别代码中的微小错误(变异体),测试质量越高。
    Test Strength = (被杀死的变异体数量) / (总变异体数量 - 等价变异体数量) × 100%

(2)变异体详情(存活的变异体)
ce4de40a-6de9-4608-98a0-6576fafc9b26

PITest 会精准定位存活的变异体:
浅绿色的代码行表示已经被测试用例覆盖;
深绿色的代码行表示已经被变异测试覆盖;
浅粉红色的代码行表示没有被测试用例覆盖;
深粉红色的代码行表示还没有被变异测试覆盖;

  • Mutations:指 PITest 为当前类 / 方法生成的所有变异体数量(包含所有状态:Killed / 存活 / 未覆盖 / 等价),是评估 “当前代码被注入多少个故意错误” 的基础指标。Covering tests表示所覆盖的测试用例。
  • Active mutators:指 本次变异测试中,PITest 为当前类 / 方法实际启用的变异器类型列表
  • Tests examined:指 PITest 为了验证当前类 / 方法的每个变异体,实际执行的单元测试用例数量和执行时间,反映 “多少个测试用例参与了当前代码的变异验证”。
  1. 第五步:优化测试用例(杀死存活的变异体)
点击查看代码
// 补充测试:覆盖 signatureCount < threshold 的场景(false分支)
@Test
void testIsSignatureEnough_NotEnough() {
    assertFalse(service.isSignatureEnough(1)); // 测false分支
}
  1. 第六步:重新执行变异测试
    mvn clean test org.pitest:pitest-maven:mutationCoverage

四、PITest 高级配置(适配区块链开发场景)

  1. 排除无需变异的代码
点击查看代码
<configuration>
  <excludedClasses>
    <param>com.multisig.config.*</param> <!-- 排除配置类 -->
    <param>com.multisig.constants.*</param> <!-- 排除常量类 -->
    <param>com.multisig.utils.*</param> <!-- 排除工具类 -->
  </excludedClasses>
</configuration>
  1. 只变异核心业务代码
点击查看代码
<configuration>
  <targetClasses>
    <param>com.multisig.MultisigService</param>
    <param>com.multisig.TimelockService</param>
  </targetClasses>
</configuration>
  1. 配置变异操作(聚焦核心场景)
点击查看代码
<configuration>
  <mutators>
    <mutator>CONDITIONALS_BOUNDARY</mutator> <!-- 条件边界(门限判断) -->
    <mutator>ARITHMETIC</mutator> <!-- 算术操作(手续费计算) -->
    <mutator>RETURN_VALS</mutator> <!-- 返回值修改(RPC结果) -->
  </mutators>
</configuration>
  1. 加速变异测试(解决慢的问题)
点击查看代码
<configuration>
  <threads>4</threads> <!-- 多线程执行(CPU核心数) -->
  <timeoutFactor>1.5</timeoutFactor> <!-- 超时因子(缩短超时时间) -->
  <skipFailingTests>true</skipFailingTests> <!-- 跳过失败的测试 -->
</configuration>

学习技术不是用来写HelloWorld和Demo的,而是要用来解决线上系统的真实问题的.