# 测试规范 ## 概述 本规范基于项目现有代码实现,定义了单元测试和集成测试的设计原则和标准。项目目前尚未编写测试代码,本规范为未来测试开发提供指导。 ## 基本原则 1. **测试驱动开发**:优先编写测试代码,再实现业务逻辑。 2. **测试覆盖**:确保核心业务逻辑有足够的测试覆盖。 3. **独立性**:每个测试用例应独立运行,不依赖其他测试。 4. **可读性**:测试代码应清晰易懂,便于维护。 ## 测试框架 - **单元测试**:使用JUnit 5作为测试框架。 - **集成测试**:使用Spring Boot Test进行集成测试。 - **Mock框架**:使用Mockito进行依赖注入的模拟。 ### 当前项目情况 - 当前 `pom.xml` 中 **未** 包含常用的测试依赖(如 `spring-boot-starter-test`/`junit-jupiter`/`mockito`)。因此仓库内 `src/test/java` 目录目前为空。 - 建议在 `pom.xml` 中添加以下依赖以开启测试能力: ```xml org.springframework.boot spring-boot-starter-test test org.junit.jupiter junit-jupiter 5.9.2 test ``` 添加这些依赖后,建议在本地或 CI 中运行 `mvn test` 并生成 coverage 报告(如使用 JaCoCo)。 ## 测试结构 1. **测试类命名**:测试类以被测类名 + "Test" 命名,例如 `UserServiceTest`。 2. **测试方法命名**:使用描述性名称,遵循 `should_When_Then` 或 `test_方法名_场景` 格式。 3. **测试文件位置**:测试文件放置在 `src/test/java` 目录下,与主代码保持相同的包结构。 ## 单元测试规范 1. **测试范围**:主要测试Service层、Util类等业务逻辑。 2. **Mock依赖**:使用Mockito模拟外部依赖,如Mapper、外部服务。 3. **断言**:使用AssertJ或JUnit的断言方法进行结果验证。 ## 集成测试规范 1. **测试范围**:测试Controller层、数据库操作等。 2. **测试环境**:使用@SpringBootTest注解启动完整应用上下文。 3. **数据库测试**:使用H2内存数据库或Testcontainers进行数据库测试。 ## 测试数据 1. **测试数据准备**:在测试方法中使用@BeforeEach准备测试数据。 2. **数据清理**:在测试方法中使用@AfterEach清理测试数据。 3. **数据隔离**:确保测试数据不影响其他测试。 ## 测试运行 1. **Maven命令**:使用 `mvn test` 运行所有测试。 2. **IDE集成**:在IDE中直接运行测试类或方法。 3. **CI/CD集成**:在构建过程中自动运行测试。 ## 代码覆盖率 1. **覆盖率工具**:使用JaCoCo生成测试覆盖率报告。 2. **覆盖率目标**:核心业务代码覆盖率不低于80%。 3. **覆盖率检查**:在CI/CD中设置覆盖率阈值检查。 ## 注意事项 - 测试代码应与生产代码一同维护。 - 避免在测试中使用硬编码的外部依赖。 - 定期review测试代码,确保其有效性。 ### API 文档与契约测试(补充) 目的:确保生成的 Swagger/OpenAPI 文档正确地体现接口契约,尤其是当接口返回泛型包装类(如 `R`、分页 `Page`)时,文档应显示具体字段结构。 建议测试项: - 文档结构断言:使用集成测试在 `/v3/api-docs` 或 Knife4j 的 JSON 输出上断言特定接口的 schema 中包含预期字段(例如断言某接口的 `data` 类型为 `CheckUserBindingResponse` 的 schema)。 - 注解覆盖验证:在变更 Controller 的返回类型或 VO 后,运行文档生成并比对变更,确保 `@ApiResponse` / `@Schema` 注解的声明能被正确解析。 - CI 校验:把对 `/v3/api-docs` 的基本断言纳入 CI(如果团队接受),避免接口实现与文档脱节。 示例(测试思路): 1. 启动应用上下文并请求 `/v3/api-docs`,获取 JSON。 2. 解析 JSON,定位目标接口的 responses -> 200 -> content -> application/json -> schema -> $ref,并解析该 schema 对应的定义。 3. 断言 schema 定义中列出了预期字段,例如 `exists`、`bindingType` 等。 ### 关于长整型 ID 的测试 目的:验证 API 在面对超过 JavaScript 安全整数范围(> 2^53-1)的 ID 时,前端与后端之间不会因为精度丢失而导致 CRUD 操作失败或数据不一致。 建议测试项: - 接口契约测试:断言返回的 `id` 字段在 JSON 中为字符串类型(例如使用 MockMvc / RestAssured 检查 JSON schema)。 - 集成测试(Controller -> Service -> Mapper):创建一条使用雪花算法生成的 ID(或模拟一个大于 2^53-1 的 ID),确保返回的 DTO 中 `id` 为字符串且值为 `record.getId().toString()`。 - 更新/删除端到端测试:前端(或测试脚本)以字符串形式传递 ID 时,后端能正确解析并执行对应操作(请求参数仍可用 Long,或后端先尝试解析字符串为 Long)。 - 边界测试:使用最大/最小 Long 值、以及接收非法字符串(非数字)时的错误处理与返回码。 示例(伪测试步骤): 1. 插入记录并获取数据库生成的 Long ID(例如:9223372036854775807 或任意大于 JS 安全整数的值)。 2. 调用查询接口,断言响应 JSON 中 `id` 为字符串且等于数据库 ID 的字符串表示。 3. 调用删除接口,传入字符串形式的 ID,断言操作成功并且数据库记录被删除。