1
0
Files
nex/openspec/specs/mysql-testing/spec.md
lanyuanxiaoyao 2c401f7ae6 chore: streamline workspace make workflows
Clarify product-level server and desktop commands while moving backend-only maintenance tasks into backend/Makefile. This keeps root automation focused on core flows and aligns the main OpenSpec specs with the new command boundaries.
2026-04-28 17:44:23 +08:00

105 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MySQL Testing
## Purpose
提供 MySQL 数据库专项测试能力,验证迁移正确性、外键约束、并发写入等数据库特定行为。
## Requirements
### Requirement: MySQL 测试环境可启动
系统 SHALL 提供 Docker Compose 配置和 backend 局部 make 命令以启动 MySQL 8.0 测试环境。
#### Scenario: 启动 MySQL 测试容器
- **WHEN** 在 `backend/` 目录执行 `make mysql-up`
- **THEN** 启动 MySQL 8.0 容器,端口 13306
- **AND** 创建数据库 `nex_test`
- **AND** 容器数据存储在内存盘tmpfs
#### Scenario: 销毁 MySQL 测试容器
- **WHEN** 在 `backend/` 目录执行 `make 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 测试命令完整
`backend/Makefile` SHALL 提供完整的 MySQL 测试命令。
#### Scenario: 完整测试流程
- **WHEN** 在 `backend/` 目录执行 `make mysql-test`
- **THEN** 启动 Docker MySQL
- **AND** 等待 MySQL 就绪
- **AND** 运行所有 MySQL 测试
- **AND** 销毁容器
#### Scenario: 快速测试(容器已运行)
- **WHEN** 在 `backend/` 目录执行 `make mysql-test-quick`
- **THEN** 直接运行测试,不管理容器生命周期