# Writing controller tests

Testing Kubernetes controllers is a big subject, and the boilerplate testing
files generated for you by kubebuilder are fairly minimal.

To walk you through integration testing patterns for Kubebuilder-generated controllers, this guide revisits the CronJob built in the first tutorial and writes a simple test for it.

The basic approach is that, in your generated `suite_test.go` file, you uses envtest to create a local Kubernetes API server, instantiate and run your controllers, and then write additional `*_test.go` files to test it using [Ginkgo](http://onsi.github.io/ginkgo).

If you want to tinker with how your envtest cluster is configured, see section [Configuring envtest for integration tests](../reference/envtest.md) as well as the [`envtest docs`](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/envtest?tab=doc).

<aside class="note" role="note">
<p class="note-title">Other Examples</p>

If you would like to see additional examples of controller tests generated by Kubebuilder, take a look at the <a href="../plugins/available/deploy-image-plugin-v1-alpha.md">Deploy Image plugin (deploy-image/v1-alpha)</a>.
This plugin scaffolds APIs and controllers for managing an Operand (container image) on a cluster, following recommended patterns.

The plugin abstracts much of the complexity of managing Deployments while still allowing you to customize the generated code.
When you enable it, the plugin also generates a controller test that uses <a href="../reference/envtest.md">ENV TEST</a> to verify that the controller creates the expected Deployment.

An example of this test can be found under the `testdata` directory in the Kubebuilder repository:
<a href="https://github.com/kubernetes-sigs/kubebuilder/blob/master/testdata/project-v4-with-plugins/internal/controller/busybox_controller_test.go">testdata/project-v4-with-plugins/internal/controller/busybox_controller_test.go</a>.
</aside>

## Test environment setup

{{#literatego ../cronjob-tutorial/testdata/project/internal/controller/suite_test.go}}

## Testing your Controller's Behavior

{{#literatego ../cronjob-tutorial/testdata/project/internal/controller/cronjob_controller_test.go}}

This Status update example above demonstrates a general testing strategy for a custom Kind with downstream objects. By this point, you hopefully have learned the following methods for testing your controller behavior:

* Setting up your controller to run on an envtest cluster
* Writing stubs for creating test objects
* Isolating changes to an object to test specific controller behavior
