# Admin Service 测试指南

## 测试架构

本项目采用三层测试策略：

1. **单元测试 (Unit Tests)** - 测试独立组件（Value Objects, Entities, Mappers）
2. **集成测试 (Integration Tests)** - 测试组件间交互（Repositories, Handlers）
3. **端到端测试 (E2E Tests)** - 测试完整的 API 流程（Controllers）

## 测试覆盖

### 单元测试
- ✅ Value Objects (VersionCode, VersionName, FileSize, FileSha256 等)
- ✅ Domain Entities (AppVersion)
- ✅ Mappers (AppVersionMapper)

### 集成测试
- ✅ Repository (AppVersionRepository)
- ✅ Command Handlers (CreateVersionHandler)
- ✅ Query Handlers (CheckUpdateHandler)

### E2E 测试
- ✅ Version API Endpoints
- ✅ 输入验证
- ✅ 错误处理

## 快速开始

### 前置要求

- Node.js 20+
- PostgreSQL 16+
- (可选) Docker & Docker Compose
- (可选) WSL2 (Windows 用户)

### 1. 本地测试

```bash
# 安装依赖
npm install

# 生成 Prisma 客户端
npm run prisma:generate

# 创建测试数据库
createdb admin_service_test

# 运行所有测试
make test

# 或使用 npm
npm test
```

### 2. 分类测试

```bash
# 只运行单元测试
make test-unit

# 只运行集成测试（需要数据库）
make test-integration

# 只运行 E2E 测试（需要数据库）
make test-e2e

# 生成覆盖率报告
make test-cov
```

### 3. WSL2 测试（Windows 推荐）

WSL2 测试会自动忽略 node_modules，在 WSL 环境中重新安装依赖并运行测试。

```powershell
# Windows PowerShell
.\scripts\run-wsl-tests.ps1
```

或直接在 WSL 中：

```bash
# 在 WSL Ubuntu 中
cd /mnt/c/Users/dong/Desktop/rwadurian/backend/services/admin-service
./scripts/test-in-wsl.sh
```

### 4. Docker 测试

使用 Docker Compose 在隔离环境中运行所有测试（包括数据库）：

```bash
# 启动测试环境并运行测试
docker-compose -f docker-compose.test.yml up --build

# 清理
docker-compose -f docker-compose.test.yml down -v
```

或使用 Makefile：

```bash
make docker-test-all
```

## 测试配置

### 环境变量

测试使用 `.env.test` 文件配置：

```env
NODE_ENV=test
APP_PORT=3005
API_PREFIX=api/v1
DATABASE_URL=postgresql://postgres:password@localhost:5432/admin_service_test?schema=public
JWT_SECRET=test-jwt-secret
JWT_EXPIRES_IN=7d
TZ=UTC
```

### Jest 配置

Jest 配置在 `package.json` 中：

```json
{
  "jest": {
    "moduleFileExtensions": ["js", "json", "ts"],
    "rootDir": ".",
    "testRegex": ".*\\.spec\\.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "collectCoverageFrom": [
      "src/**/*.(t|j)s",
      "!src/**/*.module.ts",
      "!src/main.ts",
      "!src/**/*.interface.ts",
      "!src/**/*.dto.ts",
      "!src/**/*.enum.ts"
    ],
    "testEnvironment": "node"
  }
}
```

## 测试数据库

### 本地 PostgreSQL

```bash
# 创建测试数据库
createdb admin_service_test

# 运行迁移
DATABASE_URL="postgresql://postgres:password@localhost:5432/admin_service_test" npm run prisma:migrate

# 清空测试数据
psql admin_service_test -c "TRUNCATE TABLE \"AppVersion\" CASCADE;"
```

### Docker PostgreSQL

```bash
# 启动测试数据库
docker run -d \
  --name admin-test-db \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=password \
  -e POSTGRES_DB=admin_service_test \
  -p 5433:5432 \
  postgres:16-alpine

# 停止并删除
docker stop admin-test-db && docker rm admin-test-db
```

## 持续集成 (CI)

### GitHub Actions 示例

```yaml
name: Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:16-alpine
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: password
          POSTGRES_DB: admin_service_test
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432

    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm ci

      - name: Generate Prisma client
        run: npm run prisma:generate

      - name: Run migrations
        run: npm run prisma:migrate
        env:
          DATABASE_URL: postgresql://postgres:password@localhost:5432/admin_service_test

      - name: Run tests
        run: npm test
        env:
          DATABASE_URL: postgresql://postgres:password@localhost:5432/admin_service_test

      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage/lcov.info
```

## 常见问题

### Q: 集成测试失败，显示 "Can't reach database server"

**A:** 确保 PostgreSQL 正在运行，并且 `.env.test` 中的 `DATABASE_URL` 正确。

```bash
# 检查 PostgreSQL 状态
sudo systemctl status postgresql

# 或使用 Docker
docker ps | grep postgres
```

### Q: WSL 测试失败，找不到文件

**A:** 确保在 Windows 中运行 PowerShell 脚本，它会自动转换路径。

### Q: Docker 测试挂起

**A:** 检查数据库健康检查是否通过：

```bash
docker-compose -f docker-compose.test.yml ps
docker-compose -f docker-compose.test.yml logs postgres-test
```

### Q: 测试覆盖率低

**A:** 查看覆盖率报告：

```bash
npm run test:cov
open coverage/lcov-report/index.html
```

## 最佳实践

1. **隔离测试** - 每个测试应该独立，不依赖其他测试
2. **清理数据** - 在 `beforeEach` 中清理测试数据
3. **使用工厂** - 创建测试数据的辅助函数
4. **描述性命名** - 测试名称应该清楚描述测试内容
5. **AAA 模式** - Arrange, Act, Assert

## 测试命令速查

| 命令 | 说明 |
|------|------|
| `make test` | 运行所有测试 |
| `make test-unit` | 只运行单元测试 |
| `make test-integration` | 只运行集成测试 |
| `make test-e2e` | 只运行 E2E 测试 |
| `make test-cov` | 生成覆盖率报告 |
| `make docker-test-all` | Docker 环境测试 |
| `npm run test:watch` | 监听模式 |
| `npm run test:debug` | 调试模式 |

## 报告问题

如果遇到测试问题：

1. 检查测试日志
2. 验证环境配置
3. 查看 `TEST_GUIDE.md`
4. 提交 Issue 并附上错误信息
