Testing Guide⚓
This document describes the comprehensive testing setup for the Locust K8s Operator, covering unit tests, integration tests (envtest), and end-to-end tests.
Overview⚓
The operator uses a multi-layered testing strategy:
| Test Type | Framework | Scope | Speed |
|---|---|---|---|
| Unit Tests | Go testing | Individual functions | Fast (~seconds) |
| Integration Tests | envtest | Controller + API Server | Medium (~30s) |
| E2E Tests | Ginkgo + Kind | Full cluster deployment | Slow (~5-10min) |
Test Structure⚓
locust-k8s-operator/
├── api/
│ ├── v1/
│ │ └── *_test.go # v1 API tests
│ └── v2/
│ ├── *_test.go # v2 API tests
│ └── locusttest_webhook_test.go # Webhook validation tests
├── internal/
│ ├── config/
│ │ └── config_test.go # Configuration tests
│ ├── controller/
│ │ ├── suite_test.go # envtest setup
│ │ ├── locusttest_controller_test.go # Unit tests
│ │ └── integration_test.go # Integration tests
│ └── resources/
│ ├── job_test.go # Job builder tests
│ ├── service_test.go # Service builder tests
│ ├── labels_test.go # Label builder tests
│ ├── env_test.go # Environment builder tests
│ └── command_test.go # Command builder tests
└── test/
└── e2e/
├── e2e_suite_test.go # E2E test setup
└── e2e_test.go # E2E test scenarios
Prerequisites⚓
- Go 1.24+: Required for running tests
- Docker: Required for E2E tests (Kind)
- Kind: Required for E2E tests
Running Tests⚓
Unit & Integration Tests (envtest)⚓
The primary test command runs both unit tests and integration tests using envtest:
# Run all tests with coverage
make test
# Run tests with verbose output
go test ./... -v
# Run specific package tests
go test ./internal/resources/... -v
go test ./internal/controller/... -v
go test ./api/v2/... -v
# Run specific test by name
go test ./internal/controller/... -v -run TestReconcile
# Generate coverage report
make test
go tool cover -html=cover.out -o coverage.html
E2E Tests (Kind)⚓
End-to-end tests run against a real Kubernetes cluster using Kind:
# Run E2E tests (creates Kind cluster automatically)
make test-e2e
# Run E2E tests with verbose output
KIND_CLUSTER=locust-test go test ./test/e2e/ -v -ginkgo.v
# Cleanup E2E test cluster
make cleanup-test-e2e
CI Pipeline⚓
All tests run automatically in GitHub Actions:
# Run the same checks as CI locally
make ci
# This runs:
# - make lint (golangci-lint)
# - make test (unit + integration tests)
Test Fixtures⚓
Test fixtures and sample data are located in:
internal/testdata/- Test fixtures for unit testsconfig/samples/- Sample CRs for integration/E2E tests
Troubleshooting⚓
Common Issues⚓
envtest Binary Issues⚓
Test Timeouts⚓
Kind Cluster Issues⚓
# Check if cluster exists
kind get clusters
# Delete and recreate
kind delete cluster --name locust-k8s-operator-test-e2e
make test-e2e
Debug Mode⚓
Run tests with verbose logging:
# Verbose test output
go test ./internal/controller/... -v -ginkgo.v
# With debug logs from controller
go test ./internal/controller/... -v -args -zap-log-level=debug
Writing New Tests⚓
Guidelines⚓
- Unit tests: Test pure functions in isolation
- Integration tests: Test controller behavior with envtest
- E2E tests: Test user-facing scenarios in real cluster
Test Naming Conventions⚓
// Unit tests: Test<FunctionName>_<Scenario>
func TestBuildMasterJob_WithEnvConfig(t *testing.T) {}
// Integration tests: Describe/Context/It
Describe("LocustTest Controller", func() {
Context("When creating a LocustTest", func() {
It("Should create master Job", func() {})
})
})
Adding Integration Tests⚓
- Add test to
internal/controller/integration_test.go - Use
k8sClientfor Kubernetes operations - Use
Eventuallyfor async assertions - Clean up resources in
AfterEach
Related Documentation⚓
- Local Development - Development setup
- Contributing - Contribution guidelines
- Pull Request Process - PR workflow