temporalio/temporal
Testing
The repository ships three test layers, each with its own Make target. Most contributions need at least the first two.
The three layers
| Layer | Make target | Tag | What it covers |
|---|---|---|---|
| Unit | make unit-test |
(none) | Pure Go tests under service/, common/, chasm/. No real DB; uses mocks generated by go.uber.org/mock. |
| Integration | make integration-test |
integration |
Persistence-backed tests requiring a real DB or fault-injection wrapper. |
| Functional | make functional-test |
test_dep |
E2E tests under tests/. Spin up an in-process cluster. |
Required build tag for any test: -tags test_dep (called out as mandatory in AGENTS.md). Add -tags integration,test_dep for integration tests.
go test -tags test_dep -v ./service/history/workflow -run TestMutableStateImpl
go test -tags integration,test_dep -v ./common/persistence/cassandraPatterns and conventions
The project's test conventions are summarised in AGENTS.md and enforced by testifylint in make lint-code:
- Prefer
requireoverassertin unit tests.assertcontinues on failure and pollutes the failure log. - Avoid testify suites in unit tests (functional tests use them for cluster setup; that's fine).
require.Eventuallyinstead oftime.Sleep. The latter is forbidden by lint.- Float comparisons use
require.InDelta/require.InEpsilon, neverEqual. - In testify suites, use
s.Require().NoError(err)rather thans.NoError(err)(the latter doesn't fail-fast). - Test both happy and failure paths, especially around persistence retries, shard transitions, and replication conflicts.
Mocks
Generated mocks live next to the interface (e.g. data_interfaces_mock.go next to data_interfaces.go). Regenerate with:
go generate ./common/persistence/...Mocks are produced by go.uber.org/mock/mockgen; each mock file is annotated with //go:generate mockgen ... near the top of the source it mocks.
Integration test infrastructure
Persistence integration tests live in common/persistence/persistence-tests/. They use a small testify suite per backend; the same test bodies run against Cassandra, MySQL, Postgres, and SQLite. Bringing the backends up:
make start-dependencies # Docker compose: Cassandra, MySQL, PG, ES
make stop-dependenciesThe fault-injection wrapper at common/persistence/faultinjection/ wraps a real DB and randomly returns errors, used to exercise retry paths.
Functional tests
Under tests/. They:
- Bring up an in-process Temporal cluster via
tests/testcore/. - Drive it with a real Temporal SDK client (
go.temporal.io/sdk). - Assert on events, history, and outcomes.
They use testify suites because suite setup is non-trivial. Many functional tests are sharded across CI runners by the tools/optimize-test-sharding/ tool.
To run one functional test:
go test -tags test_dep,functional_test -v ./tests -run TestActivityApi -timeout 5mThe tests/xdc/ subdirectory holds cross-cluster (multi-DC) functional tests; they require two embedded clusters and exercise the replication path.
Coverage
make unit-test-coverage produces coverage reports uploaded to Codecov (config in .github/.codecov.yml). There is no hard percentage gate, but reviewers will ask about untested branches in critical paths (workflow state transitions, persistence retries, replication conflict resolution).
Flakiness and retries
The project has a custom flake-reporting tool at tools/flakereport/ that scrapes go-junit-report output and posts to Slack. If a test is flaky:
- Reproduce locally with
-count=10or higher. - Use
require.Eventuallyfor any timing-sensitive assertion. - If the flake comes from upstream infrastructure (Cassandra spin-up, Docker DNS), file a CI issue rather than disabling the test.
Adding a test
For a new persistence behaviour: add a method to data_interfaces.go, regenerate mocks, write a unit test against the mock, then add a row to the matrix in persistence-tests/.
For a new gRPC API: add the proto, run make proto, write a unit test against the handler, then add a functional test under tests/.
For a new CHASM library: follow the layout in chasm/lib/ — most existing libraries (workflow, scheduler, nexusoperation) are good templates.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.