How do I add Tests to this codebase?
This document outlines how to add tests to the fluxcd/flux2
codebase, which is written in Go, HCL, Shell, Makefile, and Dockerfile. The Golang Module name is github.com/fluxcd/flux2/v2
, which affects the go build
output.
Integration Tests
Integration tests are used to test the interaction between different parts of the system.
- Example:
tests/integration/suite_test.go
func init() {
utilruntime.Must(sourcev1.AddToScheme(scheme.Scheme))
utilruntime.Must(sourcev1beta2.AddToScheme(scheme.Scheme))
utilruntime.Must(kustomizev1.AddToScheme(scheme.Scheme))
utilruntime.Must(helmv2beta1.AddToScheme(scheme.Scheme))
utilruntime.Must(reflectorv1beta2.AddToScheme(scheme.Scheme))
utilruntime.Must(automationv1beta1.AddToScheme(scheme.Scheme))
utilruntime.Must(notiv1beta3.AddToScheme(scheme.Scheme))
random = rand.New(rand.NewSource(time.Now().UnixNano()))
}
func TestAzureDevOpsCommitStatus(t *testing.T) {
g := NewWithT(t)
ctx := context.TODO()
branchName := "commit-status"
testID := branchName + randStringRunes(5)
manifest := `apiVersion: v1
kind: ConfigMap
metadata:
name: foobar`
repoUrl := getTransportURL(cfg.applicationRepository)
tmpDir := t.TempDir()
c, err := getRepository(ctx, tmpDir, repoUrl, defaultBranch, cfg.defaultAuthOpts)
g.Expect(err).ToNot(HaveOccurred())
files := make(map[string]io.Reader)
files["configmap.yaml"] = strings.NewReader(manifest)
err = commitAndPushAll(ctx, c, files, branchName)
g.Expect(err).ToNot(HaveOccurred())
// ... rest of the test code
}
- Example:
tests/integration/flux_test.go
func TestRepositoryCloning(t *testing.T) {
ctx := context.TODO()
branchName := "feature/branch"
tagName := "v1"
g := NewWithT(t)
// ... rest of the test code
}
- Example:
tests/integration/util_test.go
// getRepository and clones the git repository to the directory.
func getRepository(ctx context.Context, dir, repoURL, branchName string, authOpts *git.AuthOptions) (*gogit.Client, error) {
c, err := gogit.NewClient(dir, authOpts, gogit.WithSingleBranch(false), gogit.WithDiskStorage())
if err != nil {
return nil, err
}
_, err = c.Clone(ctx, repoURL, repository.CloneConfig{
CheckoutStrategy: repository.CheckoutStrategy{
Branch: branchName,
},
})
if err != nil {
return nil, err
}
return c, nil
}
Unit Tests
Unit tests are used to test individual functions or methods.
- Example:
cmd/flux/trace_test.go
func TestTraceNoArgs(t *testing.T) {
cmd := cmdTestCase{
args: "trace",
assert: assertError("either `/` or ` ` is required as an argument"),
}
cmd.runTestCmd(t)
}
- Example:
internal/utils/utils_test.go
func TestCompatibleVersion(t *testing.T) {
tests := []struct {
name string
binary string
target string
want bool
}{
{"different major version", "1.1.0", "0.1.0", false},
{"different minor version", "0.1.0", "0.2.0", false},
{"same version", "0.1.0", "0.1.0", true},
{"binary patch version ahead", "0.1.1", "0.1.0", true},
{"target patch version ahead", "0.1.1", "0.1.2", true},
{"prerelease binary", "0.0.0-dev.0", "0.1.0", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := CompatibleVersion(tt.binary, tt.target); got != tt.want {
t.Errorf("CompatibleVersion() = %v, want %v", got, tt.want)
}
})
}
}
Running Tests
To run the tests, execute the following command from the root of the repository:
make test
This command runs all unit and integration tests.
Writing Tests
When writing tests, follow these guidelines:
- Use the
testing
package. This package provides the necessary functionality for writing tests in Go. - Use descriptive test names. This helps to make the tests more readable and understandable.
- Test one thing at a time. Each test should focus on testing a specific piece of functionality.
- Use
t.Errorf
andt.Fatalf
for reporting errors. These functions are used to report errors during the test execution. - Add new tests for new functionality. When adding new code, make sure to add tests to cover the new functionality.
Additional Resources
- Go Testing Documentation: https://golang.org/pkg/testing/
- Fluxcd/Flux2 Documentation: https://fluxcd.io/docs/flux2/