1. 概述

JUnit 是 Java 应用最流行的测试框架之一,提供了强大且灵活的自动化单元测试能力。其中一项核心功能是创建测试套件(test suite),允许我们将多个测试分组执行

本文将深入探讨如何使用 JUnit 创建测试套件。首先实现并运行一个简单套件,然后探索包含/排除测试的配置技巧。

2. 创建测试套件

测试套件本质上是将多个测试组合为单个执行单元的集合。我们用它按逻辑分组测试(如特定组件或功能模块),也能按特定顺序执行测试,或根据条件运行测试子集。

JUnit 5 提供多种创建测试套件的方式。开始前需确保添加 junit-platform-suite 依赖

<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-suite</artifactId>
    <version>1.11.0-M1</version>
    <scope>test</scope>
</dependency>

JUnit Platform Suite Engine 负责通过 JUnit 测试引擎运行自定义套件,并提供创建套件所需的 API。

2.1. 使用 @Suite 注解

最推荐的套件实现方式是使用类级别注解 @Suite(自 JUnit Platform 1.8.0 起支持):

@Suite
@SuiteDisplayName("我的测试套件")
public class JUnitTestSuite {
}

@Suite 标记该类为可执行单元
@SuiteDisplayName(可选)自定义套件名称
⚠️ 当前套件未包含任何测试

通过 IDE 或 maven-surefire-plugin 即可执行套件中所有配置的测试。

2.2. 使用 @RunWith 注解

替代方案是使用 JUnit 4 风格的 @RunWith 注解

@RunWith(JUnitPlatform.class)
@SuiteDisplayName("我的测试套件")
public class JUnitRunWithSuite {
}

需额外添加依赖:

<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-runner</artifactId>
    <version>1.11.0-M1</version>
    <scope>test</scope>
</dependency>

仅适用于旧版 JUnit
JUnitPlatform 已在 1.8.0 废弃,未来版本将移除
✅ 功能与 @Suite 等价

3. 包含与排除测试

当前套件未包含任何测试。JUnit Platform Suite Engine 提供多种注解控制测试的包含/排除

主要分两类注解:

  • @Select 系列:指定测试扫描范围
  • @Include/@Exclude 系列:对已扫描测试添加过滤条件

⚠️ 必须先使用 @Select 注解@Include/@Exclude 才能生效。可混合使用实现精准控制。

3.1. @SelectClasses

最常用方式:通过 @SelectClasses 指定测试类

@Suite
@SelectClasses({ClassOneUnitTest.class, ClassTwoUnitTest.class})
public class JUnitSelectClassesSuite {
}

✅ 执行两个类中所有 @Test 方法

3.2. @SelectPackages

使用 @SelectPackages 指定扫描包

@Suite
@SelectPackages({"com.baeldung.testsuite", "com.baeldung.testsuitetwo"})
public class JUnitSelectPackagesSuite {
}

✅ 自动包含子包中的所有测试类

3.3. @IncludePackages 和 @ExcludePackages

在包扫描基础上进一步过滤

@Suite
@SelectPackages("com.baeldung.testsuite")
@IncludePackages("com.baeldung.testsuite.subpackage")
public class JUnitTestIncludePackagesSuite {
}

仅执行 com.baeldung.testsuite.subpackage 中的测试

排除示例:

@Suite
@SelectPackages("com.baeldung.testsuite")
@ExcludePackages("com.baeldung.testsuite.subpackage")
public class JUnitExcludePackagesSuite {
}

✅ 执行 com.baeldung.testsuite 及其子包
跳过 com.baeldung.testsuite.subpackage

3.4. @IncludeClassNamePatterns 和 @ExcludeClassNamePatterns

通过正则表达式过滤类名

@Suite
@SelectPackages("com.baeldung.testsuite")
@IncludeClassNamePatterns("com.baeldung.testsuite.Class.*UnitTest")
@ExcludeClassNamePatterns("com.baeldung.testsuite.ClassTwoUnitTest")
public class JUnitClassNamePatternsSuite {
}

✅ 匹配 Class.*UnitTest 模式(如 ClassOneUnitTest
❌ 严格排除 ClassTwoUnitTest
⚠️ 正则需匹配完整类名(含包路径)

3.5. @IncludeTags 和 @ExcludeTags

基于 @Tag 注解过滤测试

@Suite
@SelectPackages("com.baeldung.testsuite")
@IncludeTags("slow")
public class JUnitTestIncludeTagsSuite {
}

仅执行带 @Tag("slow") 的测试

反向配置:

@Suite
@SelectPackages("com.baeldung.testsuite")
@ExcludeTags("slow")
public class JUnitTestExcludeTagsSuite {
}

✅ 执行所有不带 @Tag("slow") 的测试(包括未标记的)
支持方法级 @Tag 过滤(区别于类级别过滤)

3.6. @SelectMethod

精准选择特定测试方法

@Suite
@SuiteDisplayName("我的测试套件")
@SelectMethod(type = ClassOneUnitTest.class, name = "whenFalse_thenFalse")
@SelectMethod("com.baeldung.testsuite.subpackage.ClassTwoUnitTest#whenFalse_thenFalse")
public class JUnitSelectMethodsSuite {
}

两种指定方式:

  1. type + name 属性组合
  2. 完整类名 + # + 方法名(如示例)

✅ 仅执行选中的 whenFalse_thenFalse() 方法
⚠️ 每个注解只能选择一个方法

4. 总结

JUnit 提供了便捷的测试套件创建能力,支持按逻辑分组、按序执行或条件化运行测试子集。

本文探讨了两种实现方式:

  • 推荐使用 @Suite 注解(现代方案)
  • ❌ 避免使用已废弃的 @RunWith(JUnitPlatform.class)

并通过多种注解实现测试选择:

  • @SelectClasses/@SelectPackages基础范围选择
  • @IncludePackages/@ExcludePackages包级别过滤
  • @IncludeClassNamePatterns/@ExcludeClassNamePatterns类名正则过滤
  • @IncludeTags/@ExcludeTags标签过滤
  • @SelectMethod方法级精准控制

本文示例代码可在 GitHub 获取。


原始标题:Creating a Test Suite With JUnit