Stage 3 · Build
Testing & Release Confidence
CI Test Strategy
Split fast unit tests, integration suites, race detection, coverage thresholds, and flaky test quarantine.
Test Splitting
Run fast tests on every commit. Run slow integration tests on PR merges. This gives developers fast feedback while ensuring comprehensive coverage before production.
| Suite | Trigger | Duration | Dependencies |
|---|---|---|---|
| Unit | Every commit | < 30s | None |
| Integration | PR merge | 2-5 min | PostgreSQL, Redis |
| E2E | Nightly | 10-30 min | Full stack |
Fast Unit Tests
name: Unit Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Run unit tests
run: go test -short -count=1 ./...
- name: Run linter
uses: golangci/golangci-lint-action@v4
with:
version: latestUnit tests run on every push and PR. Use -short to skip integration tests. Add linting to catch code style issues. Keep this workflow under 30 seconds.
Integration Suites
name: Integration Tests
on:
push:
branches: [main]
jobs:
integration:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: testdb
ports: ['5432:5432']
redis:
image: redis:7
ports: ['6379:6379']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Run migrations
run: go run cmd/migrate/main.go
- name: Run integration tests
run: go test -tags=integration -count=1 -timeout 300s ./...
env:
DATABASE_URL: postgres://test:test@localhost:5432/testdb?sslmode=disable
REDIS_ADDR: localhost:6379Integration tests use GitHub Actions services for PostgreSQL and Redis. They run on merges to main. Run migrations before tests. Set a timeout to prevent hung tests.
Race Detection
name: Race Detection
on: [push, pull_request]
jobs:
race:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Run tests with race detector
run: go test -race -short -count=1 -timeout 120s ./...Race detection catches concurrent data access bugs. It adds overhead but catches critical bugs. Run it on every PR. The -short flag skips slow integration tests.
Coverage Thresholds
- name: Run tests with coverage
run: go test -short -coverprofile=coverage.out ./...
- name: Check coverage threshold
run: |
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
echo "Coverage: $COVERAGE%"
if (( $(echo "$COVERAGE < 70" | bc -l) )); then
echo "Coverage below 70% threshold"
exit 1
fi
- name: Upload coverage report
uses: codecov/codecov-action@v4
with:
file: coverage.outSet a coverage threshold (e.g., 70%). Fail CI if coverage drops below it. Upload coverage reports to Codecov or similar for trend tracking.
Flaky Test Quarantine
Developers should get test results in under 3 minutes. Split tests into fast (unit) and slow (integration). Run fast tests on every commit, slow tests on merges only.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.