Testing is a core part of Strait development process. We use a combination of unit, integration, E2E, and fuzz tests to ensure system reliability.Documentation Index
Fetch the complete documentation index at: https://docs.strait.dev/llms.txt
Use this file to discover all available pages before exploring further.
Test Infrastructure
Shared testing utilities are located inapps/strait/internal/testutil/:
testdb.go: Helpers for spinning up ephemeral PostgreSQL instances usingtestcontainers-go.testredis.go: Helpers for ephemeral Redis instances.factory.go: Data factories for generating test entities (jobs, runs, workflows).assert.go: Custom assertion helpers for common domain checks (usessamber/lofor collection queries).cmp.go: Structural comparison helpers powered bygoogle/go-cmpfor rich, human-readable diffs.
Running Tests
Unit Tests
Unit tests are fast and do not require external dependencies.Integration Tests
Integration tests require Docker to runtestcontainers. They are marked with the integration build tag.
End-to-End (E2E) Tests
E2E tests verify the entire system flow, from API request to job execution.Fuzz Tests
We use Go’s native fuzzing to test the robustness of the FSM transitions.Benchmarks
Performance benchmarks for critical paths like the job queue and workflow engine.Event Trigger Benchmarks
Integration-tagged benchmarks for event trigger database operations:BenchmarkListExpiredEventTriggers— Measures reaper query performance with 1000 triggersBenchmarkListByKeyPrefix— Measures prefix matching query performance with 1000 triggers
Load Tests
Strait has two load testing approaches that cover different concerns.Vegeta Load Tests (HTTP)
Vegeta-based tests inapps/strait/test/loadtest/ exercise every API route at scale using three attack modes: baseline (fixed-rate SLA validation), stress (high-rate ceiling discovery), and spike (linear ramp). Tests require the loadtest and integration build tags and spin up a full API server with testcontainers PostgreSQL.
jobs_test.go— CRUD, listing, filtering, pagination, batch operationstriggers_test.go— Single, bulk, idempotent, delayed, priority triggersruns_test.go— Listing, filtering, status transitions, replay, annotationsworkflows_test.go— CRUD, triggering, step run listing, concurrent operationssdk_test.go— Heartbeat, logging, checkpoints, progress, continuationwebhooks_test.go— Subscription managementrbac_test.go— API key CRUD, scoped access enforcementevents_test.go— Event sending and listingjob_groups_test.go— Group CRUD, job assignmentenvironments_test.go— Environment CRUD, variable managementmixed_test.go— Cross-resource concurrent operationsedge_cases_test.go— Malformed payloads, boundary values, conflict handling
Integration Load Tests (Go)
Go-native load tests inapps/strait/internal/e2e/ test internal subsystem throughput using testcontainers. They exercise queue, worker, webhook, workflow, rate limiting, store, and full pipeline operations at configurable volumes.
LOADTEST_VOLUME_TIER:
default (500 items), large (5,000 items), extreme (10,000 items).
Test files:
load_queue_test.go— Enqueue/dequeue throughput, concurrent operations, FSM transitionsload_worker_test.go— Bulk trigger, concurrent triggers, SDK heartbeat floodload_webhook_test.go— Subscription CRUD throughput, delivery listingload_workflow_test.go— Workflow creation, triggering, concurrent operationsload_ratelimit_test.go— Burst, sustained, mixed rate limit scenariosload_store_test.go— Direct store throughput for jobs, events, FSM, paginationload_pipeline_test.go— Full trigger-dequeue-complete lifecycle pipelines
Event Trigger Load Tests
Legacy integration-tagged load tests for event trigger throughput:TestEventTriggerLoadCreate— Sequential create throughput (500 triggers)TestEventTriggerLoadSendConcurrent— 50 concurrent event sends
CI Workflow
Load tests run via theLoad Tests GitHub Action (.github/workflows/loadtest.yml). This workflow is manually triggered via workflow_dispatch with configurable volume tier and duration. It runs Vegeta and integration load tests in parallel jobs, generates markdown summaries, and publishes results to the GitHub Actions step summary.
Advanced Testing Tools
Race Detector
Always run tests with the race detector enabled in CI and during local development of concurrent features.Code Coverage
Generate a coverage report to identify untested paths.Test Patterns
Table-Driven Tests
We prefer table-driven tests for testing multiple scenarios with the same logic.Parallel Execution
Uset.Parallel() in unit tests to speed up execution.
Structural Assertions with go-cmp
Usetestutil.AssertEqual for comparing complex structs. It produces rich, human-readable diffs on failure instead of opaque assertion messages.
apps/strait/internal/testutil/cmp.go:
AssertEqual(t, got, want, ...cmp.Option): Structural comparison with rich diff output.AssertJSONEqual(t, a, b []byte): JSON-aware comparison that ignores key ordering.EquateEmpty(): Treats nil slices/maps as equal to empty ones.IgnoreFields(typ, ...names): Skips specified fields during comparison (useful for timestamps, IDs).
Testcontainers
We usetestcontainers-go to manage the lifecycle of PostgreSQL and Redis during integration tests. This ensures a clean state for every test suite.
Mock Patterns
For packages likeapps/strait/internal/api and apps/strait/internal/scheduler, we use mock stores with configurable function fields:
mockPublisher supports configurable subscribeFn that returns real pubsub.Subscription instances with channels, enabling SSE stream testing without Redis.
Test Fixtures
Static test data and JSON payloads are stored intestdata/ directories within their respective packages.