Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Testing

Tazuna’s tests are split into 3 layers: unit / integration / e2e. Each layer corresponds 1:1 with a make target; unit always runs on PRs (CI), while e2e is a manual layer that assumes KinD.

Layers and How to Run

LayerCommandTargetsPrerequisites
unitmake testgo test ./...None. Runs on every push / PR via the CI workflow in GitHub Actions.
integrationmake test-integrationgo test -tags=integration ./...None. Additional tests tagged with the integration build tag are targets.
e2emake test-e2ego test -tags=e2e -count=1 ./test/e2e/...KinD cluster. Internally runs make build && make devenv-create.
Allmake test-allunit → integration → e2eSame as e2e
Coveragemake coverRuns unit tests with -race -covermode=atomic -coverprofile=coverage.out, then outputs a summaryNone

In CI (.github/workflows/ci.yaml), go test -race -covermode=atomic -coverprofile=coverage.out ./... is run, so the contents largely match make cover.

Unit Tests

Written as *_test.go in every package. Standard Go tests. They have no dependency on KinD or external CLIs, and go test ./... is self-contained.

PR review requires this layer to be green as a prerequisite.

Integration Tests

Additional tests tagged with the integration build tag. Run with make test-integration. The place to isolate scenarios that have no external dependencies but are too heavy for unit tests.

Running go test -tags=integration ./... directly is equivalent.

E2E Tests

Real-cluster tests placed in test/e2e/. Isolated by the e2e build tag, with only ./test/e2e/... targeted.

Running make test-e2e internally runs the following in order.

  1. make build (build ./tazuna)
  2. make devenv-create (stand up the KinD cluster tazuna, or switch context if one already exists)
  3. go test -tags=e2e -count=1 ./test/e2e/...

-count=1 is set so that e2e tests are not cached and actually run every time. The KinD cluster is cleaned up by make devenv-destroy (kind delete cluster --name tazuna).

KinD Cluster Specifications

ItemValue
Cluster nametazuna
kubeconfig contextkind-tazuna
Config file.github/kind-config.yaml

Because CI and developer local environments share the same KinD config, e2e that passes locally generally also passes in CI.

Test Data

E2E fixtures are placed per-case under test/e2e/testdata/. Each case directory holds a tazuna.yaml alongside the actual content (kustomize/ / helmfile/ etc.) corresponding to its type.

test/e2e/testdata/
├── kustomize-minimal/         # minimal case for type: kustomize
├── helmfile-minimal/          # minimal case for type: helmfile
├── parallel-minimal/          # type: parallel
├── testplugin-minimal/        # basic Test plugin (WaitUntil/ExistNonExist)
├── testplugin-cel/            # case with complex CEL expressions in WaitUntil
├── tags-filter-minimal/       # --tags filter
├── state-minimal/             # state list/diff/sync
├── state-modified/            # "modified" judgment in state diff
├── destroy-minimal/           # tazuna destroy
└── check-invalid/             # tazuna check error cases

When adding a new feature, the common flow is to add a corresponding fixture directory with a single minimal tazuna.yaml, and add a *_test.go under test/e2e/.

Lint

make lint

Simply calls golangci-lint run. The golangci-lint version is managed via mise.toml, so running mise install is sufficient — no additional steps required.

CI also runs the same golangci-lint. Running it locally before opening a PR reduces back-and-forth.