# README
Using Pre-defined Environment Funcs
This package demonstrates how to use all part of the framework to setup and run an end-to-end test that retrieves API objects from Kubernetes for assessments. Specifically, it shows how to use pre-defined environment functions when setting up testing environment.
TestMain (test suite)
File main_tests.go
sets up the test suite for the package. In this test, the environment functions
are used to
Declare the test environment
The first step is to declare the global environment that will be used to run the test.
var (
testenv env.Environment
)
func TestMain(m *testing.M) {
testenv = env.New()
}
Configure environment Setup
functions
The next step is to define environment functions that are executed during setup.
This example uses predefined environment functions, in env.Step
, to specify the steps to execute prior to running any test:
envfuncs.CreateKindCluster
- creates a new kind cluster as part of the setup (and stores it in the context)envfuncs.CreateNamespace
- creates a new namespace API object on the server and sets the environment configuration to use it.
func TestMain(m *testing.M) {
testenv = env.New()
kindClusterName := envconf.RandomName("my-cluster", 16)
namespace := envconf.RandomName("myns", 16)
// Setup uses pre-defined funcs to create kind cluster
// and create a namespace for the environment
testenv.Setup(
envfuncs.CreateKindCluster(kindClusterName),
envfuncs.CreateNamespace(namespace),
)
...
}
Configure environment Finish
for cleanup
Next, the Environment.Finish
method is used to define steps that are executed to teardown the environment
after all tests are executed. The example uses predefined environment functions:
envfuncs.DeleteNamespace
- removes the namespace that was previously createdenvfuncs.DestroyKindCluster
- removes all cluster resources and deletes the kind cluster that was created earlier
func TestMain(m *testing.M) {
testenv = env.New()
...
// Finish uses pre-defined funcs to
// remove namespace, then delete cluster
testenv.Finish(
envfuncs.DeleteNamespace(namespace),
envfuncs.DestroyKindCluster(kindClusterName),
)
...
}
Start the test suite
The last step in defining the test suite is to launch it:
func TestMain(m *testing.M) {
...
os.Exit(testenv.Run(m))
}
Test functions
The framework uses a regular Go test function to define the end-to-end test. Once a suite is launched, after its setup is successful, Go test will run the Go test functions in the package.
Testing Kubernetes resources
The test function in this example, found in k8s_test.go
, use the framework to define two test features.
podFeature
- One test simply pulls a list of pods and report on the number of itemsdepFeature
- The other test inject a deployment object, inspect, and then deletes it
Defining a feature to test pod items
func TestKubernetes(t *testing.T) {
podFeature := features.New("pod list").
Assess("pods from kube-system", func (ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
var pods corev1.PodList
err := cfg.Client().Resources("kube-system").List(context.TODO(), &pods)
if err != nil {
t.Fatal(err)
}
t.Logf("found %d pods", len(pods.Items))
if len(pods.Items) == 0 {
t.Fatal("no pods in namespace kube-system")
}
return ctx
}).Feature()
...
}
Defining a feature to test deployment objects
func TestKubernetes(t *testing.T) {
...
// feature uses pre-generated namespace (see TestMain)
depFeature := features.New("appsv1/deployment").
Setup(func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
// insert a deployment
deployment := newDeployment(cfg.Namespace(), "test-deployment", 1)
if err := cfg.Client().Resources().Create(ctx, deployment); err != nil {
t.Fatal(err)
}
time.Sleep(2 * time.Second)
return ctx
}).
Assess("deployment creation", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
var dep appsv1.Deployment
if err := cfg.Client().Resources().Get(ctx, "test-deployment", cfg.Namespace(), &dep); err != nil {
t.Fatal(err)
}
if &dep != nil {
t.Logf("deployment found: %s", dep.Name)
}
return context.WithValue(ctx, "test-deployment", &dep)
}).
Teardown(func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
dep := ctx.Value("test-deployment").(*appsv1.Deployment)
if err := cfg.Client().Resources().Delete(ctx, dep); err != nil {
t.Fatal(err)
}
return ctx
}).Feature()
...
}
Execute the feature test
The last step in defining the test is to use the framework to launch the tests.
func TestKubernetes(t *testing.T) {
podFeature := features.New("pod list")...
depFeature := features.New("appsv1/deployment")...
testenv.Test(t, podFeature, depFeature)
}
Run the test
Use the Go test tool to run the test.
$ go test . -v