In this lesson, you will learn how to validate your custom controller logic by running a real, lightweight Kubernetes API server directly within your test suite using envtest.
Why use Envtest?
When you write a controller, the "truth" of your system lives in the Kubernetes API. Mocking every API call is error-prone and complex. envtest allows you to spin up a binary of the kube-apiserver and etcd locally during your test execution. This lets your controller interact with a genuine API server without needing a full-blown cluster (like KinD or Minikube), making your CI pipeline significantly faster.
Setting up the Environment
In your suite_test.go file, you configure the envtest.Environment. This handles the binaries for the API server and points your controller manager to a local, ephemeral port:
var testEnv *envtest.Environment
var cfg *rest.Config
func TestMain(m *testing.M) {
testEnv = &envtest.Environment{
CRDDirectoryPaths: []string{filepath.Join("config", "crd", "bases")},
}
cfg, err := testEnv.Start()
// handle err...
code := m.Run()
testEnv.Stop()
os.Exit(code)
}
Writing the Integration Test
Once the environment is running, your tests can use the client to create custom resources. Because your controller is also watching this same API server, it will trigger its Reconcile loop automatically when you create, update, or delete objects.
To verify logic, you simply perform an action and use Eventually blocks to poll for the expected state:
func TestReconcile(t *testing.T) {
// 1. Create a Custom Resource
myObj := &myv1.MyResource{...}
Expect(k8sClient.Create(ctx, myObj)).To(Succeed())
// 2. Assert the controller modified the resource
Eventually(func() bool {
err := k8sClient.Get(ctx, key, myObj)
return err == nil && myObj.Status.Ready == true
}, time.Second*5, time.Millisecond*250).Should(BeTrue())
}
By leveraging envtest, you confirm that your controller reacts correctly to real Kubernetes events, ensuring your logic handles edge cases—like resource ownership and status updates—accurately before you ever deploy to a production cluster.
Key Takeaway: Envtest provides an ephemeral, local API server that allows you to test your controller's reconciliation logic against actual Kubernetes state without the overhead of a full cluster.