mirror of
https://github.com/Donchitos/Claude-Code-Game-Studios.git
synced 2026-10-16 10:17:06 +00:00
Release 1.1.2 — the default path works end to end
Fix release for 1.1.1: the minimal path end to end, engine commands that run on Godot, Unity and Unreal, hook warnings you can see, and verdicts that say when they could not check. Details in CHANGELOG.md; upgrade steps in UPGRADING.md (v1.1.1 → v1.1.2). Fixes #67 Fixes #131 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WuJn2FdynEybfL5KC697nJ
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
7ed2c3e9c4
commit
b21fa0f7f2
@@ -7,7 +7,7 @@ allowed-tools: Read, Glob, Grep, Bash, Write, Bash(bash "*/.claude/skills/test-s
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
!`bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys automation`
|
||||
!`bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys automation,workflow,qa.level`
|
||||
|
||||
**Automation mode**: Resolve `modes.automation` (`project.local.yaml` →
|
||||
`project.yaml` → default `collaborative`). Every `AskUserQuestion` call and
|
||||
@@ -45,8 +45,11 @@ A test framework installed at sprint four costs 3 sprints.
|
||||
- Glob `tests/` — does the directory exist?
|
||||
- Glob `tests/unit/` and `tests/integration/` — do subdirectories exist?
|
||||
- Glob `.github/workflows/` — does a CI workflow file exist?
|
||||
- Glob `tests/gdunit4_runner.gd` (Godot) or `tests/EditMode/` (Unity) or
|
||||
`Source/Tests/` (Unreal) for engine-specific artifacts.
|
||||
- Glob `addons/gdUnit4/bin/GdUnitCmdTool.gd` (Godot — note the capital U) or
|
||||
`Assets/Tests/EditMode/` (Unity) or `Source/*/Private/Tests/` (Unreal) for
|
||||
engine-specific artifacts. These are the **test roots** in
|
||||
`.claude/docs/directory-structure.md`; tests anywhere else are never compiled
|
||||
on Unity or Unreal.
|
||||
|
||||
3. **Report findings**:
|
||||
- "Engine: [engine]. Test directory: [found / not found]. CI workflow: [found / not found]."
|
||||
@@ -70,11 +73,15 @@ Based on the engine detected and the existing state, present a plan:
|
||||
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
|
||||
unit/ — Isolated unit tests for formulas, state, and logic (Godot only)
|
||||
integration/ — Cross-system tests and save/load round-trips (Godot only)
|
||||
smoke/ — Critical path test list (15-minute manual gate)
|
||||
README.md — Test framework documentation
|
||||
|
||||
[Unity/Unreal: unit and integration tests go under the engine's test root
|
||||
instead — Unity Assets/Tests/EditMode|PlayMode/, Unreal
|
||||
Source/<Module>/Private/Tests/ — because neither compiles code in tests/]
|
||||
|
||||
production/qa/
|
||||
evidence/ — Screenshot and manual test sign-off records
|
||||
|
||||
@@ -102,7 +109,7 @@ After approval, create the following files:
|
||||
|
||||
### `tests/README.md`
|
||||
|
||||
```markdown
|
||||
````markdown
|
||||
# Test Infrastructure
|
||||
|
||||
**Engine**: [engine name + version]
|
||||
@@ -119,17 +126,18 @@ tests/
|
||||
smoke/ # Critical path test list for /smoke-check gate
|
||||
```
|
||||
|
||||
[Unity/Unreal — replace the unit/integration lines: unit and integration tests
|
||||
live under the engine's test root, `Assets/Tests/EditMode|PlayMode/[System]/`
|
||||
or `Source/<Module>/Private/Tests/[System]/`; `tests/` keeps this README and
|
||||
`smoke/`. Every `tests/unit/` path below means that test root.]
|
||||
|
||||
```
|
||||
production/qa/
|
||||
evidence/ # Screenshot logs and manual test sign-off records
|
||||
```
|
||||
|
||||
> **Manual evidence lives under `production/qa/evidence/`, not `tests/`.** That is
|
||||
> where every consumer reads it — `/smoke-check`, `/test-evidence-review`,
|
||||
> `/qa-plan`, and the evidence table in `.claude/docs/coding-standards.md`. This
|
||||
> scaffold and this skill's completion summary must name the same path: listing
|
||||
> `tests/evidence/` here while the summary reports `production/qa/evidence/`
|
||||
> creates a directory nothing reads and skips the one everything does.
|
||||
> **Manual evidence lives under `production/qa/evidence/`, not `tests/`** — that
|
||||
> is where every consumer reads it.
|
||||
|
||||
## Running Tests
|
||||
|
||||
@@ -137,9 +145,15 @@ production/qa/
|
||||
|
||||
## Test Naming
|
||||
|
||||
- **Files**: `[system]_[feature]_test.[ext]`
|
||||
- **Functions**: `test_[scenario]_[expected]`
|
||||
- **Example**: `combat_damage_test.gd` → `test_base_attack_returns_expected_damage()`
|
||||
Names follow the engine's language (`.claude/rules/test-standards.md`):
|
||||
- **Godot**: file `[system]_[feature]_test.gd`, function `test_[scenario]_[expected]`
|
||||
— `combat_damage_test.gd` → `test_base_attack_returns_expected_damage()`
|
||||
- **Unity**: class `[System]Tests` in `[System]Tests.cs`, method `[Scenario]_[Expected]`
|
||||
— `CombatTests.cs` → `BaseAttack_ReturnsExpectedDamage()`
|
||||
- **Unreal**: class `F[System][Scenario]Test`, test name `<Project>.[System].[Scenario]`
|
||||
— `FCombatBaseAttackTest` → `<Project>.Combat.BaseAttack`
|
||||
[`<Project>` is the root the filter in `commands.test` uses — write it out:
|
||||
the project name, or the distinct root `/setup-engine` chose]
|
||||
|
||||
## Story Type → Test Evidence
|
||||
|
||||
@@ -148,38 +162,57 @@ production/qa/
|
||||
| Logic | Automated unit test — must pass | `tests/unit/[system]/` |
|
||||
| Integration | Integration test OR playtest doc | `tests/integration/[system]/` |
|
||||
| Visual/Feel | Screenshot + lead sign-off | `production/qa/evidence/` |
|
||||
| UI | Manual walkthrough OR interaction test | `production/qa/evidence/` |
|
||||
| UI | Retained screenshot of each screen touched | `production/qa/evidence/` |
|
||||
| Config/Data | Smoke check pass | `production/qa/smoke-*.md` |
|
||||
|
||||
## CI
|
||||
|
||||
Tests run automatically on every push to `main` and on every pull request.
|
||||
A failed test suite blocks merging.
|
||||
```
|
||||
```
|
||||
````
|
||||
|
||||
The README and this skill's completion summary name the same evidence path —
|
||||
`production/qa/evidence/` is where `/smoke-check`, `/test-evidence-review`,
|
||||
`/qa-plan` and the evidence table in `.claude/docs/coding-standards.md` read,
|
||||
so a `tests/evidence/` would be a directory nothing reads.
|
||||
|
||||
### `production/qa/evidence/.gitkeep`
|
||||
|
||||
Create it empty. Git does not keep an empty directory, and this is where
|
||||
`/story-done`, `/smoke-check` and `/test-evidence-review` look for screenshots and
|
||||
sign-off records — the completion summary lists it, so it must exist.
|
||||
|
||||
### Engine-specific files
|
||||
|
||||
#### Godot 4 (`Engine: Godot`)
|
||||
|
||||
Create `tests/gdunit4_runner.gd`:
|
||||
**Do not write a runner script.** gdUnit4 ships its own command-line runner,
|
||||
`res://addons/gdUnit4/bin/GdUnitCmdTool.gd`. The command CI, `/smoke-check`
|
||||
and `commands.test` use is:
|
||||
|
||||
```gdscript
|
||||
# GdUnit4 test runner — invoked by CI and /smoke-check
|
||||
# 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)
|
||||
```bash
|
||||
godot --headless --path . --import
|
||||
godot --headless -s -d --remote-debug tcp://127.0.0.1:0 res://addons/gdUnit4/bin/GdUnitCmdTool.gd -a res://tests --ignoreHeadlessMode
|
||||
```
|
||||
|
||||
Run the import first. A fresh clone has no `.godot/` class cache, and a run
|
||||
without one exits **1** — `GdUnitCmdTool.gd` did not load (`Failed to load
|
||||
script`), so no test ran. A cache older than a new `class_name` fails valid
|
||||
code with 105. The CI action imports on its own.
|
||||
|
||||
Exit code **0** when every test passes and **100** when any fails — verified
|
||||
on Godot 4.6.1 with gdUnit4 6.1.3. **101** means every test passed but a test
|
||||
leaked nodes: a warning, not a failure. 103 and 104 mean gdUnit4 could not run
|
||||
(headless refused, Godot older than 4.3); 105 means a test script does not parse. `-a res://tests` runs every suite
|
||||
under `tests/`; `--ignoreHeadlessMode` is required because gdUnit4 otherwise
|
||||
refuses to run headless. `--remote-debug tcp://127.0.0.1:0` is required too —
|
||||
it is what gdUnit4's own `runtest` script passes. Without it a script error
|
||||
opens Godot's interactive debugger, and the run waits at a `debug>` prompt
|
||||
forever instead of exiting 105. The flag makes every run print two `ERROR:`
|
||||
lines about the remote port (`127.0.0.1:0`); they are expected, not a failure.
|
||||
A run that finds no tests prints `No test cases found` and exits 0 — that is
|
||||
not a pass. The folder is `addons/gdUnit4/` with a **capital U**.
|
||||
|
||||
Create `tests/unit/.gdignore_placeholder` with content:
|
||||
`# Unit tests go here — one subdirectory per system (e.g., tests/unit/combat/)`
|
||||
|
||||
@@ -191,44 +224,116 @@ Note in the README: **Installing GdUnit4**
|
||||
1. Open Godot → AssetLib → search "GdUnit4" → Download & Install
|
||||
2. Enable the plugin: Project → Project Settings → Plugins → GdUnit4 ✓
|
||||
3. Restart the editor
|
||||
4. Verify: res://addons/gdunit4/ exists
|
||||
4. Verify: res://addons/gdUnit4/bin/GdUnitCmdTool.gd exists (capital U)
|
||||
```
|
||||
|
||||
#### Unity (`Engine: Unity`)
|
||||
|
||||
Create `tests/EditMode/` placeholder file `tests/EditMode/README.md`:
|
||||
```markdown
|
||||
# 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`
|
||||
Tests live under **`Assets/Tests/`** — Unity compiles only `Assets/` and
|
||||
`Packages/`. A test under `tests/` is never compiled, and the run then reports
|
||||
**0 tests, `Passed`, exit 0** (verified on 6000.3.23f1): a false pass.
|
||||
|
||||
First check the Test Framework package:
|
||||
`grep -q 'com.unity.test-framework' Packages/manifest.json`. Without it
|
||||
`-runTests` does not fail — it hangs. If absent, ask to add
|
||||
`"com.unity.test-framework"` to `dependencies` at the version your editor
|
||||
bundles. Unity 6 releases bundle different ones — 1.6.0 in 6000.3.23f1, 1.5.1 in
|
||||
6000.1.0f1 — so read it rather than copy a number: on Windows it is the
|
||||
`version` in `Data/Resources/PackageManager/BuiltInPackages/com.unity.test-framework/package.json`
|
||||
under the folder that holds `Unity.exe`.
|
||||
|
||||
Create `Assets/Tests/EditMode/EditModeTests.asmdef` — unit tests, no Play Mode:
|
||||
```json
|
||||
{
|
||||
"name": "EditModeTests",
|
||||
"references": ["UnityEngine.TestRunner", "UnityEditor.TestRunner"],
|
||||
"includePlatforms": ["Editor"],
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": ["nunit.framework.dll"],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": ["UNITY_INCLUDE_TESTS"]
|
||||
}
|
||||
```
|
||||
|
||||
Create `tests/PlayMode/README.md`:
|
||||
```markdown
|
||||
# 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`
|
||||
```
|
||||
Create `Assets/Tests/PlayMode/PlayModeTests.asmdef` — integration tests in a
|
||||
running scene: the same JSON with `"name": "PlayModeTests"` and
|
||||
`"includePlatforms": []`.
|
||||
|
||||
Note in the README: **Enabling Unity Test Framework**
|
||||
> **A test assembly cannot see code in the default `Assembly-CSharp`.** An
|
||||
> `.asmdef` can reference only other `.asmdef`s. If the game's scripts have no
|
||||
> `.asmdef` of their own, ask before creating one (e.g. `Assets/Scripts/Game.asmdef`)
|
||||
> and add `"Game"` to both test assemblies' `references`. Without it the first
|
||||
> test that names a game class fails to compile. Moving scripts into an
|
||||
> `.asmdef` changes what they can see, so before creating it:
|
||||
>
|
||||
> - **List the packages the scripts use.** `Assembly-CSharp` references every
|
||||
> package on its own; an `.asmdef` references only what it names. Read the
|
||||
> scripts' `using` lines and add the matching assemblies — commonly
|
||||
> `"Unity.InputSystem"`, `"Unity.TextMeshPro"`, `"UnityEngine.UI"`:
|
||||
> `{ "name": "Game", "references": ["Unity.InputSystem", "Unity.TextMeshPro"] }`.
|
||||
> Name only packages the project has installed.
|
||||
> - **Give each `Editor/` folder under it its own `.asmdef`** with
|
||||
> `"includePlatforms": ["Editor"]` and `"references": ["Game"]`. Otherwise
|
||||
> editor scripts join the runtime assembly, and `using UnityEditor;` breaks the
|
||||
> player build.
|
||||
|
||||
Note in the README: **Running Unity tests** (use the editor executable —
|
||||
`Unity` on `PATH` may be Unity's separate CLI, not the editor)
|
||||
```
|
||||
Window → General → Test Runner
|
||||
(Unity Test Framework is included by default in Unity 2019+)
|
||||
"<Unity editor>" -batchmode -runTests -projectPath . -testPlatform EditMode -testResults test-results/editmode.xml
|
||||
"<Unity editor>" -batchmode -runTests -projectPath . -testPlatform PlayMode -testResults test-results/playmode.xml
|
||||
```
|
||||
Exit **0** when every test passes, **2** when any fails. Exit 1 or 3 is a FAIL
|
||||
too: 1 is a compile error, which writes no results file, and 3 a failed run.
|
||||
So is 4 (an unknown `-testPlatform`), and any other non-zero exit.
|
||||
Delete `test-results/editmode.xml` before each run so an old file is never read
|
||||
as a new result. Read the `<test-run>`
|
||||
element of the results file: `testcasecount="0"` means nothing was compiled or
|
||||
found — report it as not assessed, never as a pass. Do not add `-quit`;
|
||||
`-runTests` exits by itself. Play Mode is the second line: a separate run with
|
||||
its own results file, read the same way, and deleted before each run the same
|
||||
way. An Edit Mode run never runs the tests in `Assets/Tests/PlayMode/`, so
|
||||
`/smoke-check` runs both whenever that folder holds tests.
|
||||
|
||||
#### Unreal Engine (`Engine: Unreal` or `Engine: UE5`)
|
||||
|
||||
Create `Source/Tests/README.md`:
|
||||
Tests live **inside the game module**: `Source/<Module>/Private/Tests/`, where
|
||||
`<Module>` is the primary game module (for a C++ project, the `.uproject` name).
|
||||
UnrealBuildTool compiles only module folders — a tests folder directly under
|
||||
`Source/` is not a module, so a test there is silently never built and every
|
||||
run reports `No automation tests matched`.
|
||||
|
||||
Create `Source/<Module>/Private/Tests/README.md`. `<Project>.` in it — and
|
||||
`[ProjectName].` in the CI filter below — is the test root the filter in
|
||||
`commands.test` uses: the project name, or the distinct root `/setup-engine`
|
||||
chose when the project's name is also an engine area. Write that root:
|
||||
```markdown
|
||||
# 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"
|
||||
Tests use the UE Automation Testing Framework and compile with this module.
|
||||
Wrap each test file in `#if WITH_DEV_AUTOMATION_TESTS` … `#endif`.
|
||||
Flags: `EAutomationTestFlags::EditorContext | EAutomationTestFlags::ProductFilter`
|
||||
(there is no `GameFilter` flag).
|
||||
|
||||
Test class naming: F[SystemName]Test
|
||||
Test category naming: "MyGame.[System].[Feature]"
|
||||
Run via: Session Frontend → Automation → select "<Project>." tests
|
||||
Or headlessly from the project root, after building the editor target — on a
|
||||
fresh checkout the editor exits before any test runs:
|
||||
"<UE root>/Engine/Binaries/DotNET/UnrealBuildTool/UnrealBuildTool.exe" <Project>Editor Win64 Development -Project="$(pwd -W 2>/dev/null || pwd)/<Project>.uproject"
|
||||
"<UE root>/Engine/Binaries/Win64/UnrealEditor-Cmd.exe" "$(pwd -W 2>/dev/null || pwd)/<Project>.uproject" -ExecCmds="Automation RunTests <Project>.; Quit" -unattended -nullrhi -stdout -FullStdOutLogOutput
|
||||
The project path must be absolute: UE does not find a relative one (exit 1,
|
||||
"Project file not found"). Those two lines are Windows'. On Linux build with
|
||||
`Engine/Build/BatchFiles/Linux/Build.sh <Project>Editor Linux Development -Project="$(pwd -W 2>/dev/null || pwd)/<Project>.uproject"` and run
|
||||
the tests with `Engine/Binaries/Linux/UnrealEditor` and the same arguments; on
|
||||
macOS build with `Engine/Build/BatchFiles/Mac/Build.sh <Project>Editor Mac Development -Project="$(pwd -W 2>/dev/null || pwd)/<Project>.uproject"`
|
||||
— Epic documents no command-line editor inside `UnrealEditor.app` for the test
|
||||
run (see `docs/engine-reference/unreal/current-best-practices.md`, "Command Line").
|
||||
|
||||
Read the output, not the exit code: a failing test and a run that matched nothing both exit 255.
|
||||
`Result={Fail}` is a failure; `No automation tests matched` means no test was
|
||||
built or named `<Project>.…`.
|
||||
|
||||
Test class naming: F[System][Scenario]Test — one class per test; a second
|
||||
test reusing a class name fails to link
|
||||
Test name: "<Project>.[System].[Scenario]"
|
||||
```
|
||||
|
||||
---
|
||||
@@ -252,6 +357,14 @@ jobs:
|
||||
test:
|
||||
name: Run GdUnit4 Tests
|
||||
runs-on: ubuntu-latest
|
||||
# The action publishes its results as a check run. A new repository's
|
||||
# token is read-only, and without checks: write the job fails even when
|
||||
# every test passes. If you protect main, require the `Run GdUnit4 Tests` job
|
||||
# check, not `test-results`: that check run concludes success even when a
|
||||
# test fails.
|
||||
permissions:
|
||||
contents: read
|
||||
checks: write
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -259,10 +372,15 @@ jobs:
|
||||
with:
|
||||
lfs: true
|
||||
|
||||
# godot-version must be a full release such as 4.6.1 (`godot --version`
|
||||
# shows it); VERSION.md's "4.6" is not one. version: installed runs the
|
||||
# gdUnit4 committed in addons/ -- without it the action deletes that
|
||||
# copy and installs the latest release, which may not match your tests.
|
||||
- name: Run GdUnit4 Tests
|
||||
uses: MikeSchulze/gdUnit4-action@v1
|
||||
uses: godot-gdunit-labs/gdUnit4-action@v1
|
||||
with:
|
||||
godot-version: '[VERSION FROM docs/engine-reference/godot/VERSION.md]'
|
||||
godot-version: '[FULL GODOT VERSION, e.g. 4.6.1]'
|
||||
version: 'installed'
|
||||
paths: |
|
||||
tests/unit
|
||||
tests/integration
|
||||
@@ -343,21 +461,36 @@ on:
|
||||
jobs:
|
||||
test:
|
||||
name: Run UE Automation Tests
|
||||
runs-on: self-hosted # UE requires a local runner with the editor installed
|
||||
runs-on: [self-hosted, windows] # UE requires a local runner with the editor installed
|
||||
|
||||
# The quoted "{0}" in each `shell:` below: the Windows runner passes bash
|
||||
# its script path unquoted, so with plain `shell: bash` every step fails
|
||||
# ("No such file or directory") when the runner's folder has a space.
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
lfs: true
|
||||
|
||||
# Binaries/ is gitignored, so a fresh checkout has no compiled game
|
||||
# module: without this step the editor stops with "The game module could
|
||||
# not be found" before running any test. UnrealBuildTool.exe, not
|
||||
# Build.bat -- from bash, Build.bat fails on an engine path with spaces.
|
||||
- name: Build Editor Target
|
||||
run: |
|
||||
"$UE_ROOT/Engine/Binaries/DotNET/UnrealBuildTool/UnrealBuildTool.exe" [ProjectName]Editor Win64 Development \
|
||||
-Project="${{ github.workspace }}/[ProjectName].uproject"
|
||||
shell: bash --noprofile --norc -eo pipefail "{0}"
|
||||
|
||||
# -stdout -FullStdOutLogOutput: without them the editor prints nothing
|
||||
# here, and the results are only in Saved/Logs/.
|
||||
- name: Run Automation Tests
|
||||
run: |
|
||||
"$UE_EDITOR_PATH" "${{ github.workspace }}/[ProjectName].uproject" \
|
||||
"$UE_ROOT/Engine/Binaries/Win64/UnrealEditor-Cmd.exe" "${{ github.workspace }}/[ProjectName].uproject" \
|
||||
-nullrhi -nosound \
|
||||
-ExecCmds="Automation RunTests MyGame.; Quit" \
|
||||
-log -unattended
|
||||
shell: bash
|
||||
-ExecCmds="Automation RunTests [ProjectName].; Quit" \
|
||||
-unattended -stdout -FullStdOutLogOutput
|
||||
shell: bash --noprofile --norc -eo pipefail "{0}"
|
||||
|
||||
- name: Upload Logs
|
||||
if: always()
|
||||
@@ -367,8 +500,11 @@ jobs:
|
||||
path: Saved/Logs/
|
||||
```
|
||||
|
||||
Note: UE CI requires a self-hosted runner with Unreal Editor installed.
|
||||
Set the `UE_EDITOR_PATH` environment variable on the runner.
|
||||
Note: UE CI requires a self-hosted Windows runner with Unreal Editor installed.
|
||||
The `windows` label keeps the job off any Linux self-hosted runner the
|
||||
repository also has. Set the `UE_ROOT` environment variable on the runner to the engine folder
|
||||
(e.g. `C:/Program Files/Epic Games/UE_5.7`). `[ProjectName]Editor` is the
|
||||
editor target in `Source/[ProjectName]Editor.Target.cs`.
|
||||
|
||||
---
|
||||
|
||||
@@ -417,25 +553,34 @@ Test infrastructure created for [engine].
|
||||
|
||||
Files created:
|
||||
- tests/README.md
|
||||
- tests/unit/ (directory)
|
||||
- tests/integration/ (directory)
|
||||
- tests/unit/ and tests/integration/ (Godot) — or the engine's test root:
|
||||
Unity Assets/Tests/EditMode/ and PlayMode/, Unreal Source/<Module>/Private/Tests/
|
||||
- tests/smoke/critical-paths.md
|
||||
- production/qa/evidence/ (directory)
|
||||
- production/qa/evidence/.gitkeep
|
||||
[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]
|
||||
2. Write your first test in the engine's test root:
|
||||
tests/unit/[system]/[system]_[feature]_test.gd (Godot),
|
||||
Assets/Tests/EditMode/[System]Tests.cs (Unity), or
|
||||
Source/<Module>/Private/Tests/[System]Test.cpp (Unreal)
|
||||
3. Run `/qa-plan sprint` before your first sprint to classify stories and set
|
||||
test evidence requirements
|
||||
test evidence requirements. At `workflow: minimal` — the default — skip
|
||||
this: there are no sprints. At `qa.level: minimal`, also the default, tests
|
||||
are waived, so `/dev-story` writes none. Raise `qa.level` with `/settings`
|
||||
to have it write them
|
||||
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
|
||||
- the engine's test root: tests/unit/ and tests/integration/ (Godot),
|
||||
Assets/Tests/EditMode/ and Assets/Tests/PlayMode/ (Unity), or
|
||||
Source/<Module>/Private/Tests/ (Unreal)
|
||||
- .github/workflows/tests.yml
|
||||
- At least one example test file
|
||||
Run /test-setup and write one example test before advancing.
|
||||
(At `workflow: minimal` that gate requires only the engine.)
|
||||
|
||||
Verdict: **COMPLETE** — test framework scaffolded and CI/CD wired up.
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user