1. 概述
在 CI 构建流程中,我们通常会使用 Maven 自动执行所有 JUnit 测试。但这种方式往往比较耗时。
因此,我们经常需要对测试进行过滤,在构建的不同阶段执行单元测试、集成测试或两者兼顾。
在本文中,我们将重点介绍 JUnit 5 提供的标签(Tag)机制,以及在 JUnit 5 之前的分类(Category)机制。我们还将介绍通过 Maven Surefire 插件进行测试过滤的实践方法。
2. JUnit 5 标签机制
2.1. 使用 @Tag
注解标记测试
JUnit 5 提供了 @Tag
注解,允许我们为测试类或方法打上标签,从而实现分类管理。例如:
@Test
@Tag("IntegrationTest")
public void testAddEmployeeUsingSimpelJdbcInsert() {
}
@Test
@Tag("UnitTest")
public void givenNumberOfEmployeeWhenCountEmployeeThenCountMatch() {
}
✅ 优点:灵活标记单个测试方法或整个测试类,便于后续筛选执行。
2.2. 使用测试套件过滤标签
JUnit 5 支持通过测试套件(Test Suite)来执行特定标签下的测试:
@SelectPackages("com.baeldung.tags")
@IncludeTags("UnitTest")
public class EmployeeDAOUnitTestSuite {
}
运行这个测试套件时,只会执行带有 @Tag("UnitTest")
的测试方法。
也可以使用 @ExcludeTags
排除某些标签的测试:
@SelectPackages("com.baeldung.tags")
@ExcludeTags("IntegrationTest")
public class EmployeeDAOUnitTestSuite {
}
⚠️ 注意:测试套件类不需要包含任何实际测试方法。
2.3. 使用 Maven Surefire 插件过滤标签
在 Maven 构建过程中,我们可以通过 Surefire 插件配置来过滤标签:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<groups>UnitTest</groups>
</configuration>
</plugin>
也可以排除特定标签:
<excludedGroups>IntegrationTest</excludedGroups>
✅ 优点:适用于 CI 构建环境,可灵活配置不同构建阶段执行不同标签的测试。
2.4. 使用 IDE 过滤标签
现代 IDE(如 IntelliJ IDEA 和 Eclipse)也支持通过标签过滤测试。
IntelliJ IDEA 示例:
在 Run/Debug 配置中,选择测试类型为 Tags,并填写 Tag Expression,例如:
!IntegrationTest
表示排除集成测试UnitTest | IntegrationTest
表示同时运行单元和集成测试
Eclipse 示例:
3. JUnit 4 分类机制
3.1. 使用 @Category
注解分类测试
JUnit 4 中通过 @Category
注解实现测试分类,其核心思想是使用标记接口(Marker Interface)来定义分类:
public interface UnitTest {
}
public interface IntegrationTest {
}
然后通过 @Category
注解将测试方法或类归类:
@Test
@Category(IntegrationTest.class)
public void testAddEmployeeUsingSimpelJdbcInsert() {
}
@Test
@Category(UnitTest.class)
public void givenNumberOfEmployeeWhenCountEmployeeThenCountMatch() {
}
✅ 优点:结构清晰,适合在 JUnit 4 中进行测试分类管理。
3.2. 使用 Categories
测试套件
JUnit 4 提供了 Categories
Runner 来执行特定分类的测试:
@RunWith(Categories.class)
@IncludeCategory(UnitTest.class)
@SuiteClasses(EmployeeDAOCategoryIntegrationTest.class)
public class EmployeeDAOUnitTestSuite {
}
也可以排除某个分类:
@RunWith(Categories.class)
@ExcludeCategory(IntegrationTest.class)
@SuiteClasses(EmployeeDAOCategoryIntegrationTest.class)
public class EmployeeDAOUnitTestSuite {
}
⚠️ 注意:@SuiteClasses
中必须包含目标测试类。
3.3. 在 Maven 中包含或排除分类
我们也可以在 Maven 构建中通过 Surefire 插件控制测试分类:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<groups>com.baeldung.categories.UnitTest</groups>
</configuration>
</plugin>
排除分类:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<excludedGroups>com.baeldung.categories.IntegrationTest</excludedGroups>
</configuration>
</plugin>
✅ 技巧:配合 Maven Profiles 可实现不同环境执行不同分类的测试。
4. 使用 Maven Surefire 插件进行命名过滤
除了使用 JUnit 自带的分类/标签机制,还可以通过命名约定来过滤测试类。例如:
- 单元测试类名以
*Test.java
结尾 - 集成测试类名以
*IntegrationTest.java
结尾
然后在 Surefire 插件中配置过滤规则:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<excludes>
**/*IntegrationTest.java
</excludes>
</configuration>
</plugin>
✅ 优点:无需修改测试代码,只需规范类名即可实现过滤。
⚠️ 注意:虽然 Surefire 插件可用于集成测试,但更推荐使用 Maven Failsafe Plugin 来执行集成测试。
5. 总结
本文介绍了以下三种 JUnit 测试过滤方式:
- ✅ JUnit 5 标签机制:使用
@Tag
注解 + 测试套件或 Maven Surefire 插件 - ✅ JUnit 4 分类机制:使用
@Category
注解 +Categories
Runner 或 Maven Surefire 插件 - ✅ Maven Surefire 插件命名过滤:基于类名后缀进行测试筛选
📌 推荐做法:
- 如果使用 JUnit 5,优先使用
@Tag
实现灵活标签管理 - 如果仍在使用 JUnit 4,可使用
@Category
进行分类管理 - 对于 CI 构建阶段,结合 Surefire/Failsafe 插件配置更高效
通过合理使用这些机制,可以显著提升测试效率,减少构建时间,避免不必要的测试重复执行。