Files
huang 1da680a790
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m18s
重构: 店铺套餐分配系统从加价模式改为返佣模式
主要变更:
- 重构分配模型:从加价模式(pricing_mode/pricing_value)改为返佣模式(base_commission + tier_commission)
- 删除独立的 my_package 接口,统一到 /api/admin/packages(通过数据权限自动过滤)
- 新增批量分配和批量调价功能,支持事务和性能优化
- 新增配置版本管理,订单创建时锁定返佣配置
- 新增成本价历史记录,支持审计和纠纷处理
- 新增统计缓存系统(Redis + 异步任务),优化梯度返佣计算性能
- 删除冗余的梯度佣金独立 CRUD 接口(合并到分配配置中)
- 归档 3 个已完成的 OpenSpec changes 并同步 8 个新 capabilities 到 main specs

技术细节:
- 数据库迁移:000026_refactor_shop_package_allocation
- 新增 Store:AllocationConfigStore, PriceHistoryStore, CommissionStatsStore
- 新增 Service:BatchAllocationService, BatchPricingService, CommissionStatsService
- 新增异步任务:统计更新、定时同步、周期归档
- 测试覆盖:批量操作集成测试、梯度佣金 CRUD 清理验证

影响:
- API 变更:删除 4 个梯度 CRUD 接口(POST/GET/PUT/DELETE /:id/tiers)
- API 新增:批量分配、批量调价接口
- 数据模型:重构 shop_series_allocation 表结构
- 性能优化:批量操作使用 CreateInBatches,统计使用 Redis 缓存

相关文档:
- openspec/changes/archive/2026-01-28-refactor-shop-package-allocation/
- openspec/specs/agent-available-packages/
- openspec/specs/allocation-config-versioning/
- 等 8 个新 capability specs
2026-01-28 17:11:55 +08:00

5.4 KiB
Raw Permalink Blame History

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 包中添加集成测试专用的辅助函数

新增函数:

// 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测试数据生成策略

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

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

理由:

  • 即使并行运行也不会冲突
  • 不依赖随机数(可重现)
  • 已有实现,经过验证

决策 4Fiber App 配置统一

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

配置内容:

  • ErrorHandler: 使用 errors.SafeErrorHandler
  • 中间件: 认证中间件(模拟用户上下文)
  • 路由: 使用 routes.RegisterRoutes 注册

理由:

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

Risks / Trade-offs

风险 1重构范围大

风险: 涉及 15-20 个测试文件,可能引入新 bug 缓解:

  • 逐个文件重构,每个文件重构后立即验证
  • 保留原有测试用例逻辑,只改变环境设置方式
  • 使用 git diff 确保只改变了预期的部分

风险 2事务隔离的限制

风险: 某些测试可能需要真实的数据库提交(如测试并发) 缓解:

  • 这类测试极少,可以特殊处理
  • 文档说明何时需要跳过事务隔离

风险 3testcontainers 测试可能测试了特定功能

风险: testcontainers 测试可能依赖完整的数据库生命周期 缓解:

  • 分析每个 testcontainers 测试的实际需求
  • 大多数只需要隔离的数据库环境,事务可以满足

Migration Plan

阶段 1增强 testutils1-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 首次调用时执行
    • 可能需要扩展迁移的模型列表