forked from datawhale/whale-town-end
docs:添加AI代码检查执行指南文档
- 添加完整的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 - 代码提交规范
This commit is contained in:
349
docs/ai-reading/step5-test-coverage.md
Normal file
349
docs/ai-reading/step5-test-coverage.md
Normal file
@@ -0,0 +1,349 @@
|
||||
# 步骤5:测试覆盖检查
|
||||
|
||||
## 🎯 检查目标
|
||||
检查测试文件的完整性和覆盖率,确保严格的一对一测试映射和测试分离。
|
||||
|
||||
## 📋 测试文件存在性检查
|
||||
|
||||
### 需要测试文件的类型
|
||||
```typescript
|
||||
✅ 必须有测试文件:
|
||||
- *.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工具类(复杂工具类需要)
|
||||
```
|
||||
|
||||
### 测试文件命名规范
|
||||
```typescript
|
||||
✅ 正确的一对一映射:
|
||||
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后缀外)
|
||||
|
||||
### 测试范围严格限制
|
||||
```typescript
|
||||
// ✅ 正确:只测试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
|
||||
```
|
||||
|
||||
### 测试类型分离要求
|
||||
```typescript
|
||||
// ✅ 正确:单元测试只在源文件同目录
|
||||
// 文件位置: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测试
|
||||
```typescript
|
||||
// ✅ 正确:完整的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', () => {
|
||||
// 断开连接测试
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 双模式服务测试
|
||||
```typescript
|
||||
// ✅ 正确:内存服务测试
|
||||
// 文件: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', () => {
|
||||
// 测试两种模式行为一致性
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 属性测试(管理员模块)
|
||||
```typescript
|
||||
// ✅ 正确:属性测试
|
||||
// 文件: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 # 应该拆分并移到上级目录
|
||||
```
|
||||
|
||||
## 🧪 测试执行验证(强制要求)
|
||||
|
||||
### 测试命令执行
|
||||
```bash
|
||||
# 单元测试(严格限制:只执行.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/
|
||||
```
|
||||
|
||||
### 测试执行顺序
|
||||
1. **第一阶段**:单元测试(快速反馈)
|
||||
2. **第二阶段**:集成测试(模块协作)
|
||||
3. **第三阶段**:E2E测试(业务流程)
|
||||
4. **第四阶段**:性能测试(系统性能)
|
||||
|
||||
## 🔍 检查执行步骤
|
||||
|
||||
1. **扫描需要测试的文件类型**
|
||||
- 识别所有.service.ts、.controller.ts、.gateway.ts等文件
|
||||
- 检查是否有对应的.spec.ts测试文件
|
||||
|
||||
2. **验证一对一测试映射**
|
||||
- 确保每个测试文件严格对应一个源文件
|
||||
- 检查测试文件命名是否正确对应
|
||||
|
||||
3. **检查测试范围限制**
|
||||
- 确保测试内容严格限于对应源文件功能
|
||||
- 识别跨文件测试和混合测试
|
||||
|
||||
4. **检查测试文件位置**
|
||||
- 确保单元测试与源文件在同一目录
|
||||
- 识别需要扁平化的测试文件夹
|
||||
|
||||
5. **分离集成测试和E2E测试**
|
||||
- 将集成测试移动到test/integration/
|
||||
- 将E2E测试移动到test/e2e/
|
||||
- 将性能测试移动到test/performance/
|
||||
- 将属性测试移动到test/property/
|
||||
|
||||
6. **执行测试验证**
|
||||
- 运行单元测试命令验证通过
|
||||
- 确保测试覆盖率达标
|
||||
- 验证测试质量和有效性
|
||||
|
||||
7. **游戏服务器特殊检查**
|
||||
- WebSocket Gateway的完整测试覆盖
|
||||
- 双模式服务的一致性测试
|
||||
- 属性测试的正确实现
|
||||
|
||||
## 🔥 重要提醒
|
||||
|
||||
**如果在本步骤中执行了任何修改操作(创建测试文件、移动测试文件、修正测试内容等),必须立即重新执行步骤5的完整检查!**
|
||||
|
||||
- ✅ 执行修改 → 🔥 立即重新执行步骤5 → 提供验证报告 → 等待用户确认
|
||||
- ❌ 执行修改 → 直接进入步骤6(错误做法)
|
||||
|
||||
**不能跳过重新检查环节!**
|
||||
Reference in New Issue
Block a user