- 添加完整的7步代码检查流程指导 - 包含命名规范、注释标准、代码质量等检查标准 - 提供游戏服务器特殊要求和最佳实践 - 支持NestJS双模式架构和WebSocket实时通信检查 涉及文件: - docs/ai-reading/README.md - 总体执行指南 - docs/ai-reading/step1-naming-convention.md - 命名规范检查 - docs/ai-reading/step2-comment-standard.md - 注释规范检查 - docs/ai-reading/step3-code-quality.md - 代码质量检查 - docs/ai-reading/step4-architecture-layer.md - 架构分层检查 - docs/ai-reading/step5-test-coverage.md - 测试覆盖检查 - docs/ai-reading/step6-documentation.md - 功能文档生成 - docs/ai-reading/step7-code-commit.md - 代码提交规范
11 KiB
11 KiB
步骤5:测试覆盖检查
🎯 检查目标
检查测试文件的完整性和覆盖率,确保严格的一对一测试映射和测试分离。
📋 测试文件存在性检查
需要测试文件的类型
✅ 必须有测试文件:
- *.service.ts # Service类 - 业务逻辑类
- *.controller.ts # Controller类 - 控制器类
- *.gateway.ts # Gateway类 - WebSocket网关类
- *.guard.ts # Guard类 - 守卫类(游戏服务器安全重要)
- *.interceptor.ts # Interceptor类 - 拦截器类(日志监控重要)
- *.middleware.ts # Middleware类 - 中间件类(性能监控重要)
❌ 不需要测试文件:
- *.dto.ts # DTO类 - 数据传输对象
- *.interface.ts # Interface文件 - 接口定义
- *.constants.ts # Constants文件 - 常量定义
- *.config.ts # Config文件 - 配置文件
- *.utils.ts # 简单Utils工具类(复杂工具类需要)
测试文件命名规范
✅ 正确的一对一映射:
src/business/auth/auth.service.ts
src/business/auth/auth.service.spec.ts
src/core/location_broadcast_core/location_broadcast_core.service.ts
src/core/location_broadcast_core/location_broadcast_core.service.spec.ts
src/business/admin/admin.gateway.ts
src/business/admin/admin.gateway.spec.ts
❌ 错误的命名:
src/business/auth/auth_services.spec.ts # 测试多个service,违反一对一原则
src/business/auth/auth_test.spec.ts # 命名不对应
🔥 严格一对一测试映射(重要)
强制要求
- 严格对应:每个测试文件必须严格对应一个源文件
- 禁止多对一:不允许一个测试文件测试多个源文件
- 禁止一对多:不允许一个源文件的测试分散在多个测试文件
- 命名对应:测试文件名必须与源文件名完全对应(除.spec.ts后缀外)
测试范围严格限制
// ✅ 正确:只测试LoginService的功能
// 文件:src/business/auth/login.service.spec.ts
describe('LoginService', () => {
describe('validateUser', () => {
it('should validate user credentials', () => {
// 只测试LoginService.validateUser方法
// 使用Mock隔离UserRepository等外部依赖
});
it('should throw error for invalid credentials', () => {
// 测试异常情况
});
});
describe('generateToken', () => {
it('should generate valid JWT token', () => {
// 只测试LoginService.generateToken方法
});
});
});
// ❌ 错误:在LoginService测试中测试其他服务
describe('LoginService', () => {
it('should integrate with UserRepository', () => {
// 错误:这是集成测试,应该移到test/integration/
});
it('should work with EmailService', () => {
// 错误:测试了EmailService的功能,违反范围限制
});
});
🏗️ 测试分离架构(强制要求)
顶层test目录结构
test/
├── integration/ # 集成测试 - 测试多个模块间的交互
│ ├── auth_integration.spec.ts
│ ├── location_broadcast_integration.spec.ts
│ └── zulip_integration.spec.ts
├── e2e/ # 端到端测试 - 完整业务流程测试
│ ├── user_registration_e2e.spec.ts
│ ├── location_broadcast_e2e.spec.ts
│ └── admin_operations_e2e.spec.ts
├── performance/ # 性能测试 - WebSocket和高并发测试
│ ├── websocket_performance.spec.ts
│ ├── database_performance.spec.ts
│ └── memory_usage.spec.ts
├── property/ # 属性测试 - 基于属性的随机测试
│ ├── admin_property.spec.ts
│ ├── user_validation_property.spec.ts
│ └── position_update_property.spec.ts
└── fixtures/ # 测试数据和工具
├── test_data.ts
└── test_helpers.ts
测试类型分离要求
// ✅ 正确:单元测试只在源文件同目录
// 文件位置:src/business/auth/login.service.spec.ts
describe('LoginService Unit Tests', () => {
// 只测试LoginService的单个方法功能
// 使用Mock隔离所有外部依赖
});
// ✅ 正确:集成测试统一在test/integration/
// 文件位置:test/integration/auth_integration.spec.ts
describe('Auth Integration Tests', () => {
it('should integrate LoginService with UserRepository and TokenService', () => {
// 测试多个模块间的真实交互
});
});
// ✅ 正确:E2E测试统一在test/e2e/
// 文件位置:test/e2e/user_auth_e2e.spec.ts
describe('User Authentication E2E Tests', () => {
it('should handle complete user login flow', () => {
// 端到端完整业务流程测试
});
});
🎮 游戏服务器特殊测试要求
WebSocket Gateway测试
// ✅ 正确:完整的WebSocket测试
// 文件:src/business/location/location_broadcast.gateway.spec.ts
describe('LocationBroadcastGateway', () => {
let gateway: LocationBroadcastGateway;
let mockServer: jest.Mocked<Server>;
beforeEach(async () => {
// 设置Mock服务器和依赖
});
describe('handleConnection', () => {
it('should accept valid WebSocket connection with JWT token', () => {
// 正常连接测试
});
it('should reject connection with invalid JWT token', () => {
// 异常连接测试
});
it('should handle connection when room is at capacity limit', () => {
// 边界情况测试
});
});
describe('handlePositionUpdate', () => {
it('should broadcast position to all room members', () => {
// 实时通信测试
});
it('should validate position data format', () => {
// 数据验证测试
});
});
describe('handleDisconnect', () => {
it('should clean up user resources on disconnect', () => {
// 断开连接测试
});
});
});
双模式服务测试
// ✅ 正确:内存服务测试
// 文件:src/core/users/users_memory.service.spec.ts
describe('UsersMemoryService', () => {
it('should create user in memory storage', () => {
// 测试内存模式特定功能
});
it('should handle concurrent access correctly', () => {
// 测试内存模式并发处理
});
});
// ✅ 正确:数据库服务测试
// 文件:src/core/users/users_database.service.spec.ts
describe('UsersDatabaseService', () => {
it('should create user in database', () => {
// 测试数据库模式特定功能
});
it('should handle database transaction correctly', () => {
// 测试数据库事务处理
});
});
// ✅ 正确:双模式一致性测试(集成测试)
// 文件:test/integration/users_dual_mode_integration.spec.ts
describe('Users Dual Mode Integration', () => {
it('should have identical behavior for user creation', () => {
// 测试两种模式行为一致性
});
});
属性测试(管理员模块)
// ✅ 正确:属性测试
// 文件:test/property/admin_property.spec.ts
import * as fc from 'fast-check';
describe('AdminService Properties', () => {
it('should handle any valid user status update', () => {
fc.assert(fc.property(
fc.integer({ min: 1, max: 1000000 }), // userId
fc.constantFrom(...Object.values(UserStatus)), // status
async (userId, status) => {
try {
const result = await adminService.updateUserStatus(userId, status);
expect(result).toBeDefined();
expect(result.status).toBe(status);
} catch (error) {
expect(error).toBeInstanceOf(NotFoundException || BadRequestException);
}
}
));
});
});
📍 测试文件位置规范
正确位置
✅ 正确:测试文件与源文件同目录
src/business/auth/
├── auth.service.ts
├── auth.service.spec.ts # 单元测试
├── auth.controller.ts
└── auth.controller.spec.ts # 单元测试
src/core/location_broadcast_core/
├── location_broadcast_core.service.ts
└── location_broadcast_core.service.spec.ts
错误位置(必须修正)
❌ 错误:测试文件在单独文件夹
src/business/auth/
├── auth.service.ts
├── auth.controller.ts
└── tests/ # 错误:单独的测试文件夹
├── auth.service.spec.ts # 应该移到上级目录
└── auth.controller.spec.ts
src/business/auth/
├── auth.service.ts
├── auth.controller.ts
└── __tests__/ # 错误:单独的测试文件夹
└── auth.spec.ts # 应该拆分并移到上级目录
🧪 测试执行验证(强制要求)
测试命令执行
# 单元测试(严格限制:只执行.spec.ts文件)
npm run test:unit
# 等价于: jest --testPathPattern=spec.ts --testPathIgnorePatterns="integration|e2e|performance|property"
# 集成测试(统一在test/integration/目录执行)
npm run test:integration
# 等价于: jest test/integration/
# E2E测试(统一在test/e2e/目录执行)
npm run test:e2e
# 等价于: jest test/e2e/
# 属性测试(统一在test/property/目录执行)
npm run test:property
# 等价于: jest test/property/
# 性能测试(统一在test/performance/目录执行)
npm run test:performance
# 等价于: jest test/performance/
测试执行顺序
- 第一阶段:单元测试(快速反馈)
- 第二阶段:集成测试(模块协作)
- 第三阶段:E2E测试(业务流程)
- 第四阶段:性能测试(系统性能)
🔍 检查执行步骤
-
扫描需要测试的文件类型
- 识别所有.service.ts、.controller.ts、.gateway.ts等文件
- 检查是否有对应的.spec.ts测试文件
-
验证一对一测试映射
- 确保每个测试文件严格对应一个源文件
- 检查测试文件命名是否正确对应
-
检查测试范围限制
- 确保测试内容严格限于对应源文件功能
- 识别跨文件测试和混合测试
-
检查测试文件位置
- 确保单元测试与源文件在同一目录
- 识别需要扁平化的测试文件夹
-
分离集成测试和E2E测试
- 将集成测试移动到test/integration/
- 将E2E测试移动到test/e2e/
- 将性能测试移动到test/performance/
- 将属性测试移动到test/property/
-
执行测试验证
- 运行单元测试命令验证通过
- 确保测试覆盖率达标
- 验证测试质量和有效性
-
游戏服务器特殊检查
- WebSocket Gateway的完整测试覆盖
- 双模式服务的一致性测试
- 属性测试的正确实现
🔥 重要提醒
如果在本步骤中执行了任何修改操作(创建测试文件、移动测试文件、修正测试内容等),必须立即重新执行步骤5的完整检查!
- ✅ 执行修改 → 🔥 立即重新执行步骤5 → 提供验证报告 → 等待用户确认
- ❌ 执行修改 → 直接进入步骤6(错误做法)
不能跳过重新检查环节!