sigs.k8s.io/kubebuilder/v3@v3.14.0/docs/testing/integration.md (about) 1 **Writing and Running Integration Tests** 2 3 **This document is for kubebuilder v1 only** 4 5 This article explores steps to write and run integration tests for controllers created using Kubebuilder. Kubebuilder provides a template for writing integration tests. You can simply run all integration (and unit) tests within the project by running: `make test` 6 7 For example, there is a controller watching *Parent* objects. The *Parent* objects create *Child* objects. Note that the *Child* objects must have their `.ownerReferences` field setting to the `Parent` objects. You can find the template under `pkg/controllers/parent/parent_controller_test.go`: 8 ``` 9 package parent 10 11 import ( 12 _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" 13 childapis "k8s.io/child/pkg/apis" 14 childv1alpha1 "k8s.io/childrepo/pkg/apis/child/v1alpha1" 15 parentapis "k8s.io/parent/pkg/apis" 16 parentv1alpha1 "k8s.io/parentrepo/pkg/apis/parent/v1alpha1" 17 18 ...<other import items>... 19 ) 20 21 const timeout = time.Second * 5 22 23 var c client.Client 24 var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{Name: "parent", Namespace: "default"}} 25 var childKey = types.NamespacedName{Name: "child", Namespace: "default"} 26 27 func TestReconcile(t *testing.T) { 28 g := gomega.NewGomegaWithT(t) 29 30 // Parent instance to be created. 31 parent := &parentv1alpha1.Parent{ 32 ObjectMeta: metav1.ObjectMeta{ 33 Name: "parent", 34 Namespace: "default", 35 }, 36 Spec: metav1.ParentSpec{ 37 SomeSpecField: "SomeSpecValue", 38 AnotherSpecField: "AnotherSpecValue", 39 }, 40 } 41 42 // Setup the Manager and Controller. Wrap the Controller Reconcile function 43 // so it writes each request to a channel when it is finished. 44 mgr, err := manager.New(cfg, manager.Options{}) 45 46 // Setup Scheme for all resources. 47 if err = parentapis.AddToScheme(mgr.GetScheme()); err != nil { 48 t.Logf("failed to add Parent scheme: %v", err) 49 } 50 if err = childapis.AddToScheme(mgr.GetScheme()); err != nil { 51 t.Logf("failed to add Child scheme: %v", err) 52 } 53 54 // Set up and start test manager. 55 reconciler, err := newReconciler(mgr) 56 g.Expect(err).NotTo(gomega.HaveOccurred()) 57 recFn, requests := SetupTestReconcile(reconciler) 58 g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred()) 59 defer close(StartTestManager(mgr, g)) 60 61 // Create the Parent object and expect the Reconcile and Child to be created. 62 c = mgr.GetClient() 63 err = c.Create(context.TODO(), parent) 64 g.Expect(err).NotTo(gomega.HaveOccurred()) 65 defer c.Delete(context.TODO(), parent) 66 g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) 67 68 // Verify Child is created. 69 child := &childv1alpha1.Child{} 70 g.Eventually(func() error { return c.Get(context.TODO(), childKey, child) }, timeout). 71 Should(gomega.Succeed()) 72 73 // Manually delete Child since GC isn't enabled in the test control plane. 74 g.Expect(c.Delete(context.TODO(), child)).To(gomega.Succeed()) 75 } 76 ``` 77 78 `SetupTestReconcile` function above brings up an API server and etcd instance. Note that there is no any node creation for integration testing environment. If you want to test your controller on a real node, you should write end-to-end tests. 79 80 The manager is started as part of the test itself (`StartTestManager` function). 81 82 Both functions are located in `pkg/controllers/parent/parent_controller_suite_test.go` file. The file also contains a `TestMain` function that allows you to specify CRD directory paths for the testing environment.