Nomos Test Execution Guide
This skill orchestrates test execution for the Nomos monorepo, providing command guidance and verification workflows following the project's testing standards.
When to Use This Skill
- •Running the test suite (unit, integration, or all tests)
- •Debugging test failures (hermetic vs integration)
- •Validating test coverage
- •Executing mandatory verification checklists from
AGENTS.mdfiles - •Regenerating golden files for parser/compiler tests
- •Running race detector
- •Testing specific modules independently
Testing Standards Overview
- •80% minimum coverage required for all modules
- •100% coverage for critical business logic paths
- •Table-driven tests as standard pattern
- •Integration tests require
//go:build integrationtag - •Test isolation using
t.TempDir() - •Hermetic tests - no network/external deps in unit tests
Quick Command Reference
Basic Test Commands
# Run all tests (unit only, fast) make test # Run with race detector make test-race # Run unit tests only (explicit) make test-unit # Run integration tests only make test-integration # Run all tests (unit + integration) make test-all # Test specific module make test-module MODULE=libs/parser make test-module MODULE=libs/compiler make test-module MODULE=apps/command-line # Generate coverage reports make test-coverage
Build Commands (Required Before Some Tests)
# Build all applications make build # Build CLI specifically make build-cli # Build test binaries (required for integration tests) make build-test
Development Commands
# Format code before testing make fmt # Tidy dependencies make mod-tidy # Lint (requires golangci-lint) make lint # Full verification workflow make fmt && make test && make lint
Test Execution Workflows
Workflow 1: Basic Unit Testing
When: Regular development, fast feedback loop
# 1. Run unit tests make test # 2. If failures, run specific module make test-module MODULE=libs/parser # 3. Check race conditions if suspicious make test-race
Expected output:
ok github.com/autonomous-bits/nomos/libs/parser 0.123s coverage: 92.1% of statements ok github.com/autonomous-bits/nomos/libs/compiler 0.456s coverage: 88.5% of statements
Workflow 2: Pre-Commit Verification
When: Before committing code
# 1. Format code make fmt # 2. Run all unit tests make test # 3. Run race detector make test-race # 4. Lint if available make lint
Workflow 3: Full Integration Testing
When: Before PR, release preparation, debugging complex issues
# 1. Build test binaries first (critical!) make build-test # 2. Run integration tests make test-integration # 3. Run all tests (unit + integration) make test-all
Common mistake: Forgetting make build-test causes integration tests to fail with "binary not found" errors.
Workflow 4: Module-Specific Testing
When: Working on specific module, faster iteration
# Parser module make test-module MODULE=libs/parser # Compiler module make test-module MODULE=libs/compiler # CLI module make test-module MODULE=apps/command-line
Workflow 5: Coverage Validation
When: Ensuring coverage requirements met
# 1. Generate coverage report make test-coverage # 2. Open HTML report open coverage.html # macOS xdg-open coverage.html # Linux start coverage.html # Windows # 3. Verify minimum 80% coverage # Look for files below threshold
Check coverage manually:
go test -coverprofile=coverage.out ./... go tool cover -func=coverage.out | grep total # Example output: total: (statements) 88.2%
Debugging Test Failures
Failure Type 1: Unit Test Failures
Symptom: Test fails in regular make test run
Debug steps:
# 1. Run specific test verbosely cd libs/parser go test -v -run TestParsing # 2. Check for table-driven test case # Look at test output to identify failing case # 3. Run with race detector go test -race -run TestParsing # 4. Check test helper usage # Ensure helpers marked with t.Helper()
Failure Type 2: Integration Test Failures
Symptom: Test fails only with make test-integration
Debug steps:
# 1. Verify build tags present grep -r "//go:build integration" libs/compiler/test/ # 2. Ensure test binary built make build-test ls -la bin/ # 3. Run integration test verbosely cd libs/compiler go test -v -tags=integration ./test/... # 4. Check for external dependencies # - Network calls? # - File system operations? # - Provider binary execution?
Failure Type 3: Golden File Mismatches (Parser)
Symptom: "output mismatch" errors comparing actual vs golden files
Debug steps:
# 1. Review actual output cat testdata/fixtures/test.csl cat testdata/golden/test.csl.json # 2. If intentional change, regenerate golden files cd libs/parser rm testdata/golden/test.csl.json go test # Will regenerate # 3. Review diff before committing git diff testdata/golden/ # 4. Run tests again to verify go test
Failure Type 4: Hermetic Test Violations
Symptom: Tests pass locally but fail in CI
Debug steps:
# 1. Check for hermetic violations: # - Network calls in unit tests # - Hardcoded paths # - Time-dependent behavior # - External dependencies # 2. Verify test uses t.TempDir() grep -A 10 "func Test" libs/compiler/*_test.go | grep TempDir # 3. Check for missing build tags # Unit tests should NOT have //go:build tags # Integration tests MUST have //go:build integration # 4. Isolate test go test -run TestSpecific -count=1 -v
Failure Type 5: Race Detector Warnings
Symptom: make test-race reports data races
Debug steps:
# 1. Run race detector with failing test go test -race -run TestConcurrent -v # 2. Examine race report # Shows: goroutine stack traces where race occurs # 3. Common causes: # - Missing mutex protection # - Shared map access # - Provider caching without locks # 4. Fix and re-run make test-race
Module-Specific Test Patterns
Parser Module (libs/parser)
Test organization:
testdata/ fixtures/ # Input .csl files golden/ # Expected AST outputs errors/ # Error test cases
Common commands:
cd libs/parser # Run all tests go test ./... # Run benchmarks go test -bench=. -benchmem # Regenerate golden files (after intentional changes) rm testdata/golden/*.json go test # Check coverage go test -coverprofile=coverage.out ./... go tool cover -html=coverage.out -o coverage.html
Expected behavior:
- •Golden files auto-generate if missing (review before commit!)
- •Benchmarks should meet performance goals (see AGENTS.md)
- •Coverage should exceed 80%
Compiler Module (libs/compiler)
Test organization:
testdata/ # Test fixtures test/ # Integration tests testutil/ # Fake providers, test helpers
Common commands:
cd libs/compiler # Unit tests only go test -run "^Test" ./... # Integration tests (hermetic) make build-test # Critical first step go test -tags=integration ./test/... # All tests go test ./... && go test -tags=integration ./test/... # Test provider resolution specifically go test -v -run TestProvider
Expected behavior:
- •Hermetic tests use fake providers from
testutil/ - •Integration tests require real provider binaries
- •Provider process cleanup verified (no zombie processes)
CLI Module (apps/command-line)
Test organization:
testdata/ # Test configs test/ # Integration tests (CLI invocation) internal/ # Unit tests alongside code
Common commands:
cd apps/command-line # Build CLI first make build-cli # Unit tests go test ./internal/... # Integration tests (invoke CLI binary) make build-test go test -tags=integration ./test/... # Test specific command go test -v -run TestInit ./internal/initcmd/
Expected behavior:
- •Integration tests invoke actual CLI binary
- •Exit codes verified
- •Stdout/stderr captured and validated
Verification Checklists (Mandatory)
Each module has verification requirements in AGENTS.md. Follow these before completing tasks:
Universal Checklist (All Modules)
# ✅ Build Verification make build # All code must compile without errors # ✅ Unit Test Verification make test # All existing tests must pass # ✅ Race Detector make test-race # No data races reported # ✅ Linting (if golangci-lint installed) make lint # No errors (warnings acceptable if documented) # ✅ Coverage Check make test-coverage # Minimum 80% overall, 100% for critical paths
Parser Module Checklist
cd libs/parser # ✅ Build go build ./... # ✅ Unit Tests go test ./... # All tests pass # ✅ Race Detector go test -race ./... # ✅ Golden Files git diff testdata/golden/ # Review any changes to golden files # ✅ Benchmarks go test -bench=. -run=^$ # Performance meets goals # ✅ Linting go vet ./... golangci-lint run # ✅ Coverage go test -coverprofile=coverage.out ./... go tool cover -func=coverage.out | grep total # Minimum 80%
Compiler Module Checklist
cd libs/compiler # ✅ Build go build ./... # ✅ Unit Tests go test ./... # ✅ Integration Tests go test -tags=integration ./test/... # ✅ Race Detector go test -race ./... # ✅ Linting go vet ./... golangci-lint run # ✅ Coverage go test -coverprofile=coverage.out ./... # Check: >= 80%
CLI Module Checklist
cd apps/command-line # ✅ Build CLI make build-cli ./nomos --help # Binary executes and shows help # ✅ Unit Tests go test ./internal/... # ✅ Integration Tests make build-test go test -tags=integration ./test/... # ✅ Race Detector go test -race ./... # ✅ Exit Codes go test -v -run TestExitCode ./test/... # Verify: 0 (success), 1 (errors), 2 (usage) # ✅ Linting go vet ./... golangci-lint run # ✅ Coverage go test -coverprofile=coverage.out ./...
Common Issues and Solutions
Issue: "Test binary not found"
Solution:
make build-test
Integration tests require pre-built binaries.
Issue: "go.work out of sync"
Solution:
make work-sync make mod-tidy
Issue: Tests pass locally, fail in CI
Causes:
- •Missing integration build tags
- •Hermetic test violations (network calls)
- •Platform-specific assumptions
- •Uncommitted test fixtures
Solution:
# Check build tags grep -r "//go:build integration" . # Check for network calls in unit tests grep -r "http\." *_test.go # Test in clean environment git clean -xdf make test
Issue: Coverage below 80%
Solution:
# Identify uncovered code go test -coverprofile=coverage.out ./... go tool cover -func=coverage.out | grep -v "100.0%" # Add tests for uncovered functions # Focus on critical paths first (must be 100%)
Issue: Race detector warnings
Solution:
# Run with race detector go test -race -v ./... # Fix identified races: # - Add mutex protection # - Use channels for coordination # - Copy data instead of sharing
Best Practices
- •
Always run tests before committing:
bashmake fmt && make test && make test-race
- •
Test specific module during development:
bashmake test-module MODULE=libs/parser
- •
Build test binaries before integration tests:
bashmake build-test
- •
Check coverage periodically:
bashmake test-coverage
- •
Run full suite before PR:
bashmake build-test && make test-all && make test-race
- •
Review golden file changes carefully:
bashgit diff testdata/golden/
Reference Documentation
For complete testing guidelines, see: