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 {
}
两种指定方式:
type
+name
属性组合- 完整类名 +
#
+ 方法名(如示例)
✅ 仅执行选中的 whenFalse_thenFalse()
方法
⚠️ 每个注解只能选择一个方法
4. 总结
JUnit 提供了便捷的测试套件创建能力,支持按逻辑分组、按序执行或条件化运行测试子集。
本文探讨了两种实现方式:
- ✅ 推荐使用
@Suite
注解(现代方案) - ❌ 避免使用已废弃的
@RunWith(JUnitPlatform.class)
并通过多种注解实现测试选择:
@SelectClasses
/@SelectPackages
:基础范围选择@IncludePackages
/@ExcludePackages
:包级别过滤@IncludeClassNamePatterns
/@ExcludeClassNamePatterns
:类名正则过滤@IncludeTags
/@ExcludeTags
:标签过滤@SelectMethod
:方法级精准控制
本文示例代码可在 GitHub 获取。