test-setup
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTest Setup
测试框架搭建
This skill scaffolds the automated testing infrastructure for the project.
It detects the configured engine, generates the appropriate test runner
configuration, creates the standard directory layout, and wires up CI/CD
so tests run on every push.
Run this once during the Technical Setup phase, before any implementation
begins. A test framework installed at sprint start costs 30 minutes.
A test framework installed at sprint four costs 3 sprints.
Output: directory structure +
tests/.github/workflows/tests.yml这个Skill为项目搭建自动化测试基础设施。它会检测已配置的引擎,生成对应的测试运行器配置,创建标准目录结构,并配置CI/CD,确保每次推送代码时自动运行测试。
需在技术设置阶段、任何开发工作开始前运行一次。在Sprint初期安装测试框架仅需30分钟,而在第四个Sprint才安装则会耗费3个Sprint的时间。
输出: 目录结构 +
tests/.github/workflows/tests.ymlPhase 1: Detect Engine and Existing State
阶段1:检测引擎与现有状态
-
Read engine config:
- Read and extract the
.claude/docs/technical-preferences.mdvalue.Engine: - If engine is not configured (), stop: "Engine not configured. Run
[TO BE CONFIGURED]first, then re-run/setup-engine."/test-setup
- Read
-
Check for existing test infrastructure:
- Glob — does the directory exist?
tests/ - Glob and
tests/unit/— do subdirectories exist?tests/integration/ - Glob — does a CI workflow file exist?
.github/workflows/ - Glob (Godot) or
tests/gdunit4_runner.gd(Unity) ortests/EditMode/(Unreal) for engine-specific artifacts.Source/Tests/
- Glob
-
Report findings:
- "Engine: [engine]. Test directory: [found / not found]. CI workflow: [found / not found]."
- If everything already exists AND argument was not passed: "Test infrastructure appears to be in place. Re-run with
forceto regenerate. Proceeding will not overwrite existing test files."/test-setup force
If the argument is passed, skip the "already exists" early-exit and
proceed — but still do not overwrite files that already exist at a given path.
Only create files that are missing.
force-
读取引擎配置:
- 读取 并提取
.claude/docs/technical-preferences.md的值。Engine: - 若引擎未配置(值为),则终止操作: "引擎未配置,请先运行
[TO BE CONFIGURED],再重新运行/setup-engine。"/test-setup
- 读取
-
检查现有测试基础设施:
- 查找 目录是否存在?
tests/ - 查找 和
tests/unit/子目录是否存在?tests/integration/ - 查找 目录下是否存在CI工作流文件?
.github/workflows/ - 查找引擎专属文件,如Godot的、Unity的
tests/gdunit4_runner.gd或Unreal的tests/EditMode/。Source/Tests/
- 查找
-
报告检测结果:
- "引擎:[engine]。测试目录:[已找到/未找到]。CI工作流:[已找到/未找到]。"
- 若所有内容已存在且未传入参数: "测试基础设施已就绪。如需重新生成,请使用
force运行。继续操作不会覆盖现有测试文件。"/test-setup force
若传入参数,则跳过"已存在"的提前终止步骤,继续执行——但仍不会覆盖已存在路径下的文件,仅创建缺失的文件。
forcePhase 2: Present Plan
阶段2:展示执行计划
Based on the engine detected and the existing state, present a plan:
undefined基于检测到的引擎和现有状态,展示执行计划:
undefinedTest Setup Plan — [Engine]
测试框架搭建计划 — [Engine]
I will create the following (skipping any that already exist):
tests/
unit/ — Isolated unit tests for formulas, state, and logic
integration/ — Cross-system tests and save/load round-trips
smoke/ — Critical path test list (15-minute manual gate)
evidence/ — Screenshot and manual test sign-off records
README.md — Test framework documentation
[Engine-specific files — see per-engine details below]
.github/workflows/tests.yml — CI: run tests on every push to main
Estimated time: ~5 minutes to create all files.
Ask: "May I create these files? I will not overwrite any test files that
already exist at these paths."
Do not proceed without approval.
---我将创建以下内容(已存在的会跳过):
tests/
unit/ — 用于公式、状态和逻辑的独立单元测试
integration/ — 跨系统测试与保存/加载往返测试
smoke/ — 关键路径测试清单(15分钟手动校验)
evidence/ — 截图与手动测试签署记录
README.md — 测试框架文档
[引擎专属文件 — 详见下方各引擎说明]
.github/workflows/tests.yml — CI配置:每次推送至main分支时运行测试
预计耗时:约5分钟创建所有文件。
询问:"是否允许我创建这些文件?我不会覆盖任何已存在路径下的测试文件。"
未获得批准前请勿继续执行。
---Phase 3: Create Directory Structure
阶段3:创建目录结构
After approval, create the following files:
获得批准后,创建以下文件:
tests/README.md
tests/README.mdtests/README.md
tests/README.mdmarkdown
undefinedmarkdown
undefinedTest Infrastructure
测试基础设施
Engine: [engine name + version]
Test Framework: [GdUnit4 | Unity Test Framework | UE Automation]
CI:
Setup date: [date]
.github/workflows/tests.yml引擎: [引擎名称 + 版本]
测试框架: [GdUnit4 | Unity Test Framework | UE Automation]
CI:
搭建日期: [日期]
.github/workflows/tests.ymlDirectory Layout
目录结构
tests/
unit/ # Isolated unit tests (formulas, state machines, logic)
integration/ # Cross-system and save/load tests
smoke/ # Critical path test list for /smoke-check gate
evidence/ # Screenshot logs and manual test sign-off recordstests/
unit/ # 独立单元测试(公式、状态机、逻辑)
integration/ # 跨系统与保存/加载测试
smoke/ # 用于/smoke-check校验的关键路径测试清单
evidence/ # 截图日志与手动测试签署记录Running Tests
运行测试
[Engine-specific command — see below]
[引擎专属命令 — 详见下方]
Test Naming
测试命名规范
- Files:
[system]_[feature]_test.[ext] - Functions:
test_[scenario]_[expected] - Example: →
combat_damage_test.gdtest_base_attack_returns_expected_damage()
- 文件:
[system]_[feature]_test.[ext] - 函数:
test_[scenario]_[expected] - 示例: →
combat_damage_test.gdtest_base_attack_returns_expected_damage()
Story Type → Test Evidence
需求类型 → 测试证据要求
| Story Type | Required Evidence | Location |
|---|---|---|
| Logic | Automated unit test — must pass | |
| Integration | Integration test OR playtest doc | |
| Visual/Feel | Screenshot + lead sign-off | |
| UI | Manual walkthrough OR interaction test | |
| Config/Data | Smoke check pass | |
| 需求类型 | 所需证据 | 存放位置 |
|---|---|---|
| 逻辑类 | 自动化单元测试 — 必须通过 | |
| 集成类 | 集成测试或游戏测试文档 | |
| 视觉/体验类 | 截图 + 负责人签署 | |
| UI类 | 手动 walkthrough 或交互测试 | |
| 配置/数据类 | Smoke测试通过 | |
CI
CI说明
Tests run automatically on every push to and on every pull request.
A failed test suite blocks merging.
mainundefined测试会在每次推送至分支和每次提交Pull Request时自动运行。测试套件失败会阻止合并操作。
mainundefinedEngine-specific files
引擎专属文件
Godot 4 (Engine: Godot
)
Engine: GodotGodot 4 (Engine: Godot
)
Engine: GodotCreate :
tests/gdunit4_runner.gdgdscript
undefined创建 :
tests/gdunit4_runner.gdgdscript
undefinedGdUnit4 test runner — invoked by CI and /smoke-check
GdUnit4 test runner — invoked by CI and /smoke-check
Usage: godot --headless --script tests/gdunit4_runner.gd
Usage: godot --headless --script tests/gdunit4_runner.gd
extends SceneTree
func _init() -> void:
var runner := load("res://addons/gdunit4/GdUnitRunner.gd")
if runner == null:
push_error("GdUnit4 not found. Install via AssetLib or addons/.")
quit(1)
return
var instance = runner.new()
instance.run_tests()
quit(0)
Create `tests/unit/.gdignore_placeholder` with content:
`# Unit tests go here — one subdirectory per system (e.g., tests/unit/combat/)`
Create `tests/integration/.gdignore_placeholder` with content:
`# Integration tests go here — one subdirectory per system`
Note in the README: **Installing GdUnit4**- Open Godot → AssetLib → search "GdUnit4" → Download & Install
- Enable the plugin: Project → Project Settings → Plugins → GdUnit4 ✓
- Restart the editor
- Verify: res://addons/gdunit4/ exists
undefinedextends SceneTree
func _init() -> void:
var runner := load("res://addons/gdunit4/GdUnitRunner.gd")
if runner == null:
push_error("GdUnit4 not found. Install via AssetLib or addons/.")
quit(1)
return
var instance = runner.new()
instance.run_tests()
quit(0)
创建 `tests/unit/.gdignore_placeholder`,内容为:
`# Unit tests go here — one subdirectory per system (e.g., tests/unit/combat/)`
创建 `tests/integration/.gdignore_placeholder`,内容为:
`# Integration tests go here — one subdirectory per system`
在README中添加说明:**安装GdUnit4**- 打开Godot → AssetLib → 搜索 "GdUnit4" → 下载并安装
- 启用插件:Project → Project Settings → Plugins → GdUnit4 ✓
- 重启编辑器
- 验证:res://addons/gdunit4/ 目录存在
undefinedUnity (Engine: Unity
)
Engine: UnityUnity (Engine: Unity
)
Engine: UnityCreate placeholder file :
tests/EditMode/tests/EditMode/README.mdmarkdown
undefined创建 占位文件 :
tests/EditMode/tests/EditMode/README.mdmarkdown
undefinedEdit Mode Tests
Edit Mode Tests
Unit tests that run without entering Play Mode.
Use for pure logic: formulas, state machines, data validation.
Assembly definition required:
tests/EditMode/EditModeTests.asmdef
Create `tests/PlayMode/README.md`:
```markdownUnit tests that run without entering Play Mode.
Use for pure logic: formulas, state machines, data validation.
Assembly definition required:
tests/EditMode/EditModeTests.asmdef
创建 `tests/PlayMode/README.md`:
```markdownPlay Mode Tests
Play Mode Tests
Integration tests that run in a real game scene.
Use for cross-system interactions, physics, and coroutines.
Assembly definition required:
tests/PlayMode/PlayModeTests.asmdef
Note in the README: **Enabling Unity Test Framework**Window → General → Test Runner
(Unity Test Framework is included by default in Unity 2019+)
undefinedIntegration tests that run in a real game scene.
Use for cross-system interactions, physics, and coroutines.
Assembly definition required:
tests/PlayMode/PlayModeTests.asmdef
在README中添加说明:**启用Unity Test Framework**Window → General → Test Runner
(Unity Test Framework is included by default in Unity 2019+)
undefinedUnreal Engine (Engine: Unreal
or Engine: UE5
)
Engine: UnrealEngine: UE5Unreal Engine (Engine: Unreal
或 Engine: UE5
)
Engine: UnrealEngine: UE5Create :
Source/Tests/README.mdmarkdown
undefined创建 :
Source/Tests/README.mdmarkdown
undefinedUnreal Automation Tests
Unreal Automation Tests
Tests use the UE Automation Testing Framework.
Run via: Session Frontend → Automation → select "MyGame." tests
Or headlessly: UnrealEditor -nullrhi -ExecCmds="Automation RunTests MyGame.; Quit"
Test class naming: F[SystemName]Test
Test category naming: "MyGame.[System].[Feature]"
---Tests use the UE Automation Testing Framework.
Run via: Session Frontend → Automation → select "MyGame." tests
Or headlessly: UnrealEditor -nullrhi -ExecCmds="Automation RunTests MyGame.; Quit"
Test class naming: F[SystemName]Test
Test category naming: "MyGame.[System].[Feature]"
---Phase 4: Create CI/CD Workflow
阶段4:创建CI/CD工作流
Godot 4
Godot 4
Create :
.github/workflows/tests.ymlyaml
name: Automated Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
name: Run GdUnit4 Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
lfs: true
- name: Run GdUnit4 Tests
uses: MikeSchulze/gdUnit4-action@v1
with:
godot-version: '[VERSION FROM docs/engine-reference/godot/VERSION.md]'
paths: |
tests/unit
tests/integration
report-name: test-results
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: reports/创建 :
.github/workflows/tests.ymlyaml
name: Automated Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
name: Run GdUnit4 Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
lfs: true
- name: Run GdUnit4 Tests
uses: MikeSchulze/gdUnit4-action@v1
with:
godot-version: '[VERSION FROM docs/engine-reference/godot/VERSION.md]'
paths: |
tests/unit
tests/integration
report-name: test-results
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: reports/Unity
Unity
Create :
.github/workflows/tests.ymlyaml
name: Automated Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
name: Run Unity Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
lfs: true
- name: Run Edit Mode Tests
uses: game-ci/unity-test-runner@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
with:
testMode: editmode
artifactsPath: test-results/editmode
- name: Run Play Mode Tests
uses: game-ci/unity-test-runner@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
with:
testMode: playmode
artifactsPath: test-results/playmode
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: test-results/Note: Unity CI requires a secret. Add to GitHub repository
secrets before the first CI run.
UNITY_LICENSE创建 :
.github/workflows/tests.ymlyaml
name: Automated Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
name: Run Unity Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
lfs: true
- name: Run Edit Mode Tests
uses: game-ci/unity-test-runner@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
with:
testMode: editmode
artifactsPath: test-results/editmode
- name: Run Play Mode Tests
uses: game-ci/unity-test-runner@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
with:
testMode: playmode
artifactsPath: test-results/playmode
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: test-results/注意:Unity CI需要配置密钥。请在首次CI运行前添加至GitHub仓库密钥中。
UNITY_LICENSEUnreal Engine
Unreal Engine
Create :
.github/workflows/tests.ymlyaml
name: Automated Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
name: Run UE Automation Tests
runs-on: self-hosted # UE requires a local runner with the editor installed
steps:
- name: Checkout
uses: actions/checkout@v4
with:
lfs: true
- name: Run Automation Tests
run: |
"$UE_EDITOR_PATH" "${{ github.workspace }}/[ProjectName].uproject" \
-nullrhi -nosound \
-ExecCmds="Automation RunTests MyGame.; Quit" \
-log -unattended
shell: bash
- name: Upload Logs
if: always()
uses: actions/upload-artifact@v4
with:
name: test-logs
path: Saved/Logs/Note: UE CI requires a self-hosted runner with Unreal Editor installed.
Set the environment variable on the runner.
UE_EDITOR_PATH创建 :
.github/workflows/tests.ymlyaml
name: Automated Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
name: Run UE Automation Tests
runs-on: self-hosted # UE requires a local runner with the editor installed
steps:
- name: Checkout
uses: actions/checkout@v4
with:
lfs: true
- name: Run Automation Tests
run: |
"$UE_EDITOR_PATH" "${{ github.workspace }}/[ProjectName].uproject" \
-nullrhi -nosound \
-ExecCmds="Automation RunTests MyGame.; Quit" \
-log -unattended
shell: bash
- name: Upload Logs
if: always()
uses: actions/upload-artifact@v4
with:
name: test-logs
path: Saved/Logs/注意:UE CI需要安装有Unreal Editor的自托管运行器。请在运行器上设置环境变量。
UE_EDITOR_PATHPhase 5: Create Smoke Test Seed
阶段5:创建Smoke测试初始文件
Create :
tests/smoke/critical-paths.mdmarkdown
undefined创建 :
tests/smoke/critical-paths.mdmarkdown
undefinedSmoke Test: Critical Paths
Smoke Test: Critical Paths
Purpose: Run these 10-15 checks in under 15 minutes before any QA hand-off.
Run via: (which reads this file)
Update: Add new entries when new core systems are implemented.
/smoke-checkPurpose: Run these 10-15 checks in under 15 minutes before any QA hand-off.
Run via: (which reads this file)
Update: Add new entries when new core systems are implemented.
/smoke-checkCore Stability (always run)
Core Stability (always run)
- Game launches to main menu without crash
- New game / session can be started from the main menu
- Main menu responds to all inputs without freezing
- Game launches to main menu without crash
- New game / session can be started from the main menu
- Main menu responds to all inputs without freezing
Core Mechanic (update per sprint)
Core Mechanic (update per sprint)
<!-- Add the primary mechanic for each sprint here as it is implemented -->
<!-- Example: "Player can move, jump, and the camera follows correctly" -->
- [Primary mechanic — update when first core system is implemented]
<!-- Add the primary mechanic for each sprint here as it is implemented -->
<!-- Example: "Player can move, jump, and the camera follows correctly" -->
- [Primary mechanic — update when first core system is implemented]
Data Integrity
Data Integrity
- Save game completes without error (once save system is implemented)
- Load game restores correct state (once load system is implemented)
- Save game completes without error (once save system is implemented)
- Load game restores correct state (once load system is implemented)
Performance
Performance
- No visible frame rate drops on target hardware (60fps target)
- No memory growth over 5 minutes of play (once core loop is implemented)
---- No visible frame rate drops on target hardware (60fps target)
- No memory growth over 5 minutes of play (once core loop is implemented)
---Phase 6: Post-Setup Summary
阶段6:搭建完成总结
After writing all files, report:
Test infrastructure created for [engine].
Files created:
- tests/README.md
- tests/unit/ (directory)
- tests/integration/ (directory)
- tests/smoke/critical-paths.md
- tests/evidence/ (directory)
[engine-specific files]
- .github/workflows/tests.yml
Next steps:
1. [Engine-specific install step, e.g., "Install GdUnit4 via AssetLib"]
2. Write your first test: create tests/unit/[first-system]/[system]_test.[ext]
3. Run `/qa-plan sprint` before your first sprint to classify stories and set
test evidence requirements
4. `/smoke-check` before every QA hand-off
Gate note: /gate-check Technical Setup → Pre-Production now requires:
- tests/ directory with unit/ and integration/ subdirectories
- .github/workflows/tests.yml
- At least one example test file
Run /test-setup and write one example test before advancing.
Verdict: **COMPLETE** — test framework scaffolded and CI/CD wired up.所有文件创建完成后,输出报告:
已为[engine]创建测试基础设施。
已创建文件:
- tests/README.md
- tests/unit/ (目录)
- tests/integration/ (目录)
- tests/smoke/critical-paths.md
- tests/evidence/ (目录)
[引擎专属文件]
- .github/workflows/tests.yml
后续步骤:
1. [引擎专属安装步骤,例如:"通过AssetLib安装GdUnit4"]
2. 编写你的第一个测试:创建 tests/unit/[first-system]/[system]_test.[ext]
3. 在首个Sprint前运行 `/qa-plan sprint` 对需求进行分类,并设置测试证据要求
4. 每次QA交付前运行 `/smoke-check`
校验说明:/gate-check Technical Setup → Pre-Production 现在要求:
- 包含unit/和integration/子目录的tests/目录
- .github/workflows/tests.yml
- 至少一个示例测试文件
请在推进前运行/test-setup并编写一个示例测试。
结论:**完成** — 测试框架已搭建完成,CI/CD已配置就绪。Collaborative Protocol
协作规则
- Never overwrite existing test files — only create files that are missing. If a test runner file exists, leave it as-is.
- Always ask before creating files — Phase 2 requires explicit approval.
- Engine detection is non-negotiable — if the engine is not configured,
stop and redirect to . Do not guess.
/setup-engine - flag skips the "already exists" early-exit but never overwrites. It means "create any missing files even if the directory already exists."
force - For Unity CI, note that the secret must be configured manually. Do not attempt to automate license management.
UNITY_LICENSE
- 切勿覆盖现有测试文件 — 仅创建缺失的文件。若测试运行器文件已存在,请保持原样。
- 创建文件前务必获得批准 — 阶段2需要明确的批准。
- 引擎检测不可省略 — 若引擎未配置,请终止操作并引导用户运行,切勿猜测。
/setup-engine - 参数会跳过"已存在"的提前终止步骤,但仍不会覆盖文件。它的含义是"即使目录已存在,也创建所有缺失的文件"。
force - 对于Unity CI,请注意密钥必须手动配置,请勿尝试自动化许可证管理。
UNITY_LICENSE