cui-java-unit-testing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

CUI Java Unit Testing Skill

CUI Java单元测试技能

Standards and patterns for writing high-quality unit tests in CUI Java projects using JUnit 5, the CUI test generator framework, and value object contract testing.
本文介绍了在CUI Java项目中使用JUnit 5、CUI测试生成器框架和值对象契约测试编写高质量单元测试的标准与模式。

Workflow

工作流程

Step 1: Load Applicable Testing Standards

步骤1:加载适用的测试标准

CRITICAL: Load current testing standards to use as enforcement criteria.
  1. Always load foundational testing standards:
    Read: standards/testing-junit-core.md
    This provides core JUnit 5 patterns, AAA structure, assertion standards, and test organization that are always needed for testing.
  2. Conditional loading based on testing context:
    A. If project uses test data generators (presence of
    de.cuioss.test.generator
    imports or
    @EnableGeneratorController
    ):
    Read: standards/test-generator-framework.md
    Provides comprehensive generator standards including mandatory requirements, all parameterized testing annotations (@GeneratorsSource, @CompositeTypeGeneratorSource, etc.), seed restrictions, anti-patterns, and complete API reference.
    B. If testing value objects (classes with equals/hashCode/toString or annotated with @Value, @Data):
    Read: standards/testing-value-objects.md
    Provides comprehensive contract testing standards using
    ShouldHandleObjectContracts<T>
    interface and proper generator integration.
    C. If testing HTTP clients or APIs (testing code that makes HTTP requests):
    Read: standards/testing-mockwebserver.md
    Provides MockWebServer setup patterns, response mocking, request verification, retry logic testing, and HTTP status code handling.
    D. If writing integration tests (tests that interact with multiple components or external systems):
    Read: standards/integration-testing.md
    Covers Maven surefire/failsafe configuration, integration test naming conventions (*IT.java), profile setup, and CI/CD integration.
    E. If testing applications that use Java Util Logging (JUL) (testing code that uses
    java.util.logging
    or needs to assert log output):
    Read: standards/testing-juli-logger.md
    Provides patterns for configuring test loggers with
    @EnableTestLogger
    , asserting log statements with
    LogAsserts
    , and dynamically changing log levels in tests.
    F. If focusing on test quality or reviewing existing tests (improving test quality, eliminating AI-generated artifacts, or ensuring compliance):
    Read: standards/testing-quality-standards.md
    Provides quality best practices including AI-generated code detection, parameterized test guidelines, assertion message standards, SonarQube compliance, library migration guidelines, and coverage requirements.
  3. Extract key requirements from all loaded standards
  4. Store in working memory for use during task execution
重要提示:加载当前测试标准作为执行准则。
  1. 始终加载基础测试标准
    Read: standards/testing-junit-core.md
    该文档提供了核心JUnit 5模式、AAA结构、断言标准以及测试组织方式,是所有测试都需要遵循的内容。
  2. 根据测试上下文条件加载
    A. 如果项目使用测试数据生成器(存在
    de.cuioss.test.generator
    导入或
    @EnableGeneratorController
    注解):
    Read: standards/test-generator-framework.md
    该文档提供了全面的生成器标准,包括强制要求、所有参数化测试注解(@GeneratorsSource、@CompositeTypeGeneratorSource等)、种子限制、反模式以及完整的API参考。
    B. 如果测试值对象(包含equals/hashCode/toString方法或标注了@Value、@Data注解的类):
    Read: standards/testing-value-objects.md
    该文档提供了使用
    ShouldHandleObjectContracts<T>
    接口进行全面契约测试的标准,以及生成器的正确集成方式。
    C. 如果测试HTTP客户端或API(测试发起HTTP请求的代码):
    Read: standards/testing-mockwebserver.md
    该文档提供了MockWebServer的设置模式、响应模拟、请求验证、重试逻辑测试以及HTTP状态码处理方式。
    D. 如果编写集成测试(与多个组件或外部系统交互的测试):
    Read: standards/integration-testing.md
    涵盖Maven surefire/failsafe配置、集成测试命名约定(*IT.java)、配置文件设置以及CI/CD集成。
    E. 如果测试使用Java Util Logging (JUL)的应用(测试使用
    java.util.logging
    或需要断言日志输出的代码):
    Read: standards/testing-juli-logger.md
    提供了使用
    @EnableTestLogger
    配置测试日志记录器、使用
    LogAsserts
    断言日志语句以及在测试中动态更改日志级别的模式。
    F. 如果关注测试质量或评审现有测试(提升测试质量、消除AI生成的冗余代码或确保合规性):
    Read: standards/testing-quality-standards.md
    提供了质量最佳实践,包括AI生成代码检测、参数化测试指南、断言消息标准、SonarQube合规性、库迁移指南以及覆盖率要求。
  3. 从所有加载的标准中提取关键要求
  4. 存储到工作内存中,以便在任务执行时使用

Step 2: Analyze Existing Tests (if applicable)

步骤2:分析现有测试(如适用)

If working with existing tests:
  1. Identify current test structure:
    • Check test class organization and naming
    • Review test method structure (AAA pattern compliance)
    • Examine assertion usage and messages
    • Identify parameterized test opportunities
  2. Assess CUI framework compliance:
    • Verify
      @EnableGeneratorController
      usage where needed
    • Check for prohibited libraries (Mockito, Hamcrest, PowerMock)
    • Validate generator usage for all test data
    • Confirm value object contract testing where applicable
  3. Review test quality:
    • Check assertion message quality (meaningful, concise)
    • Verify test independence and isolation
    • Assess test naming and @DisplayName usage
    • Identify potential test consolidation opportunities
    • Detect AI-generated code artifacts (see testing-quality-standards.md for indicators)
如果处理现有测试:
  1. 识别当前测试结构
    • 检查测试类的组织和命名
    • 评审测试方法结构(是否符合AAA模式)
    • 检查断言的使用和消息
    • 识别参数化测试的适用场景
  2. 评估CUI框架合规性
    • 验证在需要的地方是否使用了
      @EnableGeneratorController
    • 检查是否使用了禁用的库(Mockito、Hamcrest、PowerMock)
    • 验证所有测试数据是否使用了生成器
    • 确认在适用的地方是否进行了值对象契约测试
  3. 评审测试质量
    • 检查断言消息的质量(有意义、简洁)
    • 验证测试的独立性和隔离性
    • 评估测试命名和@DisplayName的使用
    • 识别潜在的测试合并机会
    • 检测AI生成的代码冗余(参考testing-quality-standards.md中的指标)

Step 3: Write/Modify Tests According to Standards

步骤3:根据标准编写/修改测试

When writing or modifying tests:
  1. Apply core JUnit 5 standards:
    • Use AAA pattern (Arrange-Act-Assert)
    • Include meaningful assertion messages (20-60 characters)
    • Use @DisplayName for readable test descriptions
    • Follow test independence principles
    • Apply proper exception testing with assertThrows
  2. Use CUI test generator for all data (if applicable):
    • Add @EnableGeneratorController to test classes
    • Replace manual data creation with Generators.* calls
    • Use @GeneratorsSource for parameterized tests (3+ similar variants)
    • Never commit @GeneratorSeed annotations (debugging only)
    • Combine generators for complex object creation
  3. Implement value object contract testing (if applicable):
    • Apply ShouldHandleObjectContracts<T> interface
    • Implement getUnderTest() using generators
    • Verify equals/hashCode/toString contracts
    • Separate contract tests from business logic tests
  4. Configure HTTP mocking (if applicable):
    • Use @EnableMockWebServer annotation
    • Enqueue mock responses before requests
    • Verify request headers, body, and parameters
    • Test various status codes and error scenarios
    • Combine with generators for comprehensive testing
  5. Set up integration tests (if applicable):
    • Name tests with *IT.java or *ITCase.java suffix
    • Configure Maven failsafe plugin
    • Create integration-tests profile
    • Ensure proper test separation
编写或修改测试时:
  1. 应用核心JUnit 5标准
    • 使用AAA模式(Arrange-Act-Assert,准备-执行-断言)
    • 包含有意义的断言消息(20-60个字符)
    • 使用@DisplayName提供易读的测试描述
    • 遵循测试独立性原则
    • 使用assertThrows进行正确的异常测试
  2. 使用CUI测试生成器处理所有数据(如适用):
    • 为测试类添加@EnableGeneratorController注解
    • 用Generators.*调用替代手动创建数据
    • 对参数化测试使用@GeneratorsSource(3个及以上相似变体)
    • 禁止提交@GeneratorSeed注解(仅用于调试)
    • 组合生成器以创建复杂对象
  3. 实现值对象契约测试(如适用):
    • 应用ShouldHandleObjectContracts<T>接口
    • 使用生成器实现getUnderTest()方法
    • 验证equals/hashCode/toString契约
    • 将契约测试与业务逻辑测试分离
  4. 配置HTTP模拟(如适用):
    • 使用@EnableMockWebServer注解
    • 在发起请求前入队模拟响应
    • 验证请求头、请求体和参数
    • 测试各种状态码和错误场景
    • 结合生成器进行全面测试
  5. 设置集成测试(如适用):
    • 测试命名使用IT.java或ITCase.java后缀
    • 配置Maven failsafe插件
    • 创建integration-tests配置文件
    • 确保测试正确分离

Step 4: Verify Test Quality

步骤4:验证测试质量

Before completing the task:
  1. Verify standards compliance:
    • All tests follow AAA pattern
    • All assertions have meaningful messages
    • Test independence verified (tests don't depend on each other)
    • Proper @DisplayName usage
    • No prohibited libraries used
  2. Verify CUI framework usage (if applicable):
    • @EnableGeneratorController present where needed
    • All test data uses Generators.* (no manual creation)
    • No @GeneratorSeed annotations committed
    • Value object contracts implemented correctly
    • MockWebServer setup follows patterns
  3. Run tests and verify success:
    # Run unit tests
    Task:
      subagent_type: maven-builder
      description: Run unit tests
      prompt: |
        Execute unit tests only.
    
        Parameters:
        - command: clean test
    
        CRITICAL: Wait for tests to complete. Inspect results and fix any failures.
    
    # Run integration tests (if applicable)
    Task:
      subagent_type: maven-builder
      description: Run integration tests
      prompt: |
        Execute integration tests with the integration-tests profile.
    
        Parameters:
        - command: clean verify -Pintegration-tests
    
        CRITICAL: Wait for tests to complete. Inspect results and fix any failures.
    
    # Verify coverage
    Task:
      subagent_type: maven-builder
      description: Verify test coverage
      prompt: |
        Execute tests with coverage analysis using the coverage profile.
    
        Parameters:
        - command: clean verify -Pcoverage
    
        CRITICAL: Wait for build to complete. Inspect coverage results and ensure
        minimum 80% line/branch coverage is met. Address any coverage gaps.
  4. Check coverage requirements:
    • Minimum 80% line coverage
    • Minimum 80% branch coverage
    • Critical paths have 100% coverage
    • All public APIs tested
完成任务前:
  1. 验证标准合规性
    • 所有测试遵循AAA模式
    • 所有断言都有有意义的消息
    • 验证测试独立性(测试之间无依赖)
    • 正确使用@DisplayName
    • 未使用禁用的库
  2. 验证CUI框架使用情况(如适用):
    • 在需要的地方存在@EnableGeneratorController
    • 所有测试数据使用Generators.*(无手动创建)
    • 未提交@GeneratorSeed注解
    • 值对象契约实现正确
    • MockWebServer设置符合模式
  3. 运行测试并验证通过
    # 运行单元测试
    Task:
      subagent_type: maven-builder
      description: Run unit tests
      prompt: |
        Execute unit tests only.
    
        Parameters:
        - command: clean test
    
        CRITICAL: Wait for tests to complete. Inspect results and fix any failures.
    
    # 运行集成测试(如适用)
    Task:
      subagent_type: maven-builder
      description: Run integration tests
      prompt: |
        Execute integration tests with the integration-tests profile.
    
        Parameters:
        - command: clean verify -Pintegration-tests
    
        CRITICAL: Wait for tests to complete. Inspect results and fix any failures.
    
    # 验证覆盖率
    Task:
      subagent_type: maven-builder
      description: Verify test coverage
      prompt: |
        Execute tests with coverage analysis using the coverage profile.
    
        Parameters:
        - command: clean verify -Pcoverage
    
        CRITICAL: Wait for build to complete. Inspect coverage results and ensure
        minimum 80% line/branch coverage is met. Address any coverage gaps.
  4. 检查覆盖率要求
    • 最低80%行覆盖率
    • 最低80%分支覆盖率
    • 关键路径达到100%覆盖率
    • 所有公开API都经过测试

Step 5: Report Results

步骤5:报告结果

Provide summary of:
  1. Tests created/modified: List test classes and methods
  2. Standards applied: Which standards were followed
  3. Framework features used: Generators, value object contracts, MockWebServer, etc.
  4. Coverage metrics: Current coverage percentages
  5. Any deviations: Document and justify any standard deviations
提供以下内容的总结:
  1. 创建/修改的测试:列出测试类和方法
  2. 应用的标准:遵循了哪些标准
  3. 使用的框架特性:生成器、值对象契约、MockWebServer等
  4. 覆盖率指标:当前覆盖率百分比
  5. 任何偏差:记录并说明任何标准偏差的原因

Quality Verification

质量验证

Test Execution Checklist

测试执行检查清单

  • All new/modified tests pass
  • Tests are independent (can run in any order)
  • No flaky tests (consistent results)
  • Fast execution (unit tests < 1 second each)
  • Proper cleanup in @AfterEach if needed
  • 所有新增/修改的测试都通过
  • 测试是独立的(可以按任意顺序运行)
  • 无不稳定测试(结果一致)
  • 执行速度快(每个单元测试耗时<1秒)
  • 如有需要,在@AfterEach中进行适当的清理

Code Quality Checklist

代码质量检查清单

  • No hardcoded test data (use generators)
  • No prohibited testing libraries
  • Assertion messages are meaningful and concise
  • Test names clearly describe behavior
  • No commented-out code
  • No @GeneratorSeed annotations
  • 无硬编码测试数据(使用生成器)
  • 无禁用的测试库
  • 断言消息有意义且简洁
  • 测试名称清晰描述行为
  • 无注释掉的代码
  • 无@GeneratorSeed注解

Coverage Verification

覆盖率验证

  • Run coverage profile using maven-builder agent with -Pcoverage
  • Coverage meets minimum requirements (80% line/branch)
  • Critical paths have 100% coverage
  • No coverage regressions from previous state
  • 使用maven-builder agent并添加-Pcoverage参数运行覆盖率配置文件
  • 覆盖率达到最低要求(80%行/分支覆盖率)
  • 关键路径达到100%覆盖率
  • 相比之前的状态,覆盖率没有下降

Common Patterns and Examples

常见模式与示例

Basic Unit Test Pattern

基础单元测试模式

java
@EnableGeneratorController
@DisplayName("Token Validator Tests")
class TokenValidatorTest {

    @Test
    @DisplayName("Should validate token with correct issuer")
    void shouldValidateTokenWithCorrectIssuer() {
        // Arrange
        String issuer = Generators.strings().next();
        Token token = createTokenWithIssuer(issuer);
        TokenValidator validator = new TokenValidator(issuer);

        // Act
        ValidationResult result = validator.validate(token);

        // Assert
        assertTrue(result.isValid(), "Token with correct issuer should be valid");
    }
}
java
@EnableGeneratorController
@DisplayName("Token Validator Tests")
class TokenValidatorTest {

    @Test
    @DisplayName("Should validate token with correct issuer")
    void shouldValidateTokenWithCorrectIssuer() {
        // Arrange
        String issuer = Generators.strings().next();
        Token token = createTokenWithIssuer(issuer);
        TokenValidator validator = new TokenValidator(issuer);

        // Act
        ValidationResult result = validator.validate(token);

        // Assert
        assertTrue(result.isValid(), "Token with correct issuer should be valid");
    }
}

Value Object Contract Test Pattern

值对象契约测试模式

java
@EnableGeneratorController
class UserDataTest implements ShouldHandleObjectContracts<UserData> {

    @Override
    public UserData getUnderTest() {
        return UserData.builder()
            .username(Generators.strings().next())
            .email(Generators.emailAddress().next())
            .age(Generators.integers(18, 100).next())
            .build();
    }
}
java
@EnableGeneratorController
class UserDataTest implements ShouldHandleObjectContracts<UserData> {

    @Override
    public UserData getUnderTest() {
        return UserData.builder()
            .username(Generators.strings().next())
            .email(Generators.emailAddress().next())
            .age(Generators.integers(18, 100).next())
            .build();
    }
}

Parameterized Test Pattern

参数化测试模式

java
@EnableGeneratorController
class ParameterizedValidationTest {

    @ParameterizedTest
    @DisplayName("Should validate various email formats")
    @GeneratorsSource(generator = GeneratorType.DOMAIN_EMAIL, count = 5)
    void shouldValidateEmailFormats(String email) {
        assertTrue(validator.isValidEmail(email),
            "Generated email should be valid");
    }
}
java
@EnableGeneratorController
class ParameterizedValidationTest {

    @ParameterizedTest
    @DisplayName("Should validate various email formats")
    @GeneratorsSource(generator = GeneratorType.DOMAIN_EMAIL, count = 5)
    void shouldValidateEmailFormats(String email) {
        assertTrue(validator.isValidEmail(email),
            "Generated email should be valid");
    }
}

HTTP Testing Pattern

HTTP测试模式

java
@EnableMockWebServer
@EnableGeneratorController
class HttpClientTest {

    @InjectMockWebServer
    private MockWebServerHolder serverHolder;

    @Test
    @DisplayName("Should successfully fetch user data")
    void shouldFetchUserData() throws Exception {
        // Arrange
        String userName = Generators.strings().next();
        serverHolder.enqueue(new MockResponse()
            .setResponseCode(200)
            .setBody(String.format("{\"name\": \"%s\"}", userName)));

        // Act
        User user = client.getUser(serverHolder.getBaseUrl(), 1);

        // Assert
        assertNotNull(user, "Response should not be null");
        assertEquals(userName, user.getName(), "User name should match");
    }
}
java
@EnableMockWebServer
@EnableGeneratorController
class HttpClientTest {

    @InjectMockWebServer
    private MockWebServerHolder serverHolder;

    @Test
    @DisplayName("Should successfully fetch user data")
    void shouldFetchUserData() throws Exception {
        // Arrange
        String userName = Generators.strings().next();
        serverHolder.enqueue(new MockResponse()
            .setResponseCode(200)
            .setBody(String.format("{\"name\": \"%s\"}", userName)));

        // Act
        User user = client.getUser(serverHolder.getBaseUrl(), 1);

        // Assert
        assertNotNull(user, "Response should not be null");
        assertEquals(userName, user.getName(), "User name should match");
    }
}

Error Handling

错误处理

If encountering issues:
  1. Test failures: Review assertion messages and debug failing tests
  2. Coverage gaps: Identify untested code paths and add tests
  3. Framework errors: Verify @EnableGeneratorController and dependencies
  4. Maven build issues: Check surefire/failsafe configuration
  5. Integration test problems: Verify profile configuration and naming conventions
如果遇到问题:
  1. 测试失败:查看断言消息并调试失败的测试
  2. 覆盖率缺口:识别未测试的代码路径并添加测试
  3. 框架错误:验证@EnableGeneratorController和依赖项
  4. Maven构建问题:检查surefire/failsafe配置
  5. 集成测试问题:验证配置文件配置和命名约定

References

参考资料

  • Core Testing Standards: standards/testing-junit-core.md
  • Value Object Testing: standards/testing-value-objects.md
  • Generator Usage: standards/testing-generators.md
  • MockWebServer Testing: standards/testing-mockwebserver.md
  • Integration Testing: standards/integration-testing.md
  • JULi Logger Testing: standards/testing-juli-logger.md
  • 核心测试标准:standards/testing-junit-core.md
  • 值对象测试:standards/testing-value-objects.md
  • 生成器使用:standards/testing-generators.md
  • MockWebServer测试:standards/testing-mockwebserver.md
  • 集成测试:standards/integration-testing.md
  • JULi日志测试:standards/testing-juli-logger.md