chore: initial commit

This commit is contained in:
2026-05-08 11:04:00 +08:00
commit f55d2a57c3
6278 changed files with 866081 additions and 0 deletions

View File

@@ -0,0 +1,338 @@
# 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 FrameworkEditMode + PlayMode
- Custom QA CI RunnerGitHub Actions / 本地 MSBuild
- GameCI DockerUnity 无头构建)
- 手动 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 SwitchTV 模式)| 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*