98 lines
10 KiB
Markdown
98 lines
10 KiB
Markdown
# RailwaySystem 核心业务场景集成测试矩阵 (Core Business Test Matrix)
|
||||
|
|
|
|||
|
|
本文档整理了 RailwaySystem 核心业务场景自动化测试套件的覆盖范围、验证层级(Mock单元测试 vs. 真实Kingbase/API集成Gate)以及当前验证结果。本材料面向研发阶段汇报与质量门禁审计。
|
|||
|
|
|
|||
|
|
> **基线信息**:
|
|||
|
|
> - 开发分支:`integration/wave2-20260914`
|
|||
|
|
> - 基线 HEAD:`c04992a8017de78c6b4a43592ae9941e85a9fea9`
|
|||
|
|
> - 最新测试运行编号:`QA_W2_20260914221336`
|
|||
|
|
> - 自动化测试架构:离线 Mock 测试(`CoreBusinessScenarioMockTest`) + 显式真实集成门禁(`scripts/qa/run-core-business-scenario.sh`)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. 核心业务场景测试矩阵
|
|||
|
|
|
|||
|
|
| 业务模块 | 测试场景 | API / 接口 | 数据库/核心逻辑断言 | 验证层级 (Mock / Real) | 当前结果 |
|
|||
|
|
| :--- | :--- | :--- | :--- | :--- | :--- |
|
|||
|
|
| **Teacher (教师)** | 教师档案创建与可用性验证 | `POST /train/teacher`<br>`GET /train/teacher/list` | 教师主键 `t_id` 持久化,姓名、职称、联系方式正确落库 | Mock & Real | **PASS** |
|
|||
|
|
| **Course (课程)** | 基础课程创建与状态维护 | `POST /train/course`<br>`GET /train/course/list` | 课程主键 `c_id`、编码与课时正确落库,`status=1` | Mock & Real | **PASS** |
|
|||
|
|
| **Classroom (教室)** | 理论教室资源创建与容量设定 | `POST /train/classroom`<br>`GET /train/classroom/{id}` | 教室主键 `class_room_id` 与容量有效持久化 | Mock & Real | **PASS** |
|
|||
|
|
| **TrainingSite (实训场地)** | 演练实训基地创建与容量校验 | `POST /train/training-site`<br>`GET /train/training-site/list` | 自动生成32位UUID主键,必填容量非空校验,状态可用 | Mock & Real | **PASS** |
|
|||
|
|
| **Student (学员)** | 学员基础档案建立与主档状态区分 | `POST /train/student`<br>`GET /train/student/list` | 32位UUID主键,学员主档状态独立维护 (`1:正常`, `0:停用`) | Mock & Real | **PASS** |
|
|||
|
|
| **Plan (培训计划)** | 创建培训班计划与周期时间合法性 | `POST /train/plans`<br>`GET /train/plans/{id}` | 生成32位UUID,初始状态强制为 `0:草稿`,起止时间校验 | Mock & Real | **PASS** |
|
|||
|
|
| **PlanCourse (计划课程)** | 培训班绑定课程及关联关系查询 | `POST /train/plans/{id}/courses`<br>`GET /train/plans/{id}/courses` | 生成自增 `plan_course_id`,外键关联一致性 | Mock & Real | **PASS** |
|
|||
|
|
| **Enrollment (学员报名)** | 正常学员入班 (Happy Path) | `POST /train/plans/{id}/enrollments` | 生成自增 `enrollment_id`,参训状态初始为 `0:待报到` | Mock & Real | **PASS** |
|
|||
|
|
| **Enrollment (学员报名)** | 同一计划重复报名校验 | `POST /train/plans/{id}/enrollments` | 业务错误码 `40030: ENROLLMENT_ALREADY_EXISTS`,数据库唯一约束保证 `duplicate enrollment = 0` | Mock & Real | **PASS** |
|
|||
|
|
| **Enrollment (学员报名)** | 计划招生容量上限超限拦截 | `POST /train/plans/{id}/enrollments` | 业务错误码 `40031: ENROLLMENT_CAPACITY_EXCEEDED`,不允许超额入班 | Mock & Real | **PASS** |
|
|||
|
|
| **Enrollment (学员报名)** | 无效学员入班拦截 | `POST /train/plans/{id}/enrollments` | 业务错误码 `40402: STUDENT_NOT_FOUND`,拒绝非法入班 | Mock & Real | **PASS** |
|
|||
|
|
| **Enrollment (学员报名)** | 停用状态学员 (`status=0`) 入班拦截 | `POST /train/plans/{id}/enrollments` | 业务错误码 `40402: STUDENT_DISABLED`,严禁停用学员报名 | Mock & Real | **PASS** |
|
|||
|
|
| **Enrollment (学员报名)** | 报到/请假/退训参训状态维护 | `PUT /train/enrollments/{id}/status` | 参训状态独立流转 (`0:待报到`, `1:已报到`, `2:请假`, `3:退训`, `4:已完成`) | Mock & Real | **PASS** |
|
|||
|
|
| **Scheduling (排课)** | 正常排课课次冲突预检 | `POST /train/lessons/check-conflict` | 返回 `hasConflict=false, conflictType=NONE` | Mock & Real | **PASS** |
|
|||
|
|
| **Scheduling (排课)** | 教师时间重叠冲突检测 | `POST /train/lessons/check-conflict` | 返回 `hasConflict=true, conflictType=TEACHER` | Mock & Real | **PASS** |
|
|||
|
|
| **Scheduling (排课)** | 教室资源重叠冲突检测 (Warning) | `POST /train/lessons/check-conflict` | 返回 `hasConflict=true, conflictType=CLASSROOM`,Warning级别 | Mock & Real | **PASS** |
|
|||
|
|
| **Scheduling (排课)** | 实训场地重叠冲突检测 (Warning) | `POST /train/lessons/check-conflict` | 返回 `hasConflict=true, conflictType=SITE`,Warning级别 | Mock & Real | **PASS** |
|
|||
|
|
| **Scheduling (排课)** | 计划内课次重叠冲突检测 (Warning) | `POST /train/lessons/check-conflict` | 返回 `hasConflict=true, conflictType=PLAN_OVERLAP`,Warning级别 | Mock & Real | **PASS** |
|
|||
|
|
| **Scheduling (排课)** | Warning非硬阻断验证 | `POST /train/plans/{id}/lessons` | Warning不阻断保存,禁止任何 `force/override` 参数,标准POST成功保存 | Mock & Real | **PASS** |
|
|||
|
|
| **Scheduling (排课)** | 起止时间非法硬阻断 | `POST /train/plans/{id}/lessons` | 业务错误码 `40010: LESSON_TIME_INVALID` (startTime >= endTime) | Mock & Real | **PASS** |
|
|||
|
|
| **Scheduling (排课)** | 计划锁定/已结训硬阻断 | `POST /train/plans/{id}/lessons` | 业务错误码 `40012: PLAN_LOCKED`,已结束计划禁止变更课次 | Mock & Real | **PASS** |
|
|||
|
|
| **Scheduling (排课)** | 场地 XOR 互斥硬阻断 | `POST /train/plans/{id}/lessons` | 场地二选一非法时强行拦截,DB层面 `invalid venue XOR = 0` | Mock & Real | **PASS** |
|
|||
|
|
| **Scheduling (排课)** | 跨计划关联课程硬阻断 | `POST /train/plans/{id}/lessons` | 业务错误码 `40420: PLAN_COURSE_NOT_IN_PLAN`,禁止错链 | Mock & Real | **PASS** |
|
|||
|
|
| **Scheduling (排课)** | 关键资源不存在硬阻断 | `POST /train/plans/{id}/lessons` | 业务错误码 `40401/40403/40410`,拒绝孤立外键记录 | Mock & Real | **PASS** |
|
|||
|
|
| **Timetable (课表)** | 课表视图与聚合字段显示 | `GET /train/plans/{id}/timetable` | 正确映射 `courseName`, `teacherName`, `venueName` | Mock & Real | **PASS** |
|
|||
|
|
| **ElectronicBoard (电子班牌)** | 班牌创建与主键UUID规则 | `POST /train/board`<br>`GET /train/board/list` | 后端自动生成32位UUID,默认在线状态 `board_status=0` | Mock & Real | **PASS** |
|
|||
|
|
| **ElectronicBoard (电子班牌)** | 教室详情与班牌绑定列表映射 | `GET /train/classroom/{id}` | 0块板返回空列表,1块板返回长度1,N块板返回长度N | Mock & Real | **PASS** |
|
|||
|
|
| **ElectronicBoard (电子班牌)** | 课表单板/多板 `boardSn` 降级规则 | `GET /train/plans/{id}/timetable` | 0块板返回null,恰好1块返回对应SN,大于1块降级为null | Mock & Real | **PASS** |
|
|||
|
|
| **ElectronicBoard (电子班牌)** | 班牌逻辑删除持久化保障 | `DELETE /train/board/{id}` | `del_flag='2'` 逻辑删除,正式接口不可查,DB断言确认存在 | Mock & Real | **PASS** |
|
|||
|
|
| **Plan Completion (结训联动)** | 计划结训与活动学员状态自动流转 | `POST /train/plans/{id}/complete` | Plan状态变更为 `2:已结束`;活动学员 (`status=0/1`) 状态自动变更为 `4:已完成`,且 `complete_time != null` 真实写入 | Mock & Real | **PASS** |
|
|||
|
|
| **Plan Completion (结训联动)** | 历史退训学员状态防覆盖保护 | `POST /train/plans/{id}/complete`<br>`GET /train/enrollments/{id}` | 历史已退训学员 (`status=3`) 状态保持为 3,`complete_time` 保持为 null,杜绝误覆盖 | Mock & Real | **PASS** |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. Legacy Analytics 模块边界说明
|
|||
|
|
|
|||
|
|
根据研发分工规范,Codex 正在独立重构 Legacy Analytics 分析统计模块,本测试套件严格执行架构隔离,**完全未碰、严禁修改或测试**以下四个模块,标记为 `PENDING_V2_CONTRACT`:
|
|||
|
|
|
|||
|
|
| 模块名称 | 职责描述 | 当前标记 | 规划接入时机 |
|
|||
|
|
| :--- | :--- | :--- | :--- |
|
|||
|
|
| **Report (报表管理)** | 培训数据统计与导出报表 | `PENDING_V2_CONTRACT` | 等待 Codex V2 契约稳定合并后扩展集成 |
|
|||
|
|
| **Checkin (签到考勤)** | 学员人脸识别与打卡明细统计 | `PENDING_V2_CONTRACT` | 等待 Codex V2 契约稳定合并后扩展集成 |
|
|||
|
|
| **Duration (学时统计)** | 学员课时完成度与学时汇总 | `PENDING_V2_CONTRACT` | 等待 Codex V2 契约稳定合并后扩展集成 |
|
|||
|
|
| **Portrait (学员画像)** | 学员综合能力多维能力画像 | `PENDING_V2_CONTRACT` | 等待 Codex V2 契约稳定合并后扩展集成 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. Kingbase 数据库只读安全断言规范
|
|||
|
|
|
|||
|
|
集成门禁每次运行均调用独立的只读断言器 `scripts.qa.DbAssertionChecker`,直接在 Kingbase 真实数据库实例上校验以下全局一致性与业务正确性指标:
|
|||
|
|
|
|||
|
|
1. **`duplicate enrollment = 0`**:没有任何重复学员出现在同一计划中。
|
|||
|
|
2. **`orphan lesson = 0`**:所有课次均正确关联有效的培训计划课程。
|
|||
|
|
3. **`orphan enrollment = 0`**:所有报名记录均归属于真实存在的培训计划。
|
|||
|
|
4. **`invalid venue XOR = 0`**:所有课次的场地配置严格满足教室/实训场地二选一互斥,无同时为空或同时设置的情况。
|
|||
|
|
5. **`del_flag = '2'`**:电子班牌逻辑删除后底层标志位规范设置为 `'2'`。
|
|||
|
|
6. **`Plan completion 状态与时间写入一致性`**:结训后学员参训状态正确流转至 4 且结训时间真实写入。
|
|||
|
|
7. **`退训状态历史保护`**:已退训记录未被结训批量任务破坏。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. 测试套件门禁执行方式
|
|||
|
|
|
|||
|
|
### 4.1 普通离线单元测试(无 DB 依赖)
|
|||
|
|
开发人员日常或 CI 极速离线门禁:
|
|||
|
|
```bash
|
|||
|
|
mvn test
|
|||
|
|
```
|
|||
|
|
- 测试用例总数:**123 个** (包含 ruoyi-train 113 个,ruoyi-admin 10 个)。
|
|||
|
|
- 执行状态:**ALL PASS (0 Failures, 0 Errors, 0 Skipped)**。
|
|||
|
|
- 执行耗时:约 3~4 秒,完全不依赖任何外部端口与数据库。
|
|||
|
|
|
|||
|
|
### 4.2 核心业务端到端集成测试套件(真实 Gate)
|
|||
|
|
阶段汇报、发布审计或环境准入门禁:
|
|||
|
|
```bash
|
|||
|
|
bash scripts/qa/run-core-business-scenario.sh
|
|||
|
|
```
|
|||
|
|
- 自动前置预检 Kingbase 隧道 (`127.0.0.1:4321`) 与后端服务。
|
|||
|
|
- 自动生成批次隔离编号 `RUN_ID=QA_W2_<timestamp>`。
|
|||
|
|
- 认证信息与数据库连接串通过环境变量或安全配置注入,零凭据泄露。
|
|||
|
|
- 运行后在 `/tmp/railwaysystem-qa/<RUN_ID>/` 生成完整报告套件(`summary.md`, `api-results.json`, `db-assertions.json`, `created-resources.json`, `cleanup-report.json`)。
|
|||
|
|
- 测试完毕后严格按照本次记录的精确主键 ID 顺序安全回滚清理,保障数据库零脏数据污染。
|