NEO-29: move AAA enforcement to test authoring time

Remove the AAA pre-commit gate and instead provide write-time scaffolding via C# snippets and a test template, then document those defaults in the C# style and testing expectations rules.
pull/54/head
VinPropane 2026-04-25 22:50:03 -04:00
parent 3a2fce2ce0
commit e6f3d63318
5 changed files with 62 additions and 15 deletions

View File

@ -95,6 +95,8 @@ public async Task PostMove_ShouldReturnBadRequest_WhenSchemaVersionIsWrong() {
- **Act:** invoke the single behavior under test. For integration tests, the Act block may include a short sequence of calls if that sequence *is* the behavior (e.g. POST then GET to verify persistence)—keep it one clear scenario per test.
- **Assert:** all expectations (`Assert.*`, etc.); read response bodies here when the read is for verification, not for driving the next call (otherwise fold those reads into Act).
- Multi-scenario files stay readable with **one AAA triple per `[Fact]` / `[Theory]`** method.
- **Write-time default:** use the workspace VS Code snippet prefix **`xut`** (method) or **`xutc`** (class) from `.vscode/csharp.code-snippets` when authoring tests so AAA sections are present from the first draft.
- **Template reference:** `server/NeonSprawl.Server.Tests/TestTemplates/AAA_TEST_METHOD_TEMPLATE.cs.txt`.
## Tooling

View File

@ -10,6 +10,7 @@ alwaysApply: true
- **Non-trivial logic** (validation, simulation rules, serialization boundaries, idempotency, security-sensitive paths) should have **automated tests** once a test project exists in the repo.
- **Default framework:** **xUnit** for new test projects unless the repo already standardizes on something else—stay consistent with existing `*.Tests` projects.
- **Layout:** use **Arrange / Act / Assert** in every test method; see [C# style — Unit and integration tests](csharp-style.md#unit-and-integration-tests-arrange-act-assert).
- **At-write-time default:** start new tests with snippet **`xut`** / **`xutc`** from `.vscode/csharp.code-snippets` (AAA sections pre-inserted) or copy `server/NeonSprawl.Server.Tests/TestTemplates/AAA_TEST_METHOD_TEMPLATE.cs.txt`.
- **Names:** **`MethodName_ShouldExpectedOutcome_WhenScenario`**; see [C# style — Test method naming convention](csharp-style.md#test-method-naming-convention).
- **No test project yet:** It is acceptable to ship a small change without a suite only while the server is mostly scaffolding. When you add the **first** testable module, **add a `NeonSprawl.Server.Tests` (or equivalent) project** and start covering that area; do not leave new core logic permanently untested.
- **Bug fixes:** Prefer a **regression test** when the fix is non-obvious or has broken before.

47
.vscode/csharp.code-snippets vendored 100644
View File

@ -0,0 +1,47 @@
{
"xUnit Test Method AAA": {
"scope": "csharp",
"prefix": "xut",
"description": "xUnit test method with explicit Arrange/Act/Assert",
"body": [
"[Fact]",
"public async Task ${1:MethodName}_Should${2:ExpectedOutcome}_When${3:Scenario}()",
"{",
" // Arrange",
" ${4:// setup}",
"",
" // Act",
" ${5:// execute}",
"",
" // Assert",
" ${6:// verify}",
"}"
]
},
"xUnit Test Class AAA": {
"scope": "csharp",
"prefix": "xutc",
"description": "xUnit test class scaffold with AAA guidance",
"body": [
"using Xunit;",
"",
"namespace ${1:NeonSprawl.Server.Tests};",
"",
"public sealed class ${2:Feature}Tests",
"{",
" [Fact]",
" public async Task ${3:MethodName}_Should${4:ExpectedOutcome}_When${5:Scenario}()",
" {",
" // Arrange",
" ${6:// setup}",
"",
" // Act",
" ${7:// execute}",
"",
" // Assert",
" ${8:// verify}",
" }",
"}"
]
}
}

View File

@ -43,18 +43,3 @@ if has_staged_match '^client/scripts/.*\.gd$'; then
exit 1
fi
fi
# Enforce explicit AAA markers in changed C# test files.
for f in "${staged_files[@]}"; do
if [[ ! "$f" =~ ^server/NeonSprawl\.Server\.Tests/.*Tests\.cs$ ]]; then
continue
fi
if [[ ! -f "$f" ]]; then
continue
fi
if ! rg -q 'Arrange' "$f" || ! rg -q 'Act' "$f" || ! rg -q 'Assert' "$f"; then
echo "pre-commit: $f is missing explicit AAA markers (Arrange/Act/Assert)." >&2
echo "Add clear Arrange/Act/Assert sections in changed C# tests." >&2
exit 1
fi
done

View File

@ -0,0 +1,12 @@
[Fact]
public async Task MethodName_ShouldExpectedOutcome_WhenScenario()
{
// Arrange
// Create factory/client/dependencies and test data.
// Act
// Invoke exactly one behavior/scenario under test.
// Assert
// Verify outcome(s) with Assert.* calls.
}