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.