- 新增 backend/tests/mysql/ 目录,包含 Docker Compose 配置和测试文件 - 新增 Makefile 命令: test-mysql, test-mysql-up, test-mysql-down, test-mysql-quick - 使用 build tag 控制测试启用,默认不运行 - 测试覆盖: 迁移正确性、外键约束、UNIQUE 约束、并发写入 - 发现 statsRepo.Record 存在并发 bug(检查-然后-操作竞态条件)
3.5 KiB
3.5 KiB
MySQL Testing
Purpose
提供 MySQL 数据库专项测试能力,验证迁移正确性、外键约束、并发写入等数据库特定行为。
Requirements
Requirement: MySQL 测试环境可启动
系统 SHALL 提供 Docker Compose 配置以启动 MySQL 8.0 测试环境。
Scenario: 启动 MySQL 测试容器
- WHEN 执行
make test-mysql-up - THEN 启动 MySQL 8.0 容器,端口 13306
- AND 创建数据库
nex_test - AND 容器数据存储在内存盘(tmpfs)
Scenario: 销毁 MySQL 测试容器
- WHEN 执行
make test-mysql-down - THEN 停止并删除容器
- AND 所有数据被销毁
Requirement: MySQL 测试可通过 build tag 控制
MySQL 测试 SHALL 使用 // +build mysql build tag,默认不运行。
Scenario: 默认测试不包含 MySQL 测试
- WHEN 执行
go test ./... - THEN 不运行
tests/mysql/下的测试
Scenario: 启用 MySQL 测试
- WHEN 执行
go test -tags=mysql ./tests/mysql/... - THEN 运行所有 MySQL 测试
Requirement: MySQL 迁移正确执行
MySQL 测试 SHALL 验证迁移脚本在 MySQL 环境下正确执行。
Scenario: 迁移创建所有表
- WHEN 运行 MySQL 迁移
- THEN 创建
providers、models、usage_stats表 - AND 字段类型符合 MySQL 迁移文件定义(VARCHAR、DATETIME(3)、BOOLEAN 等)
- AND 索引
idx_models_provider_id、idx_models_model_name、idx_usage_stats_provider_model_date创建成功
Scenario: 迁移可重复执行
- WHEN 在已迁移的数据库上再次运行迁移
- THEN 不报错,数据库状态不变
Requirement: MySQL 外键约束生效
MySQL 测试 SHALL 验证外键约束行为符合预期。
Scenario: 外键约束阻止无效引用
- WHEN 创建 model 时
provider_id不存在 - THEN 操作失败,返回外键约束错误
Scenario: 级联删除生效
- WHEN 删除 provider
- THEN 该 provider 的所有 models 被级联删除
Requirement: MySQL UNIQUE 约束生效
MySQL 测试 SHALL 验证 UNIQUE 约束行为符合预期。
Scenario: models 表 UNIQUE 约束
- WHEN 尝试创建相同
(provider_id, model_name)组合的 model - THEN 操作失败,返回唯一约束错误
Scenario: usage_stats 表 UNIQUE 约束
- WHEN 尝试创建相同
(provider_id, model_name, date)组合的 usage_stats - THEN 操作失败,返回唯一约束错误
Requirement: MySQL 并发写入正确
MySQL 测试 SHALL 验证并发写入不丢失数据。
Scenario: 并发记录 usage_stats
- WHEN 10 个 goroutine 并发调用
statsRepo.Record(providerID, modelName) - THEN 最终
request_count等于 10 - AND 无数据丢失或重复
Scenario: 并发创建相同 provider
- WHEN 10 个 goroutine 并发创建相同 ID 的 provider
- THEN 仅 1 个成功,其他 9 个失败
Scenario: 并发创建相同 model
- WHEN 10 个 goroutine 并发创建相同
(provider_id, model_name)的 model - THEN 仅 1 个成功,其他 9 个失败
Requirement: MySQL 测试命令完整
Makefile SHALL 提供完整的 MySQL 测试命令。
Scenario: 完整测试流程
- WHEN 执行
make test-mysql - THEN 启动 Docker MySQL
- AND 等待 MySQL 就绪
- AND 运行所有 MySQL 测试
- AND 销毁容器
Scenario: 快速测试(容器已运行)
- WHEN 执行
make test-mysql-quick - THEN 直接运行测试,不管理容器生命周期