# sample-junit **Repository Path**: souco/sample-junit ## Basic Information - **Project Name**: sample-junit - **Description**: 各个版本 junit 使用示例 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-20 - **Last Updated**: 2025-11-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # JUnit 3 / 4 / 5 / 6 功能特性对比总览 代码仓库:[https://gitee.com/souco/sample-junit](https://gitee.com/souco/sample-junit) --- ## 1. 基础结构与生命周期 | 特性 | JUnit 3 | JUnit 4 | JUnit 5 (Jupiter) | JUnit 6 | 支持方式 / 差异说明 | |------|--------------------------|---------|-------------------|---------|---------------------| | 基本测试类命名 | 继承 TestCase;方法名以 test 开头 | 任意类;方法用 @Test | 任意类;方法用 @Test | 任意类;方法用 @Test | 4/5/6 不再强制继承或命名约定 | | 断言 | Assert (继承) | org.junit.Assert (静态), Hamcrest (4.x+ 常用) | org.junit.jupiter.api.Assertions, 可引入 AssertJ 等 | 增强的断言 API | 5/6 拓展断言 API(assertAll, assertThrows 等) | | 生命周期:全局 | setUp()/tearDown() (实例级) | @Before @After (实例级); @BeforeClass @AfterClass (static) | @BeforeEach @AfterEach; @BeforeAll @AfterAll (可非 static: 若 PER_CLASS) | 增强的生命周期管理 | 5/6 更灵活;支持实例生命周期配置 | | 测试实例生命周期 | 每个测试新实例 | 每个测试新实例 | 默认每个测试新实例;可 @TestInstance(PER_CLASS) | @TestInstance 增强配置 | 5/6 可减少重复初始化开销 | | 忽略/禁用测试 | 无内置 | @Ignore | @Disabled / 条件化禁用 | 增强的条件化禁用 | 5/6 引入条件执行体系 | | 预期异常 | try-catch | @Test(expected=...) | assertThrows / assertDoesNotThrow | 增强的异常处理 | 5/6 放弃注解 expected,更精细控制 | | 超时 | 自行实现 | @Test(timeout=...);@Rule Timeout | @Timeout 注解;assertTimeout / assertTimeoutPreemptively | 增强的超时控制 | 5/6 提供断言级控制 | | 分组/套件 | TestSuite 手工组合 | @RunWith(Suite.class) @SuiteClasses | @Suite (Platform suite engine) | Platform Suite Engine | 5/6 通过 Platform 统一 | | Java 版本要求 | Java 1.3+ | Java 5+ | Java 8+ | **Java 17+** | 6 利用 Java 17+ 新特性 | --- ## 2. 组织与标签、条件 | 特性 | JUnit 3 | JUnit 4 | JUnit 5 | JUnit 6 | 支持方式 / 差异说明 | |------|---------|---------|---------|---------|---------------------| | 标签/分类 | 无 | @Category | @Tag | 增强的 @Tag | 5/6 标签任意字符串;过滤统一 | | 条件执行(OS/JRE/Env) | 无 | 第三方/Assume | @EnabledOnOs/@DisabledOnOs 等 | 增强的条件注解 | 5/6 原生条件注解体系 | | 假设(Assumptions) | 无 | org.junit.Assume.* | org.junit.jupiter.api.Assumptions.* | 增强的假设支持 | Skip 而非 Fail | | 嵌套测试 | 无 | 内部类 + Runner 较繁琐 | @Nested | 增强的嵌套测试 | 5/6 原生嵌套生命周期 | | 自定义显示名称 | 方法名固定 | 部分 Runner | @DisplayName; @DisplayNameGeneration | 增强的名称生成 | 5/6 改善报告 | | 测试排序 | TestSuite 顺序 | @FixMethodOrder | @TestMethodOrder + @Order | 增强的排序控制 | 5/6 可自定义排序器 | --- ## 3. 参数化与动态测试 | 特性 | JUnit 3 | JUnit 4 | JUnit 5 | JUnit 6 | 支持方式 / 差异说明 | |------|---------|---------|---------|---------|---------------------| | 参数化测试 | 手工循环 | @RunWith(Parameterized.class) | @ParameterizedTest + 多种 Source | 增强的参数化 | 5/6 无 Runner 冲突 | | 自定义参数源 | 手工 | @Parameters 方法 | @MethodSource / @ArgumentsSource / ParameterResolver | 增强的参数源 | 5/6 模块化 | | 动态测试 | 手工 suite | 不支持(需自定义 Runner) | @TestFactory + DynamicTest | 增强的动态测试 | 5/6 运行期生成 | | 重复测试 | 手写循环 | 手写循环 | @RepeatedTest | 增强的重复测试 | 5/6 原生统计 | | 依赖注入 (参数解析) | 无 | 无 | 参数解析器 + 内置注入(TestInfo 等) | 增强的依赖注入 | 5/6 可扩展 | --- ## 4. 扩展机制与可插拔性 | 特性 | JUnit 3 | JUnit 4 | JUnit 5 | JUnit 6 | 支持方式 / 差异说明 | |------|---------|---------|---------|---------|---------------------| | 扩展机制核心 | 继承 TestCase | Runner(单一) + Rules + MethodRule | Extension API | 增强的 Extension API | 5/6 统一模型 | | 多扩展组合 | 手工 | Runner 互斥;Rules 可叠加有限 | @ExtendWith 多个;@RegisterExtension | 更灵活的组合 | 5/6 组合灵活 | | 临时文件夹 | 手工 | @Rule TemporaryFolder | @TempDir | 增强的临时文件 | 5/6 更简洁 | | 日志/输出捕获 | 手工 | System Rules(第三方) | 扩展捕获 | 增强的输出捕获 | 5/6 统一 | | 条件化执行扩展 | 手工 | Assume + Rule | ExecutionCondition 接口 | 标准化 + 增强 | 5/6 标准化 | | 自定义标签过滤 | 不便 | Categories | Tags + Launcher Selectors | 平台过滤统一 | 5/6 平台过滤统一 | | 并行执行支持 | 不支持 | 构建工具 | Platform 内置 | 增强的并行执行 | 5/6 原生控制 | --- ## 5. 并行与执行平台 | 特性 | JUnit 3 | JUnit 4 | JUnit 5 | JUnit 6 | 支持方式 / 差异说明 | |------|---------|---------|---------|---------|---------------------| | 并行执行 | 构建工具 | 构建工具 | 平台内置 (junit-platform.properties) | 增强的并行控制 | 5/6 原生控制 | | 引擎抽象 | 无 | 无 | Platform + Engines (Jupiter, Vintage, …) | 增强的引擎支持 | 5/6 运行多框架 | | 选择性发现 | TestSuite | Runner/过滤 | LauncherDiscoveryRequest (selectors, filters) | 可编程增强 | 5/6 可编程 | | IDE 支持 | 基本 | 成熟 | 层级/动态测试可视化 | 增强的 IDE 支持 | 5/6 需 IDE Platform 支持 | | Java 17+ 特性 | 不支持 | 不支持 | 部分 | **完整支持** | 6 利用 Java 17+ 新特性 | | 动态测试生成 | 不支持 | 不支持 | @TestFactory + DynamicTest | 增强的动态测试 | 5/6 运行期生成 | ## 6. 典型替代与升级映射 | 旧用法 (JUnit 4) | 新用法 (JUnit 5) | JUnit 6 增强 | 备注 | |------------------|------------------|---------------|------| | @Before / @After | @BeforeEach / @AfterEach | 增强的生命周期 | 命名语义化 | | @BeforeClass / @AfterClass | @BeforeAll / @AfterAll | @TestInstance 增强配置 | 可非 static (PER_CLASS) | | @Ignore | @Disabled | 增强的条件化禁用 | 功能等价 | | @Category | @Tag | 增强的标签支持 | 字符串自由 | | @Test(expected=...) | assertThrows(...) | 增强的异常处理 | 控制更精准 | | @Test(timeout=...) | @Timeout 或 assertTimeout(...) | 增强的超时控制 | 区分整体与代码块 | | @RunWith(Parameterized.class) | @ParameterizedTest + Sources | 增强的参数化 | 不占 Runner | | Rules (TemporaryFolder) | @TempDir | 增强的临时文件 | 参数或字段 | | Rules (ExpectedException) | assertThrows | 增强的断言 | 直观 | | Rules (ExternalResource) | Extension (Before/After 回调) | 增强的扩展API | 拆分回调接口 | | Runner (Suite) | @Suite (Platform) | Platform Suite Engine | 平台统一 | --- ## 7. JUnit 6 新特性与最佳实践 ### 7.1 JUnit 6 核心新特性 #### 7.1.1 Java 17+ 完整支持 - **语言特性利用**:文本块 (Text Blocks)、Switch 表达式、Pattern Matching - **性能优化**:利用 Java 17 的性能改进和垃圾回收优化 - **Record 类型**:使用不可变数据模型进行测试数据管理 - **增强的 Optional API**:利用 Java 9+ 的 Optional 增强功能 #### 7.1.2 动态测试增强 (@TestFactory) ```java @TestFactory Stream dynamicTestsFromStream() { return Stream.of("a,b", "hello,world") .map(input -> dynamicTest( "concatenate: " + input, () -> assertEquals(expected, actual) )); } ``` #### 7.1.3 并行执行优化 - **动态并行配置**:根据 CPU 核心数自动调整并行度 - **资源锁定**:`@ResourceLock` 确保资源访问的安全性和一致性 - **线程模式**:支持不同的线程执行模式(same_thread, concurrent, separate_thread) #### 7.1.4 条件化执行增强 - **更多条件注解**:`@EnabledIf`、`@DisabledIf` 支持脚本表达式 - **系统属性/环境变量**:更丰富的条件检查选项 - **自定义条件**:可自定义条件检查逻辑 #### 7.1.5 显示名称生成优化 - **自定义生成器**:扩展 `DisplayNameGenerator` 创建自定义命名规则 - **多级嵌套支持**:为嵌套测试提供层次化显示名称 - **国际化支持**:支持多语言显示名称 #### 7.1.6 超时控制增强 - **抢占式超时**:`assertTimeoutPreemptively` 实现真正的超时控制 - **单位灵活性**:支持 TimeUnit 和 Duration 两种时间单位 - **细粒度控制**:方法级别和类级别超时控制 #### 7.1.7 测试实例生命周期配置 - **PER_CLASS 增强配置**:支持非静态的 `@BeforeAll` 和 `@AfterAll` - **共享状态管理**:减少重复初始化,提高测试效率 - **资源优化**:优化昂贵资源的生命周期管理 ### 7.2 JUnit 6 最佳实践 #### 7.2.1 并行执行最佳实践 ```properties # junit-platform.properties junit.jupiter.execution.parallel.enabled=true junit.jupiter.execution.parallel.mode.default=concurrent junit.jupiter.execution.parallel.mode.classes.default=concurrent junit.jupiter.execution.parallel.config.strategy=dynamic ``` #### 7.2.2 条件化执行策略 ```java @Test @EnabledOnJre({JAVA_17, JAVA_18, JAVA_19}) @EnabledOnOs({OS.MAC, OS.LINUX}) @EnabledIfEnvironmentVariable(named = "CI", matches = "true") void should_run_under_multiple_conditions() { // 测试代码 } ``` #### 7.2.3 Java 17+ 特性利用 ```java // 使用文本块进行多行字符串测试 String report = """ 测试报告 ======= 结果: %d """.formatted(result); // 使用 Record 进行测试数据管理 record TestInput(int a, int b, int expected) { @MethodSource("testData") @ParameterizedTest void testAddition(TestInput input) { assertEquals(input.expected(), input.a() + input.b()); } } ``` ### 7.3 JUnit 6 迁移指南 #### 7.3.1 基本迁移步骤 1. **升级 Java 版本**:确保使用 Java 17+ 2. **更新依赖**:使用最新的 JUnit 6 依赖 3. **迁移注解**:将 JUnit 4 注解迁移到 JUnit 6 4. **配置并行**:配置并行执行策略 5. **利用新特性**:采用 Java 17+ 新特性 #### 7.3.2 配置文件设置 ```properties # src/test/resources/junit-platform.properties junit.jupiter.execution.parallel.enabled=true junit.jupiter.execution.parallel.mode.default=concurrent junit.jupiter.execution.parallel.mode.classes.default=concurrent ```