## Context

### 当前状态

项目存在三种不同的测试基础设施方式：

| 方式 | 使用文件 | 问题 |
|------|---------|------|
| **testcontainers** | `role_test.go` | 需要 Docker，启动慢（30s+/测试），CI 环境复杂 |
| **共享数据库 + DELETE** | `shop_management_test.go` 等 | 清理不可靠，数据残留，并行冲突 |
| **事务隔离** | 部分单元测试 | ✅ 正确方式，已有 `testutils.NewTestTransaction` |

### 现有基础设施

`tests/testutils/db.go` 已提供：
- `GetTestDB(t)` - 全局单例数据库连接
- `NewTestTransaction(t)` - 创建自动回滚的测试事务
- `GetTestRedis(t)` - 全局单例 Redis 连接
- `CleanTestRedisKeys(t, rdb)` - 自动清理测试 Redis 键

问题是**集成测试没有使用这些工具**，而是各自实现了不同的方式。

## Goals / Non-Goals

**Goals:**
- 统一所有集成测试使用事务隔离模式
- 移除 testcontainers 依赖，简化测试环境要求
- 消除 DELETE 清理代码，改用事务自动回滚
- 提供标准化的集成测试环境设置模式
- 确保测试可以并行运行且互不干扰

**Non-Goals:**
- 不改变测试的业务逻辑验证内容
- 不引入新的测试框架或依赖
- 不修改 `testutils` 的核心 API（仅增强）
- 不处理性能测试或压力测试场景

## Decisions

### 决策 1：统一使用事务隔离模式

**选择**: 所有集成测试使用 `testutils.NewTestTransaction(t)` 获取独立事务

**理由**:
- 已有成熟实现，无需重新开发
- 事务回滚比 DELETE 快 100 倍以上
- 完全隔离，支持并行执行
- 不需要 Docker，降低环境要求

**放弃的替代方案**:
- testcontainers：启动慢、需要 Docker、CI 配置复杂
- 共享数据库 + 命名前缀：清理不可靠、并行时冲突

### 决策 2：增强 testutils 支持集成测试

**选择**: 在 `testutils` 包中添加集成测试专用的辅助函数

新增函数：
```go
// NewIntegrationTestEnv 创建集成测试环境
// 包含：事务、Redis、Logger、TokenManager、App
func NewIntegrationTestEnv(t *testing.T) *IntegrationTestEnv

// IntegrationTestEnv 集成测试环境
type IntegrationTestEnv struct {
    TX           *gorm.DB       // 自动回滚的事务
    Redis        *redis.Client  // 全局 Redis 连接
    Logger       *zap.Logger    // 测试用 Logger
    TokenManager *auth.TokenManager
    App          *fiber.App     // 配置好的 Fiber App
}
```

**理由**:
- 减少每个测试文件的重复代码
- 统一 ErrorHandler、中间件配置
- 方便后续扩展

### 决策 3：测试数据生成策略

**选择**: 使用原子计数器 + 时间戳生成唯一标识

```go
// 已有实现，继续使用
testutils.GenerateUniquePhone()  // 138 + 时间戳后8位
testutil.GenerateUniqueUsername(prefix) // prefix_counter
```

**理由**:
- 即使并行运行也不会冲突
- 不依赖随机数（可重现）
- 已有实现，经过验证

### 决策 4：Fiber App 配置统一

**选择**: 在 `IntegrationTestEnv` 中预配置标准的 Fiber App

配置内容：
- `ErrorHandler`: 使用 `errors.SafeErrorHandler`
- 中间件: 认证中间件（模拟用户上下文）
- 路由: 使用 `routes.RegisterRoutes` 注册

**理由**:
- 与生产环境配置一致
- 避免每个测试文件重复配置
- 便于测试真实的错误处理逻辑

## Risks / Trade-offs

### 风险 1：重构范围大
**风险**: 涉及 15-20 个测试文件，可能引入新 bug
**缓解**: 
- 逐个文件重构，每个文件重构后立即验证
- 保留原有测试用例逻辑，只改变环境设置方式
- 使用 `git diff` 确保只改变了预期的部分

### 风险 2：事务隔离的限制
**风险**: 某些测试可能需要真实的数据库提交（如测试并发）
**缓解**:
- 这类测试极少，可以特殊处理
- 文档说明何时需要跳过事务隔离

### 风险 3：testcontainers 测试可能测试了特定功能
**风险**: testcontainers 测试可能依赖完整的数据库生命周期
**缓解**:
- 分析每个 testcontainers 测试的实际需求
- 大多数只需要隔离的数据库环境，事务可以满足

## Migration Plan

### 阶段 1：增强 testutils（1-2 小时）
1. 添加 `IntegrationTestEnv` 结构和 `NewIntegrationTestEnv` 函数
2. 添加常用的测试辅助函数（创建测试用户、生成 Token 等）
3. 编写使用文档

### 阶段 2：重构 testcontainers 测试（2-3 小时）
1. 重构 `role_test.go`
2. 移除 testcontainers 导入
3. 验证所有测试通过

### 阶段 3：重构 DELETE 清理测试（3-4 小时）
1. 重构 `shop_management_test.go`
2. 重构 `shop_account_management_test.go`
3. 重构其他使用 DELETE 清理的测试
4. 删除所有 `teardown` 中的 DELETE 语句

### 阶段 4：清理和验证（1 小时）
1. 移除 `go.mod` 中的 testcontainers 依赖
2. 运行全量测试验证
3. 更新测试文档

### 回滚策略
- 每个阶段完成后提交
- 如果某个阶段失败，可以 revert 到上一个阶段
- 保留原测试文件的 git 历史，方便对比

## Open Questions

1. **是否需要保留某些 testcontainers 测试？**
   - 初步判断：不需要，所有测试都可以用事务隔离替代
   - 需要在实施时验证

2. **并发测试如何处理？**
   - 当前项目没有并发测试
   - 如果未来需要，可以单独处理

3. **测试数据库的 AutoMigrate 策略？**
   - 当前在 `GetTestDB` 首次调用时执行
   - 可能需要扩展迁移的模型列表
