Testing
Rack Gateway uses unit, integration, and end-to-end tests across Go and web codebases.
Use task commands to keep codegen, containers, and test dependencies in sync.
Test Overview
Section titled “Test Overview”| Test Type | Location | Command |
|---|---|---|
| Go Unit | cmd/**, internal/** (*_test.go) | task go:test:unit |
| Go Integration | internal/integration/ (against the built binaries) | task go:test:integration |
| Go Unit + Integration | both of the above | task go:test |
| Web Unit | web/src/**/*.test.ts* | task web:test |
| Web E2E | web/e2e/ | task web:e2e |
| CLI E2E | scripts/cli-e2e.sh | task go:e2e |
| Release image smoke test | scripts/release-smoke.sh | task docker:release:smoke |
Test Bypasses
Section titled “Test Bypasses”The unit tests and the E2E stacks run the gateway with DEV_MODE and E2E_TEST_MODE, which only work in a build
compiled with the testbypass Go build tag (see Test Bypasses).
The task commands pass the tag for you. The release image is built without it, so the E2E suite never runs it;
task docker:release:smoke builds the release image and checks it with a production configuration instead: the
bypasses are compiled out and refused at startup, and it boots with HSTS, a strict CSP, origin checks and Secure
cookies. It needs network access to Google for OIDC discovery.
Running Tests
Section titled “Running Tests”Full Test Suite
Section titled “Full Test Suite”task ciCI runs this on every push; locally it takes about 15 minutes, so run the focused tasks below while you work.
Go Tests
Section titled “Go Tests”task go:test:unit # unit tests (with -race and the testbypass tag)task go:test # unit and integration testsTests that need a database use TEST_DATABASE_URL (gateway_test on the Docker Postgres, set in mise.toml).
Web Tests
Section titled “Web Tests”task web:testE2E Tests
Section titled “E2E Tests”# Web E2Etask web:e2e
# CLI E2Etask go:e2eFocused E2E Runs
Section titled “Focused E2E Runs”Use --grep to run a single Playwright test:
task web:e2e -- --grep "manage MFA"CLI E2E filters are exposed as task variants:
task go:e2e:admintask go:e2e:api-tokentask go:e2e:deployertask go:e2e:viewerFaster Playwright Runs
Section titled “Faster Playwright Runs”When you’ve changed only test files under web/e2e/, run Playwright directly against the already-running E2E
stack instead of rebuilding it:
cd web && bunx playwright test e2e/your-test.spec.tsAny change to application code (Go, or TypeScript under web/src/) needs task web:e2e, which rebuilds the
stack. Add --headed to watch the browser, or --debug for the Playwright Inspector; screenshots and videos of
failures are in web/test-results/.
Test Layout
Section titled “Test Layout”internal/├── gateway/ # Unit + integration tests alongside code└── integration/ # Additional integration scenarios
web/├── src/ # Vitest unit tests└── e2e/ # Playwright testsWriting Tests
Section titled “Writing Tests”- Keep unit tests close to the code under test (
*_test.go,*.test.tsx). - Use E2E tests for cross-service workflows (OAuth, RBAC, deploy approvals).
- Prefer
taskcommands so the local environment matches CI behavior.