Testing
The backend has two layers of automated tests: fast unit tests that run everywhere, and integration tests that exercise the repositories against a real Postgres. Tests use testify for assertions and mockery-generated mocks for service interfaces. On top of those, an on-demand end-to-end suite drives the full stack with Playwright (see below).
Unit tests
Section titled “Unit tests”make backend-testThis runs go test -race -v ./... with a 60s timeout. The -race flag enables
the data-race detector, so concurrency bugs surface in CI. Unit tests use the
committed mock_*.go mocks rather than touching a database — see
Code Generation
for how to regenerate mocks when an interface changes.
Integration tests
Section titled “Integration tests”make backend-test-integrationIntegration tests run against a live Postgres instance: locally via Docker
Compose, in CI via a service container. They are gated behind the integration
build tag, so the default make backend-test does not run them.
Three packages carry integration-tagged files: the repository layer
(internal/repositories/postgres/...), the scheduler (internal/scheduler/...),
and the project-migration service (internal/services/projectmigration/...).
Note that make backend-test-integration above runs only the repository layer;
make backend-test-coverage-integration runs the whole tagged set.
- Override the target database with the
POSTGRES_TEST_DSNenvironment variable. - The timeout is 180s to allow for migrations and real I/O.
Locally, make backend-test-coverage-integration runs both suites in one
process against a real Postgres. In CI the suite is sharded (since #638):
the unit job runs the whole module untagged
(make backend-test-unit-coverage, no Postgres) and the integration job runs
only the integration-tagged packages
(make backend-test-integration-coverage) against a Postgres service
container. make backend-check-integration-shard guards the split: an
integration-tagged file added to a package outside that list fails CI until the
package is added to it. Both jobs publish coverage, so integration coverage
counts toward the reported total.
End-to-end tests
Section titled “End-to-end tests”make e2eThe e2e suite is production-like: docker-compose.e2e.yml builds the
combined image (backend serving the embedded SPA) from source and boots it with
Postgres, a fake-gcs emulator (plus a gcs-init bucket bootstrap), and an
a2a-test-agent (a toy A2A agent built from backend/cmd/a2a-test-agent/,
exposed to the suite via E2E_A2A_AGENT_URL) so Playwright can register an
agent and chat with it end to end. It then runs the frontend’s Playwright
tests against the running stack. make e2e does everything: installs the Playwright
browser, builds and boots the stack, runs the suite, and always tears the stack
down. The individual steps are also available:
| Target | Purpose |
|---|---|
make e2e-up | Build and start the e2e stack, blocking until every service is healthy. |
make e2e-down | Tear the stack down. |
make e2e-browsers | Install the Playwright browser. |
make e2e-test | Run the Playwright suite against a running stack (PLAYWRIGHT_BASE_URL). |
In CI the suite runs on demand only via the ci-e2e.yml workflow
(workflow_dispatch — trigger it from the Actions tab or with
gh workflow run ci-e2e.yml -f branch=<ref>). It is intentionally not wired to
every PR: building the combined image and booting the full stack is too heavy
to gate each push. The workflow delegates to the same make e2e, so a green
run there means the same command is green locally.
Coverage
Section titled “Coverage”make backend-test-coverageThis writes coverage.out and renders coverage.html in backend/. Clean up
the artifacts with make backend-test-clean.
Service interfaces are mocked with mockery. Regenerate all mocks after changing an interface:
make backend-mock-generateThe generated mock_*.go files are committed and must not be hand-edited.
Spec conformance
Section titled “Spec conformance”The internal/specconformance package contains tests asserting that the running
server matches the OpenAPI spec. These run as part of make backend-test and
help catch drift between the implementation and
the spec.
Before you commit
Section titled “Before you commit”Run the same checks CI runs:
make backend-test # unit tests (-race)make backend-check # lint + vulncheck + securityRun make backend-test-integration as well when you touch the repository layer
or migrations. See Database & Migrations.