| id | GUIDE-TPL-SELECTIVE-TESTING-001 | |
|---|---|---|
| title | Selective Testing Guide | |
| doc_type | guide | |
| status | draft | |
| stories |
|
|
| requirements |
|
|
| acs | ||
| adrs |
|
Purpose: Run only the tests affected by your changes, avoiding slow full test suite runs on Tier-2 platforms (native Windows).
| Command | Purpose | Example |
|---|---|---|
cargo xtask test-ac <AC-ID> |
Test single acceptance criterion | cargo xtask test-ac AC-PLT-001 |
cargo xtask test-changed [--base <ref>] |
Test only changed files | cargo xtask test-changed |
cargo xtask check |
Fast core checks (fmt, clippy, unit tests, change-aware BDD) | cargo xtask check |
cargo xtask selftest |
Full validation (Tier-1 only) | nix develop && cargo xtask selftest |
Default validation ladder
- After edits:
cargo xtask test-changed - Specific AC touched:
cargo xtask test-ac <AC-ID> - Pre-merge (Tier-1):
nix develop && cargo xtask selftest
Running the full BDD suite (cargo xtask bdd) or selftest on native Windows can take 2+ hours due to:
- Executable file locking (
xtask.exe,acceptance.exe) - Antivirus scanning
target/directory - Serial execution of 100+ acceptance scenarios
On Tier-1 platforms (Nix + Linux/macOS/WSL2), this is much faster (10-20 minutes), but still too slow for rapid iteration.
When working on a specific AC:
# Example: Testing the doctor command
cargo xtask test-ac AC-PLT-001
# What it does:
# 1. Looks up AC-PLT-001 in specs/spec_ledger.yaml
# 2. Finds all BDD scenarios tagged with @AC-PLT-001
# 3. Runs only those scenarios
# 4. Reports pass/failOutput example:
[INFO] Looking up AC: AC-PLT-001
[INFO] Found AC: AC-PLT-001 (requirement: REQ-PLT-ONBOARDING)
[INFO] Searching for BDD scenarios tagged with @AC-PLT-001...
[INFO] Found 1 scenario(s):
- doctor validates the environment and prints next steps
[INFO] Running acceptance tests for @AC-PLT-001...
[PASS] All tests passed for AC-PLT-001
Scenarios: 1
After making file edits:
# Compare against origin/main (default)
cargo xtask test-changed
# Compare against different base
cargo xtask test-changed --base HEAD~5
cargo xtask test-changed --base mainSmart file classification:
specs/features/*.feature-> Runs BDD for ACs in that featurespecs/spec_ledger.yaml-> Runs all BDD testscrates/xtask/**-> Runs xtask unit tests + DevEx BDDcrates/app-http/**-> Runs app-http unit testscrates/spec-runtime/**-> Runs spec-runtime tests + graph invariantscrates/business-core/**-> Runs business-core testsdocs/**only -> Runsdocs-check(lightweight)
Output example:
Analyzing changed files...
Changed files (vs origin/main):
- specs/features/xtask_devex.feature
- crates/xtask/src/commands/dev_up.rs
Test plan:
1. Run BDD: @AC-PLT-018 (Changed feature files)
2. Run unit tests: xtask (xtask crate changes)
Executing tests:
[run] cargo test -p acceptance --test acceptance (tags: "@AC-PLT-018")
[ok] Changed feature files
[run] cargo test -p xtask
[ok] xtask crate changes
[ok] All tests passed
Tag syntax
- Feature files should tag scenarios as
@AC-... CUCUMBER_TAG_EXPRESSIONacceptsAC-...or@AC-...;test-changednormalizes to@AC-...when invoking Cucumber
Plan-only preview
XTASK_TEST_CHANGED_PLAN_ONLY=1 XTASK_CHANGED_BASE=HEAD cargo xtask test-changedprints the change-aware plan and tag expression without executing tests (handy for acceptance tests or slow machines)
No changes detected:
Analyzing changed files...
Changed files (vs origin/main):
- README.md
No tests needed for these changes.
Fast iteration:
# Make changes
cargo xtask test-changed
# Or test specific AC
cargo xtask test-ac AC-PLT-001
# Before commit
cargo xtask selftestPre-commit hook:
#!/usr/bin/env bash
set -e
cargo xtask test-changedFast iteration:
# Make changes
cargo xtask check # fmt, clippy, unit tests only
# Test specific AC (if applicable)
cargo xtask test-ac AC-PLT-001
# Or test changed files
cargo xtask test-changedPre-commit hook:
#!/usr/bin/env bash
set -e
cargo xtask test-changedFull validation (use Tier-1):
# Switch to WSL2 or Linux VM
nix develop
cargo xtask selftestReserve cargo xtask selftest for:
- CI/CD pipelines (automated, Tier-1 environment)
- Pre-merge validation (in Tier-1 environment)
- Release candidates (comprehensive gate)
- After major refactoring (rare, manual trigger)
Never:
- [FAIL] On every commit (use selective testing)
- [FAIL] On native Windows for iteration (use Tier-1 for full validation)
- [FAIL] For single-file changes (use
test-acortest-changed)
| Environment | Command | Time | Use Case |
|---|---|---|---|
| Native Windows | cargo xtask selftest |
2+ hours | [FAIL] Avoid |
| Native Windows | cargo xtask test-changed |
30s - 5m | [OK] Local iteration |
| Native Windows | cargo xtask test-ac AC-PLT-001 |
10s - 2m | [OK] Focused work |
| WSL2 + Nix | cargo xtask selftest |
10-20m | [OK] Pre-merge gate |
| WSL2 + Nix | cargo xtask test-changed |
30s - 3m | [OK] Fast loop |
| CI (Linux + Nix) | cargo xtask selftest |
10-20m | [OK] Canonical truth |
$ cargo xtask test-ac AC-MISSING-001
Error: AC not found in specs/spec_ledger.yaml: AC-MISSING-001
Suggestions (first 10 ACs):
- AC-PLT-001
- AC-PLT-002
...Fix: Check specs/spec_ledger.yaml for correct AC-ID, or create it:
cargo xtask ac-new AC-MYSERV-001 "Description" --requirement REQ-ID$ cargo xtask test-ac AC-PLT-999
[WARN] No BDD scenarios found for AC-PLT-999
[INFO] Use: cargo xtask ac-suggest-scenarios AC-PLT-999Fix: Add scenarios to feature file or use:
cargo xtask ac-suggest-scenarios AC-PLT-999$ cargo xtask test-changed
Error: Not a git repositoryFix: Ensure you're in the repository root with .git/ directory.
$ cargo xtask test-changed --base nonexistent-branch
Error: Git ref not found: nonexistent-branchFix: Use valid git ref:
git branch -a # List all branches
cargo xtask test-changed --base origin/mainThe git pre-commit hook can use selective testing:
#!/usr/bin/env bash
# .git/hooks/pre-commit
set -e
echo "Running selective tests on changed files..."
cargo xtask test-changed
echo "[OK] Pre-commit checks passed"Install/update hook:
cargo xtask install-hooks# Sequential (current approach)
cargo xtask test-ac AC-PLT-001
cargo xtask test-ac AC-PLT-002
# Or use BDD tag syntax
cargo test -p acceptance --test acceptance -- --tags "@AC-PLT-001 or @AC-PLT-002"XTASK_TEST_CHANGED_PLAN_ONLY=1 cargo xtask test-changedShows the change-aware plan and CUCUMBER_TAG_EXPRESSION without running any tests. Combine with XTASK_CHANGED_BASE=HEAD for fully local diffs.
For complex changes spanning multiple crates:
# 1. Check what would run
cargo xtask test-changed --dry-run # (future enhancement)
# 2. Manually compose
cargo test -p xtask
cargo test -p rust-as-spec-runtime
cargo test -p acceptance --test acceptance -- --tags "@AC-PLT-001"# .github/workflows/ci.yml (example)
name: CI
on: [push, pull_request]
jobs:
selective-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Needed for git diff
- name: Run selective tests
run: |
nix develop --command cargo xtask test-changed --base origin/main
full-validation:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Full selftest
run: |
nix develop --command cargo xtask selftesterror: failed to remove file 'target\debug\xtask.exe'
Caused by: Access is denied. (os error 5)
Causes:
- Old cargo/xtask process still running
- VS Code rust-analyzer holding locks
- Multiple terminals running builds
Fixes:
# Kill all cargo processes
taskkill /F /IM cargo.exe /IM xtask.exe /T
# Restart terminal
# Close VS Code and reopenLikely cause: Using Tier-2 (Windows) for local testing, CI uses Tier-1 (Linux).
Fix: Validate in matching environment:
# In WSL2 with Nix (matches CI)
nix develop
cargo xtask test-changed
cargo xtask selftestIf test-changed is slow (>5 minutes):
-
Check what's running:
# Add --verbose flag (future enhancement) cargo xtask test-changed --verbose -
Verify impact analysis:
- Changed
specs/spec_ledger.yaml? Triggers all BDD tests - Changed core crate? Triggers many dependent tests
- Changed
-
Use more targeted command:
# Instead of test-changed for ledger changes cargo xtask test-ac AC-SPECIFIC-ID
- Parses
specs/spec_ledger.yamlto find AC definition - Uses
ac_parsingmodule to extract metadata (requirement, tests) - Scans
specs/features/*.featurefor scenarios tagged with@<AC-ID> - Executes:
cargo test -p acceptance --test acceptance -- --tags @<AC-ID> - Reports results with scenario count
- Executes:
git diff --name-only <base>...HEAD - Classifies changed files by prefix/pattern
- Maps to test actions:
- Feature files -> Extract AC tags -> Run BDD
- Crate sources -> Run unit tests for that crate
- Docs -> Run lightweight docs-check
- Deduplicates test commands
- Executes plan sequentially
- Aggregates pass/fail results
// Pseudocode
match file_path {
"specs/spec_ledger.yaml" => run_all_bdd(),
"specs/features/*.feature" => run_bdd_for_acs_in_file(),
"crates/xtask/**" => run_xtask_tests() + run_devex_bdd(),
"crates/app-http/**" => run_app_http_tests(),
"crates/spec-runtime/**" => run_spec_runtime_tests() + run_graph_invariants(),
"crates/business-core/**" => run_business_core_tests(),
"crates/acceptance/**" => run_all_bdd(),
"docs/**" => run_docs_check(),
_ => skip(),
}Potential additions (not yet implemented):
- Parallel execution: Run independent test groups concurrently
- First-class plan-only flag: Promote
XTASK_TEST_CHANGED_PLAN_ONLYto--plan-only - Test caching: Skip tests for unchanged code
- Impact graph: Use cargo metadata to detect transitive impacts
- Watch mode:
--watchto re-run on file changes - JSON output:
--jsonfor tooling integration - Test result caching: Skip re-running passing tests
| Command | Documentation |
|---|---|
cargo xtask check |
Core checks (fmt, clippy, tests) |
cargo xtask bdd |
Full BDD suite |
cargo xtask selftest |
Complete validation (7 steps) |
cargo xtask ac-coverage |
Show which ACs have tests |
cargo xtask ac-status |
Detailed AC test status |
cargo xtask ac-suggest-scenarios |
Generate BDD scenarios for AC |
- AGENT_GUIDE.md - Full agent workflow
- MISSING_MANUAL.md - Platform support tiers
- Platform support docs
- BDD workflow