Maven插件【单元测试自动化】:maven-surefire-plugin

12/31/2025 后端开发构建工具Maven

目录


参考


# Maven插件【单元测试自动化】:maven-surefire-plugin

Maven知识点-插件maven-surefire-plugin (opens new window)

这是 Maven Surefire Plugin,它是 Maven 生态中用于执行单元测试的核心插件,默认集成在 Maven 的生命周期中,主要用于运行 JUnit、TestNG 等测试框架的测试用例,并生成测试报告。以下是详细解析:


# 一、插件作用

  1. 自动执行单元测试
    • 在 Maven 构建的 test 生命周期阶段,自动运行 src/test/java/ 目录下符合命名规则的测试类(如 **/Test*.java**/*Test.java)。
    • 支持 JUnit 3/4/5 和 TestNG 等主流测试框架。
  2. 测试报告生成
    • 默认在 target/surefire-reports/ 目录下生成 XML 和文本格式的测试报告,便于集成到 CI/CD 工具(如 Jenkins)。
  3. 动态配置与扩展
    • 支持通过参数控制测试范围(如跳过测试、指定测试类)、并行执行、JVM 参数配置等。

# 二、配置解析(用户提供的配置示例)

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${maven-surefire-plugin.version}</version>
    <configuration>
        <skip>${skipUT}</skip>  <!-- 动态控制是否跳过单元测试 -->
        <systemPropertyVariables>
            <jacoco-agent.destfile>${project.build.directory}/jacoco.exec</jacoco-agent.destfile>
        </systemPropertyVariables>
    </configuration>
</plugin>
1
2
3
4
5
6
7
8
9
10
11

# 关键参数说明

  • <skip> 通过 ${skipUT} 变量动态决定是否跳过测试(true 跳过,false 执行)。等价于命令行 -DskipTests,但更灵活。
  • systemPropertyVariables 向测试运行时传递系统属性,此处配置了 JaCoCo 覆盖率工具的输出文件路径,用于集成测试覆盖率分析。

# 三、如何使用

# 1. 基础命令

  • 运行所有测试:

    mvn test
    
    1
  • 跳过测试:

    mvn test -DskipTests  # 或通过POM中的<skip>配置
    
    1

# 2. 高级用法

  • 指定单个测试类/方法:

    mvn test -Dtest=MyTestClass  # 运行特定类
    mvn test -Dtest=MyTestClass#testMethod  # 运行特定方法
    
    1
    2
  • 并行测试:在 <configuration> 中添加:

    <parallel>methods</parallel>
    <threadCount>4</threadCount>  <!-- 并发线程数 -->
    
    1
    2

# 3. 集成 JaCoCo(示例配置)

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.7</version>
    <executions>
        <execution>
            <goals><goal>prepare-agent</goal></goals>
        </execution>
    </executions>
</plugin>
1
2
3
4
5
6
7
8
9
10

配合 Surefire 的 jacoco-agent.destfile 参数生成覆盖率文件。


# 四、注意事项

  1. 版本兼容性 建议使用最新稳定版(如 3.0.0+),以支持 JUnit 5 和新特性。
  2. 测试命名规范 默认仅执行以 Test 开头/结尾的类,非标准命名需通过 <includes> 手动包含。
  3. maven-failsafe-plugin 区别 Surefire 用于单元测试,集成测试需使用 failsafe 插件。

通过合理配置,该插件能高效管理测试流程,是保障代码质量的关键工具。更多参数详见官方文档 (opens new window)


以下是:如何配置Surefire插件以支持JUnit 5测试?

要配置 Maven Surefire 插件以支持 JUnit 5 测试,需结合依赖引入和插件配置,以下是详细步骤和关键要点:


# 一、添加 JUnit 5 依赖

pom.xml 中引入 JUnit 5 的核心依赖(Jupiter API 和 Engine):

<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.9.3</version> <!-- 建议使用最新稳定版 -->
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.9.3</version>
        <scope>test</scope>
    </dependency>
</dependencies>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  • 作用:提供 JUnit 5 的注解(如 @Test@ParameterizedTest)和测试引擎支持。

# 二、配置 Surefire 插件

pom.xml<build> 部分配置 Surefire 插件,确保其兼容 JUnit 5:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0-M7</version> <!-- 推荐最新版本 -->
            <dependencies>
                <!-- 添加 JUnit Platform 支持 -->
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-surefire-provider</artifactId>
                    <version>1.7.0</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

关键点

  • 版本要求:Surefire 插件需 ≥ 2.22.0 才能原生支持 JUnit 5。
  • JUnit Platform 依赖junit-platform-surefire-provider 是连接 Surefire 和 JUnit 5 的桥梁。

# 三、可选:兼容 JUnit 4 和 JUnit 5

若项目混合使用 JUnit 4 和 5,需额外添加 junit-vintage-engine

<dependencies>
    <dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <version>5.9.3</version>
        <scope>test</scope>
    </dependency>
</dependencies>
1
2
3
4
5
6
7
8
  • 作用:允许运行 JUnit 4 的测试用例(如 @Test 来自 org.junit)。

# 四、高级配置示例

# 1. 指定测试范围

通过 <includes><excludes> 过滤测试类:

<configuration>
    <includes>
        <include>**/*Test.java</include> <!-- 匹配所有以 Test 结尾的类 -->
    </includes>
    <excludes>
        <exclude>**/*IntegrationTest.java</exclude> <!-- 排除集成测试 -->
    </excludes>
</configuration>
1
2
3
4
5
6
7
8

# 2. 参数化测试支持

确保 junit-jupiter-params 依赖已添加:

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-params</artifactId>
    <version>5.9.3</version>
    <scope>test</scope>
</dependency>
1
2
3
4
5
6
  • 用途:支持 @ParameterizedTest 等注解。

# 3. 并行测试

启用并行执行以提升速度:

<configuration>
    <parallel>methods</parallel>
    <threadCount>4</threadCount>
</configuration>
1
2
3
4

# 五、运行测试

执行以下命令运行测试并查看报告:

mvn test
1
  • 报告路径target/surefire-reports/ 包含 XML 和文本格式的测试结果。

# 六、常见问题解决

  1. 测试未执行

    • 检查测试类命名是否符合默认规则(如 *Test.java)或手动配置的 <includes>
    • 确认 JUnit 5 依赖和插件版本无冲突。
  2. 标签过滤 使用 groupsexcludedGroups 按标签过滤测试:

    <configuration>
        <groups>fast</groups> <!-- 只运行标记为 @Tag("fast") 的测试 -->
        <excludedGroups>slow</excludedGroups>
    </configuration>
    
    1
    2
    3
    4
    • 命令行覆盖:mvn test -Dgroups="fast"

通过以上配置,Surefire 插件可无缝支持 JUnit 5 的现代测试特性(如动态测试、嵌套测试等)。更多参数详见 官方文档 (opens new window)


以下是:Surefire插件中如何排除某些测试类不执行?

在 Maven Surefire 插件中,可以通过以下方式排除特定的测试类不执行,适用于需要跳过部分测试但保留其他测试运行的场景:


# 一、通过 <excludes> 配置排除

pom.xml 中直接配置需要排除的测试类(支持 Ant 风格路径或正则表达式):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
        <excludes>
            <exclude>**/TestCircle.java</exclude>  <!-- 排除指定类 -->
            <exclude>**/*ServiceTest.java</exclude> <!-- 排除某一类命名规则的类 -->
            <exclude>%regex[.*Slow.*]</exclude>    <!-- 正则匹配类名包含Slow的类 -->
        </excludes>
    </configuration>
</plugin>
1
2
3
4
5
6
7
8
9
10
11
12
  • 说明:
    • **/ 表示递归匹配子目录。
    • %regex[expr] 支持正则表达式匹配(基于编译后的 .class 文件名)。

# 二、通过命令行动态排除

在运行命令时通过 -Dtest 参数排除特定测试类或方法(需 Surefire ≥ 2.7.3):

mvn test -Dtest=!TestCircle,!*IntegrationTest  # 排除TestCircle和所有IntegrationTest类
1
  • 注意:此方式会覆盖 pom.xml 中的 <includes>/<excludes> 配置。

# 三、结合 Maven Profile 按环境排除

在特定 Profile 中配置排除规则,实现环境差异化测试:

<profiles>
    <profile>
        <id>prod</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <excludes>
                            <exclude>**/DevOnlyTest.java</exclude> <!-- 生产环境排除开发测试 -->
                        </excludes>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  • 适用场景:例如在生产构建中跳过耗时或依赖外部服务的测试。

# 四、通过注解临时忽略测试

对于 JUnit 或 TestNG,可直接在测试代码中添加注解忽略:

  • JUnit 4:

    @Ignore("临时忽略此测试")
    public class TestCircle { ... }
    
    1
    2
  • TestNG:

    @Test(enabled = false)
    public void disabledTest() { ... }
    
    1
    2
  • 说明:此方式无需修改插件配置,但需改动代码。


# 五、注意事项

  1. 优先级规则:
    • 命令行参数 -Dtest > pom.xml 中的 <excludes> > 注解忽略。
  2. 正则表达式匹配: 需注意正则匹配的是编译后的 .class 文件名(如 com/example/Test.class)。
  3. 多模块项目: 在父 POM 中配置 <excludes> 会对所有子模块生效,如需模块级定制需在子模块中覆盖配置。

通过以上方法,可以灵活控制测试范围,平衡构建速度与测试覆盖率。更多配置参考官方文档 (opens new window)


以下是:在多模块项目中,如何统一管理所有子模块的测试类排除规则?

在多模块 Maven 项目中,统一管理子模块的测试类排除规则可以通过以下集中化配置策略实现,确保所有模块遵循一致的测试过滤规则,同时支持灵活的子模块定制:


# 一、父 POM 全局配置(推荐)

在父模块的 pom.xml 中通过 pluginManagement<plugins> 定义默认排除规则,子模块自动继承:

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <excludes>
                        <exclude>**/*IntegrationTest.java</exclude>  <!-- 排除所有集成测试 -->
                        <exclude>**/Legacy*Test.java</exclude>       <!-- 排除Legacy前缀的测试类 -->
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
    <!-- 强制所有子模块应用此配置 -->
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
        </plugin>
    </plugins>
</build>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  • 优点:统一规则,减少重复配置;子模块可通过覆盖配置实现局部调整。
  • 适用场景:所有子模块需要共享相同的默认排除逻辑(如跳过集成测试或特定命名模式的测试类)。

# 二、动态属性与 Profile 结合

通过 Maven 属性和 Profile 实现环境差异化的排除规则:

<properties>
    <excluded.tests>**/*SlowTest.java,**/DevOnlyTest.java</excluded.tests>
</properties>

<profiles>
    <profile>
        <id>ci</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <excludes>${excluded.tests},**/LocalEnvTest.java</excludes>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  • 使用方式:
    • 默认规则:mvn test 使用 <properties> 中的排除项。
    • CI 环境规则:mvn test -Pci 追加排除 LocalEnvTest.java
  • 优点:灵活适配不同环境,命令行可覆盖(如 -Dexcluded.tests="**/TempTest.java")。

# 三、模块化排除规则继承

  1. 子模块局部覆盖 子模块可在自己的 pom.xml 中重新定义 <excludes>,优先级高于父 POM:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>**/SpecialTest.java</exclude> <!-- 仅当前模块排除 -->
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    • 适用场景:部分模块需要特殊处理(如模块 A 需排除性能测试,其他模块不排除)。
  2. 多级继承优化 对于复杂项目,可设计中间层父 POM(如 parent-serviceparent-web),在中间层定义模块组级别的排除规则。


# 四、高级技巧:正则表达式与类加载隔离

  1. 正则匹配复杂规则 使用 %regex[] 实现精细控制:

    <exclude>%regex[.*(Slow|Manual)Test.*]</exclude>  <!-- 排除含Slow或Manual的测试类 -->
    
    1
    • 适用场景:需要匹配复杂命名模式时。
  2. 类加载器隔离 避免测试类冲突,通过 argLine 配置独立类路径:

    <configuration>
        <argLine>-classpath ${project.build.directory}/test-classes</argLine>
    </configuration>
    
    1
    2
    3
    • 作用:确保模块间测试类互不干扰。

# 五、最佳实践总结

方法 适用场景 灵活性 维护性
父 POM 全局配置 所有子模块需统一规则
动态属性 + Profile 不同环境需差异化排除
子模块局部覆盖 部分模块需特殊规则
正则表达式 复杂命名模式匹配

建议组合使用

  1. 父 POM 定义基础规则(如跳过集成测试)。
  2. 子模块按需覆盖(如模块 A 排除性能测试)。
  3. 通过 Profile 实现环境适配(如 CI 环境排除本地调试测试)。
上次更新时间: 8/3/2025, 10:09:53 AM