This document outlines the testing strategy for gobackup-operator, following best practices from well-known Kubernetes operators like prometheus-operator, ArgoCD operator, and etcd-operator.
The testing approach follows a three-tier strategy:
- Unit Tests: Fast, isolated tests that don't require a Kubernetes API server
- Integration Tests: Tests using envtest that require a Kubernetes API server but no actual cluster
- End-to-End (E2E) Tests: Tests that run against a real Kubernetes cluster
- Go 1.21+
- kubectl configured to connect to a Kubernetes cluster (for E2E tests)
- kind (optional, for local E2E testing)
- Docker (for building operator images)
Fast unit tests that test individual functions:
make test-unitIntegration tests using envtest (requires test binaries):
make test-integrationRun all tests including integration tests:
make testE2E tests require a running Kubernetes cluster:
# Using an existing cluster
make test-e2e
# Or using kind (local cluster)
make kind-run
make test-e2eGenerate a test coverage report:
make test-coverageThis generates cover.html which you can open in a browser to see coverage details.
Located in package directories with _test.go suffix:
pkg/k8sutil/*_test.go- Utility function tests
Located in internal/controller/:
suite_test.go- Test suite setup with envtestbackup_controller_test.go- Controller reconciliation tests
Located in test/e2e/:
e2e_test.sh- End-to-end test script
Integration tests use Ginkgo and Gomega (BDD-style testing):
var _ = Describe("Backup Controller", func() {
var (
ctx context.Context
testNamespace string
)
BeforeEach(func() {
ctx = context.Background()
testNamespace = "test-" + time.Now().Format("20060102-150405")
// Create test namespace...
})
It("Should create a Job for immediate backup", func() {
// Test implementation
})
})- Isolation: Each test should be independent and not rely on other tests
- Cleanup: Always clean up resources in
AfterEachblocks - Timeouts: Use
Eventuallywith appropriate timeouts for async operations - Fixtures: Use helper functions to create test resources
- Assertions: Use descriptive
Expectstatements with clear error messages
- Minimum: 70% overall coverage
- Critical paths: 90%+ coverage for controller reconciliation logic
- Target: 80%+ overall coverage
Tests are designed to run in CI/CD pipelines:
# CI pipeline example
make test
make lint
make buildIf envtest tests fail, ensure binaries are downloaded:
make envtestIf E2E tests fail:
- Check cluster connectivity:
kubectl cluster-info - Verify CRDs are installed:
kubectl get crd | grep gobackup - Check operator logs:
kubectl logs -n gobackup-operator-system -l control-plane=controller-manager