339 lines
14 KiB
Markdown
339 lines
14 KiB
Markdown
# 59 · QA 测试框架(QA Testing Framework)
|
||
|
||
> **命名空间** `BaseGames.QA`
|
||
> **所属文档集** [← 返回索引](./README.md) · [总览](./00_Overview.md)
|
||
> **依赖** Unity Test Framework · `BaseGames.Reliability` · `BaseGames.Analytics`
|
||
> **关联** 49_AntiSoftlockSystem · 56_CrashRecoverySystem · 46_PlatformIntegration · 29_DifficultyModesGuide
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
1. [QA 策略总览](#1-qa-策略总览)
|
||
2. [自动化测试分层架构](#2-自动化测试分层架构)
|
||
3. [关键系统回归清单](#3-关键系统回归清单)
|
||
4. [平台认证矩阵(TCR/TRC)](#4-平台认证矩阵tcrtrc)
|
||
5. [Softlock 测试方法论](#5-softlock-测试方法论)
|
||
6. [本地化 QA 流程](#6-本地化-qa-流程)
|
||
7. [性能基准 SOP](#7-性能基准-sop)
|
||
8. [Bug 等级分类与阻塞标准](#8-bug-等级分类与阻塞标准)
|
||
9. [PlayTest 流程规范](#9-playtest-流程规范)
|
||
10. [CI/CD 质量门禁](#10-cicd-质量门禁)
|
||
|
||
---
|
||
|
||
## 1. QA 策略总览
|
||
|
||
```
|
||
QA 测试金字塔
|
||
┌─────────────┐
|
||
│ 手动 QA │ ← PlayTest / 平台认证 / 本地化审校
|
||
│ (少量,慢) │
|
||
├─────────────┤
|
||
│ 集成测试 │ ← 跨系统流程(存档↔进度、对话↔任务)
|
||
│ │
|
||
├─────────────┤
|
||
│ 单元测试 │ ← 纯逻辑(伤害计算、存档序列化、物理层)
|
||
│ (大量,快) │
|
||
└─────────────┘
|
||
```
|
||
|
||
**测试目标**:
|
||
- 发行日不存在 P0/P1 Bug
|
||
- 平台认证一次通过(不因可预期的问题而拒审)
|
||
- 关键游戏数据(存档、能力解锁)不因边界条件损坏
|
||
|
||
**QA 工具链**:
|
||
- Unity Test Framework(EditMode + PlayMode)
|
||
- Custom QA CI Runner(GitHub Actions / 本地 MSBuild)
|
||
- GameCI Docker(Unity 无头构建)
|
||
- 手动 Bug 追踪(GitHub Issues 或 Notion)
|
||
|
||
---
|
||
|
||
## 2. 自动化测试分层架构
|
||
|
||
### 2.1 EditMode 测试(纯逻辑,不需要场景)
|
||
|
||
存放路径:`Assets/Tests/EditMode/`
|
||
|
||
| 测试文件 | 覆盖内容 |
|
||
|---------|---------|
|
||
| `SaveDataSerializationTests.cs` | 存档 JSON 序列化/反序列化往返,版本迁移 |
|
||
| `DamageCalculationTests.cs` | 伤害公式、暴击、减伤计算 |
|
||
| `PhysicsLayerTests.cs` | Layer 注册正确、Collision Matrix 符合 57_PhysicsLayerMatrix |
|
||
| `EconomyTests.cs` | Geo 计算、稀有掉落保底逻辑(EconomyConfigSO)|
|
||
| `CompletionTrackerTests.cs` | 完成度积分计算,各分类加分逻辑 |
|
||
| `WorldStateRegistryTests.cs` | SetFlag/HasFlag/LoadFromSave 往返一致性 |
|
||
| `AbilityGateTests.cs` | AbilityGate 阻挡/通过逻辑 |
|
||
| `SpeedrunTimerTests.cs` | IGT 在各种暂停状态下的计时精度 |
|
||
|
||
### 2.2 PlayMode 测试(需要场景上下文)
|
||
|
||
存放路径:`Assets/Tests/PlayMode/`
|
||
|
||
| 测试文件 | 覆盖内容 |
|
||
|---------|---------|
|
||
| `PlayerMovementTests.cs` | 跳跃、冲刺、抓墙物理行为 |
|
||
| `CombatFlowTests.cs` | 攻击 → HitBox → HurtBox → 伤害 → 击退完整流程 |
|
||
| `SaveLoadCycleTests.cs` | 存档 → 读档 → 状态一致(跨场景)|
|
||
| `DialogueTriggerTests.cs` | NPC 交互 → 对话触发 → 完成 → 状态变更 |
|
||
| `SoftlockDetectorTests.cs` | SoftlockDetector 计时器触发行为 |
|
||
| `RoomTransitionTests.cs` | 场景切换、传送、存档点等场景跳转流程 |
|
||
|
||
### 2.3 测试运行命令
|
||
|
||
```bash
|
||
# 运行所有 EditMode 测试(无需 Unity 编辑器 GUI)
|
||
unity -runTests -testPlatform EditMode -projectPath . -testResults ./TestResults/EditMode.xml
|
||
|
||
# 运行所有 PlayMode 测试
|
||
unity -runTests -testPlatform PlayMode -projectPath . -testResults ./TestResults/PlayMode.xml
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 关键系统回归清单
|
||
|
||
每次发布前**必须**手动验证的核心流程(自动化未覆盖的场景):
|
||
|
||
### 3.1 存档系统
|
||
- [ ] 存档 → 强制退出 → 重启 → 进度完整
|
||
- [ ] 在 Boss 房间内强制退出 → 重启 → 在 Boss 房间外重生(不是在 Boss 房间里)
|
||
- [ ] 3 个存档槽独立,不相互干扰
|
||
- [ ] 硬件时钟倒退后,存档时间戳不异常
|
||
- [ ] 磁盘满时,错误 UI 正常显示(手动制造磁盘满条件)
|
||
|
||
### 3.2 进度与能力
|
||
- [ ] 获得双跳后,双跳立即可用(不需要重启)
|
||
- [ ] 冲刺能力解锁后,冲刺 AbilityGate 正确开启
|
||
- [ ] NG+ 开始后,继承列表中的能力/符文完整
|
||
- [ ] NG+ 不继承 Boss 状态(Boss 重置为未击败)
|
||
|
||
### 3.3 地图与世界
|
||
- [ ] 所有房间首次进入后,地图正确标记
|
||
- [ ] 地图上的 NPC 图标随 NPC 迁移而更新
|
||
- [ ] 商店库存随进度解锁
|
||
- [ ] 所有房间都能从入口正常进入/退出(无穿模)
|
||
|
||
### 3.4 战斗
|
||
- [ ] 攻击 HitBox 在各方向正确(上攻/下攻/左右攻方向一致)
|
||
- [ ] 弹反判定窗口与动画帧同步
|
||
- [ ] Boss 各阶段转场正确(不跳相)
|
||
- [ ] 死亡 → Geo 掉落 → 拾取 Geo 恢复
|
||
- [ ] 永久死亡(Geo 无法恢复)的边界条件(掉入深渊底部)
|
||
|
||
### 3.5 对话与叙事
|
||
- [ ] 关键 NPC 的对话版本随世界状态标志正确切换
|
||
- [ ] 长对话跳过后,剧情标志仍然正确设置
|
||
- [ ] 侧任务完成条件满足后,任务 UI 正确完成
|
||
|
||
---
|
||
|
||
## 4. 平台认证矩阵(TCR/TRC)
|
||
|
||
> 每个平台的具体认证要求参见 46_PlatformIntegration.md §4。本表列出常见拒审原因及对应测试项。
|
||
|
||
| 平台 | 常见拒审原因 | 测试项 |
|
||
|------|-----------|-------|
|
||
| **Steam** | 游戏崩溃 / 卡死 / 无响应 | 4小时稳定性测试(各区域循环游玩)|
|
||
| | 成就不触发 | 每个成就手动验证触发条件 |
|
||
| | 截图库无截图 / 描述不准确 | 按 Steam 商店指南核对资产 |
|
||
| **Nintendo Switch** | 休眠后无法恢复(挂起/恢复) | 在各游戏状态下触发 Switch 休眠,恢复后验证 |
|
||
| | 控制器断开后崩溃 | 运行时拔出 Joy-Con,验证提示 UI |
|
||
| | 未使用 Switch 按钮图标 | 检查所有操作提示图标(A/B/X/Y 不用 XBox 图标)|
|
||
| | 本地多人存档不隔离 | 多用户账号分别进行存档验证 |
|
||
| | Home Menu 警告文本缺失 | 检查所有 Modal 有无必要的 Home Menu 提示 |
|
||
| **PlayStation** | 数据管理要求(自动存档) | TRC T-09X 系列:自动存档符合 TCR |
|
||
| | 奖杯不解锁 / 解锁过多重复 | 每个奖杯手动验证,确认不重复触发 |
|
||
| | 营销资产规格不符 | 按 PlayStation 素材规格核对 |
|
||
|
||
### Switch 强制测试项
|
||
|
||
```
|
||
测试: 挂起/恢复 (Suspend/Resume)
|
||
环境: 在以下每种状态下触发 Switch 休眠键
|
||
- 主菜单
|
||
- 正常游玩(普通房间)
|
||
- Boss 战中
|
||
- 过场动画播放中
|
||
- 存档中(SaveIndicator 可见时)
|
||
- 加载中(黑屏过渡)
|
||
预期结果: 恢复后游戏完整可用,无崩溃,无数据丢失
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Softlock 测试方法论
|
||
|
||
> 配合 49_AntiSoftlockSystem.md §6 的 `EscapeGuaranteeValidator` 工具使用。
|
||
|
||
### 5.1 自动化检查(EditorWindow BFS)
|
||
|
||
1. 打开 `Tools → Zeling → Escape Guarantee Validator`
|
||
2. 点击"Run All Rooms",工具遍历所有房间的 `RoomEscapeInfoSO`
|
||
3. 检查是否每个房间都有对应所有能力状态的逃生路线
|
||
|
||
### 5.2 手动 Softlock 测试清单
|
||
|
||
| 测试场景 | 操作步骤 | 预期行为 |
|
||
|---------|---------|---------|
|
||
| 无能力状态进入任何房间 | 使用 Debug 模式删除全部能力,进入目标房间 | SoftlockDetector 45s 后触发,传送选项出现 |
|
||
| 被敌人推入凹陷地形 | 找到地图中所有凹形地形,测试是否可逃出 | 能跳出,或跌落重生 |
|
||
| Boss 房间门关闭后能力丢失 | 进入 Boss 房间 → 通过 Debug 移除 Dash → Boss 死亡门未开 | SoftlockDetector 触发,或 Boss 房间门有保底开门逻辑 |
|
||
| 液体区域无游泳能力 | 进入液体区域,移除游泳能力 | 玩家在液体中逐渐失血,死亡后正常重生(不卡死)|
|
||
| AbilityGate 入口无出口 | 进入 AbilityGate 保护的区域,然后条件不满足 | 区域内必须有出口或逃生路线(EscapeGuaranteeValidator 保证)|
|
||
|
||
---
|
||
|
||
## 6. 本地化 QA 流程
|
||
|
||
### 6.1 支持语言列表
|
||
|
||
| 语言 | 代码 | 审核负责人 |
|
||
|------|------|---------|
|
||
| 简体中文(主语言)| zh-CN | 内部团队 |
|
||
| 繁体中文 | zh-TW | 外包审校 |
|
||
| 英文 | en | 外包翻译 + 内部审核 |
|
||
| 日文 | ja | 外包翻译(必须含母语审校)|
|
||
| 韩文 | ko | 外包翻译(建议)|
|
||
|
||
### 6.2 本地化 QA 检查项
|
||
|
||
- [ ] **文本溢出**:所有 UI 文本在最长翻译(通常是德文/日文)下不溢出容器
|
||
- [ ] **字体覆盖**:所有语言的特殊字符正确显示(日文假名、韩文字符、中文繁体异体字)
|
||
- [ ] **语境正确性**:道具名称/NPC 名称在句子中语法正确(特别是日语助词)
|
||
- [ ] **图像内文字**:所有包含硬编码文字的图像都有对应语言版本
|
||
- [ ] **音频字幕同步**:过场动画字幕与原声音频时间轴对齐(±0.5s 内)
|
||
- [ ] **数字格式**:货币、日期格式符合各地区习惯(如日文不用逗号分隔千位数)
|
||
|
||
### 6.3 本地化自动检查工具
|
||
|
||
```csharp
|
||
// 在 CI 中运行 LocalizationAuditTool,自动检测:
|
||
// 1. 所有本地化 Key 都有对应翻译(无缺失 Key)
|
||
// 2. 无翻译超过容器字数限制(基于 Font Asset + TextMeshPro 计算)
|
||
// 3. 所有音频 Key 对应的音频文件存在
|
||
LocalizationAuditTool.RunAudit(outputPath: "./TestResults/LocalizationAudit.html");
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 性能基准 SOP
|
||
|
||
### 7.1 目标平台性能指标
|
||
|
||
| 平台 | 目标帧率 | 允许最低帧率 | 内存上限 |
|
||
|------|---------|-----------|---------|
|
||
| PC(中端,GTX 1060)| 60 FPS | 45 FPS(极端粒子特效)| 2 GB RAM |
|
||
| PC(低端,集成显卡)| 30 FPS(低质量预设)| 25 FPS | 1.5 GB RAM |
|
||
| Nintendo Switch(TV 模式)| 60 FPS | 50 FPS | 3.5 GB RAM |
|
||
| Nintendo Switch(手持模式)| 60 FPS | 45 FPS | 3.5 GB RAM |
|
||
|
||
### 7.2 性能测试标准场景
|
||
|
||
每次大版本发布前在以下场景运行 5 分钟帧率采样:
|
||
|
||
| 场景 | 测试内容 |
|
||
|------|---------|
|
||
| `Scene_Forest_Main`(大地图)| 正常游玩,含大量背景层植被 |
|
||
| `Scene_Cave_BossArena`(Boss 战)| Abyss Boss 第3阶段(最多粒子特效)|
|
||
| `Scene_Core_Final`(最终区域)| 最多光照/后处理 |
|
||
| `Scene_StressTest_500Enemies`(压测)| 人工压测场景,500个激活敌人 |
|
||
|
||
### 7.3 性能基准工具
|
||
|
||
```csharp
|
||
// 在场景中放置 PerformanceBenchmarkRunner 组件
|
||
// 运行后输出 CSV:帧率、CPU ms、GPU ms、内存、DrawCall 等
|
||
[RequireComponent(typeof(Camera))]
|
||
public class PerformanceBenchmarkRunner : MonoBehaviour
|
||
{
|
||
[SerializeField] float testDurationSeconds = 300f;
|
||
[SerializeField] string outputPath = "TestResults/Performance/";
|
||
|
||
// 每帧记录 FrameTimingManager 数据,结束后输出 CSV
|
||
}
|
||
```
|
||
|
||
### 7.4 内存泄漏检测 SOP
|
||
|
||
1. 打开 Unity Memory Profiler(包名:`com.unity.memoryprofiler`)
|
||
2. 在 `Scene_Forest_Main` 游玩 10 分钟,每隔 2 分钟截取一次内存快照
|
||
3. 比较前后快照,检查 `MonoBehaviour` / `Texture2D` / `AudioClip` 是否持续增长
|
||
4. 重点检查:切换场景后旧场景的 Addressable 资源是否正确卸载
|
||
|
||
---
|
||
|
||
## 8. Bug 等级分类与阻塞标准
|
||
|
||
| 等级 | 定义 | 示例 | 发布阻塞 |
|
||
|------|------|------|---------|
|
||
| **P0(致命)** | 导致游戏无法进行,数据丢失,或认证不通过 | 存档损坏、游戏崩溃、平台认证必需功能缺失 | 🔴 必须修复后方可发布 |
|
||
| **P1(严重)** | 游戏流程卡死,主线任务无法完成 | Softlock、Boss 无敌、主线对话不触发 | 🔴 必须修复后方可发布 |
|
||
| **P2(主要)** | 功能异常但有规避方法,或影响较大的视觉/音频 Bug | 支线任务 Bug、成就不触发、音频缺失 | 🟡 目标修复,首发前尽力解决 |
|
||
| **P3(次要)** | 小视觉 Bug,不影响游戏性 | 个别图层 z-order 错误、UI 文字截断 | 🟢 可首发后热更新 |
|
||
| **P4(优化)** | 性能问题或用户体验改善建议 | 帧率偶尔下降、操作手感微调 | 🟢 可后续版本跟进 |
|
||
|
||
---
|
||
|
||
## 9. PlayTest 流程规范
|
||
|
||
### 9.1 内部 PlayTest
|
||
|
||
| 阶段 | 时机 | 目标 | 参与者 |
|
||
|------|------|------|--------|
|
||
| **Alpha PlayTest** | 核心系统完成后 | 核心游戏循环验证,P0/P1 Bug 猎杀 | 开发团队 |
|
||
| **Beta PlayTest** | 内容完整后 | 完整流程通关,难度曲线,本地化初检 | 团队 + 10~20 名外部测试者 |
|
||
| **Pre-cert PlayTest** | 提交平台认证前 2 周 | 模拟平台认证检查,平台合规 | 专注平台认证的 QA |
|
||
| **Gold Candidate** | 发行前 1 周 | 最终回归,P0/P1 清零确认 | 全团队 |
|
||
|
||
### 9.2 PlayTest 问卷(标准版)
|
||
|
||
外部 PlayTest 结束后必须填写:
|
||
|
||
1. 整体评分(1~10)
|
||
2. 操作手感评分(1~10)
|
||
3. 难度评分(太简单 / 刚好 / 太难)
|
||
4. 是否遇到 Bug?(是/否,详细描述)
|
||
5. 是否遇到不明白如何继续的情况?(描述卡关位置)
|
||
6. 最喜欢的部分是什么?
|
||
7. 最不喜欢的部分是什么?
|
||
8. 游玩时长
|
||
|
||
---
|
||
|
||
## 10. CI/CD 质量门禁
|
||
|
||
所有 PR 合并前必须通过以下自动化检查(GitHub Actions):
|
||
|
||
```yaml
|
||
# .github/workflows/qa.yml(示例结构)
|
||
quality_gates:
|
||
- name: Unity Build (PC)
|
||
command: unity -buildTarget StandaloneWindows64 -batchmode -quit
|
||
fail_on: build_error
|
||
|
||
- name: EditMode Tests
|
||
command: unity -runTests -testPlatform EditMode
|
||
fail_on: any_test_failure
|
||
|
||
- name: Localization Audit
|
||
command: dotnet run --project Tools/LocalizationAudit
|
||
fail_on: missing_keys | overflow_detected
|
||
|
||
- name: Physics Layer Validation
|
||
command: unity -runTests -testPlatform EditMode -testFilter PhysicsLayerTests
|
||
fail_on: any_test_failure
|
||
|
||
- name: Code Coverage (minimum 60%)
|
||
command: unity -runTests -enableCodeCoverage
|
||
fail_on: coverage_below_60_percent
|
||
```
|
||
|
||
**门禁规则**:任何门禁失败,PR 不可合并,必须修复后重新提交。
|
||
|
||
---
|
||
|
||
*本文档版本 1.0 · 2026-04 · 关联 49_AntiSoftlockSystem / 56_CrashRecoverySystem / 46_PlatformIntegration*
|