Skip to content

Testing

DataKit uses a layered test strategy: fast unit tests for packages, Docker-backed integration tests for external behavior, and end-to-end tests that exercise the CLI workflow from package scaffolding through build.

    flowchart LR
  U[Unit tests] --> I[Integration tests]
  I --> E[E2E tests]
  U --> T[Transform package checks]
  T --> E
  

Make targets

Run the standard targets from the repository root:

make test-unit
make test-integration
make test-e2e

These targets are defined in the root Makefile:

  • make test-unit runs unit tests across contracts/, sdk/, cli/, and platform/controller/
  • make test-integration runs Docker-backed integration suites such as sdk/promotion/...
  • make test-e2e runs go test -v ./... under tests/e2e

Unit test patterns

The codebase consistently uses standard Go test structure:

  • table-driven tests with t.Run(...)
  • *_test.go files beside the package under test
  • t.TempDir() for disposable package directories and fixtures
  • direct assertions against parsed manifests, flags, and result structs

Examples you can copy from the codebase:

  • sdk/runner/runner_test.go validates RunOptions with table-driven cases
  • cli/cmd/run_test.go and cli/cmd/test_test.go write minimal dk.yaml files into t.TempDir()
  • tests/e2e/helpers.go centralizes helpers such as createTempDir() and assertFileExists()

Integration tests

Integration tests require Docker and exercise behavior that depends on external systems. The root Makefile calls these with the integration build tag:

cd sdk && go test -v -tags integration ./promotion/...
cd platform/controller && go test -v -tags integration ./internal/controller/...

Use integration tests when the behavior depends on container runtime access, registry interactions, or controller reconciliation logic that unit tests cannot model faithfully.

End-to-end tests

The E2E suite under tests/e2e/ validates the CLI workflow itself. tests/e2e/workflow_test.go covers the expected init → lint → build loop, and also iterates across generic-go, generic-python, dbt, and cloudquery runtimes.

Use E2E tests to prove that a user can successfully:

  • scaffold a package
  • generate dk.yaml
  • lint the package
  • build it with --dry-run

Writing tests for transforms

When you add or change transform behavior, mirror the patterns already used in CLI and runner tests:

  1. Create a disposable package directory with t.TempDir()
  2. Write the minimal dk.yaml needed for the scenario
  3. Prefer dk test <package> or runner dry-runs for fast validation paths
  4. Assert on status, exit behavior, and generated files instead of logs alone

A representative runner pattern from sdk/runner/docker_test.go is:

result, err := runner.Run(context.Background(), RunOptions{
    PackageDir: tmpDir,
    DryRun:     true,
})

A representative CLI pattern from cli/cmd/test_test.go is to write a transform manifest into t.TempDir() and then call runTest(cmd, []string{tmpDir}).

See Also