Help us shape the future of Go! Take the 2026 Go Developer Survey

terraformtest

package
v1.138.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 19, 2026 License: Apache-2.0 Imports: 29 Imported by: 0

README

YAML Terraform lifecycle tests

Use one small Go wrapper per fixture folder:

func TestTerraform(t *testing.T) {
    terraformtest.Run(t, "testdata")
}

The runner discovers every .yaml and .yml file directly in that folder (non-recursively), relative to the test package. Each file becomes a Go subtest named after its filename without the extension. For example, testdata/TestTerraformGroupLifecycle.yaml appears as TestTerraform/TestTerraformGroupLifecycle in test output and CI reports. Adding a YAML file requires no additional Go test function. Empty folders and duplicate filename stems fail instead of silently skipping tests.

Subtests run sequentially in filename order, each with independent Terraform state and an HTTP fixture server. A failing lifecycle does not prevent later files from running. Select a single file with normal Go filtering:

go test ./qa/terraformtest -run '^TestTerraform$/^TestTerraformGroupLifecycle$'

Only selected files are loaded and validated. go test -list lists the Go wrapper, not dynamically discovered subtests; go test -v shows each subtest. Tests run the actual muxed Databricks provider, supporting both SDKv2 and Plugin Framework resources.

Install Terraform on PATH, or set TF_ACC_TERRAFORM_PATH to its executable. The normal GitHub Actions tests job installs Terraform 1.13.5 with its wrapper disabled so the test runner can invoke the CLI directly. These hermetic tests run in the normal Go test suite, including -short; they do not require TF_ACC, live credentials, or CLOUD_ENV. The runner does not download Terraform. Client configuration ignores ambient credential profiles and environment defaults; SDK HTTP traffic is restricted to the test's local fixture server. Do not use t.Parallel: Terraform CLI discovery is configured through process environment variables.

Test definition

Use version: 1, followed by steps and destroy. Each step has a human name, literal HCL under config, calls, and optional state expectations. State persists across steps. Destroy always runs using the last configuration; its HTTP exchanges belong under destroy.calls, and empty state is always checked. The testing framework also attempts cleanup after an interrupted test.

Each exchange contains request and response. Requests specify method, path, optional query (values are lists of strings), optional headers, and body. Responses specify an explicit HTTP status, optional headers, and body. Use body: null for no HTTP body and body: {json: null} for JSON null. Other JSON values go under body.json; IDs are literal, without substitution.

Matching uses the complete request signature. Independent signatures are unordered; repeated identical signatures consume their responses FIFO. Every HTTP call needs a consumable fixture, including Terraform's plan refreshes and the testing framework's post-apply consistency reads. Unexpected calls and unused fixtures fail with the step's index and name.

Optional host_metadata supplies a reusable JSON response for GET /.well-known/databricks-config throughout the test, keeping repeated client initialization out of the consumable resource exchanges.

State assertions are entirely optional. state.resources selects Terraform instance addresses to check, including data sources, modules, and indexed resources; it is not a complete inventory. Listed resources must exist, but unlisted resources are allowed. Each resource's attributes is a list of targeted checks using HashiCorp's tfjsonpath and knownvalue helpers:

state:
  resources:
    databricks_group.this:
      attributes:
        - path: [id]
          equals: group-id
        - path: [settings, enabled]
          equals: true
        - path: [items, 0, name]
          equals: first
        - path: [optional_field]
          equals: null

These paths illustrate the syntax, not the schema of databricks_group. Paths start with an attribute name. String segments are literal object/map keys; nonnegative integer segments are zero-based list indices. Quote numeric map keys ([labels, "0"]) to distinguish them from indices. Dots and brackets inside string keys are not parsed as path syntax. Index paths are suitable for lists, not Terraform sets, whose element order is not guaranteed.

equals is required for each check and accepts only a string, boolean, finite number, or null. Values are compared with their types preserved, so 42 is different from "42". equals: null requires a present null value; it does not match a missing attribute. Whole-object, list, and set assertions are deferred. Unselected values and extra attributes are allowed. A resource entry with no attributes checks only that the resource exists.

Omitting state, using state: {}, or using state: {resources: {}} adds no explicit state checks to a step. Terraform's normal apply and post-apply plan-consistency checks still run. Following HashiCorp's testing guidance, assert the attributes relevant to the behavior being tested, especially computed values and response-to-state conversions, rather than snapshotting every field.

Destroy always requires an empty resource inventory, including data sources in child modules. This is enforced by the engine; destroy accepts only calls, with no configurable final-state assertion.

MVP scope

Tests start with empty Terraform state and handwritten fixtures. YAML has strict field validation: initial checkpoints, recording/setup templates, plan assertions, plan-only steps, expected client errors, forced HTTP order, and strict attribute matching are not yet supported. Unsupported fields fail before any Terraform operations. The step/call/state layout is kept stable so these capabilities can be added independently.

Documentation

Overview

Package terraformtest runs hermetic Terraform lifecycles from YAML fixtures.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Run

func Run(t *testing.T, directory string)

Run discovers .yaml and .yml files directly in directory, relative to the test package, and runs each as a subtest named after its filename stem. Each lifecycle has independent Terraform state and HTTP fixtures. Subtests run sequentially in filename order and support normal go test -run filtering. Terraform must be installed; neither the wrapper nor its ancestors may use t.Parallel because CLI discovery uses process environment variables.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL