liveBook · Manning

Test automation framework

As explained in Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu

A testing framework is a software system that provides conventions and utilities for creating, running, and evaluating automated tests.

A Terraform testing framework provides a Terraform-centric safety net for modules, helping developers review pull requests and detect breaking changes despite infrastructure-testing costs such as long runtimes and orphaned resources. section 9.7

Its distinctive model is direct access to module state: a test can use a full resource path to inspect resources, data sources, and local variables after execution. Terratest instead wraps Terraform externally, so it cannot validate internal state in the same way. section 9.4.2

Listing 9.22 Accessing named values
variables {
  test_input = "test"
}
 
run "input_passed_to_resource" {
  assert {
    condition     = terraform_data.this.input == "test"    #1
    error_message = "The resource parameter does not match the input."
  }
}

A named-value assertion checks that an input reaches a resource, demonstrating direct inspection of a module's internal value. section 9.4.2

Use the framework with these operational patterns:

  • Place tests beside examples when examples serve as test cases; each example then requires initialization and a local terraform test invocation. section 9.4.4
  • Automate coverage with make terraform_test, which iterates through example directories, initializes without a backend, and runs each test. section 9.4.4
  • Treat Terraform and the testing framework as one versioned unit: switching Terraform or OpenTofu changes the framework version and available features. section 9.4.5
  • Account for compatibility limits: framework features may prevent testing older Terraform versions, while supported-version requirements force use of the lowest common feature set. section 9.4.5
Listing 9.28 The module block
TERRAFORM_EXAMPLES:=$(wildcard examples/*)          #1
TF_TEST_OPTS:=
 
 
.PHONY: $(TERRAFORM_EXAMPLES)                       #2
$(TERRAFORM_EXAMPLES):                              #3
    @echo "Testing $@"                              #4
    cd $@ && \                                      #5
    $(TF_BINARY) init -backend=false && \           #6
    $(TF_BINARY) test $(TF_TEST_OPTS)               #7
 
.PHONY: terraform_test
terraform_test: $(TERRAFORM_EXAMPLES)               #8
    @echo "Testing Root Module"
    $(TF_BINARY) test $(TF_TEST_OPTS)               #9

A Makefile can discover example directories and provide one aggregate target while retaining direct targets for individual example tests. section 9.4.4

Listing 9.29 makefile support
TERRAFORM_VERSION:=$(shell cat .terraform-version)        #1
TOFU_VERSION:=$(shell cat .terraform-version)             #2
TF_ENGINE:=terraform                                      #3
ifeq ($(TF_ENGINE), terraform)                            #4
    TF_BINARY:=terraform
    TF_VERSION:=$(TERRAFORM_VERSION)                      #5
else ifeq ($(TF_ENGINE), opentofu)
    TF_BINARY:=tofu
    TF_VERSION:=$(TOFU_VERSION)                           #6
endif
 
ifeq ($(CI), )                                            #7
    TF_ENV_COMMAND:=tenv use $(TF_BINARY) $(TF_VERSION)
else                                                      #8
    TF_ENV_COMMAND:=echo "skipping tenv use in CI"
endif
 
TERRAFORM_EXAMPLES:=$(wildcard examples/*)
TF_TEST_OPTS:=                                            #9
 
.PHONY: $(TERRAFORM_EXAMPLES)
$(TERRAFORM_EXAMPLES):
    @echo "Testing $@"
    cd $@ && \
    $(TF_ENV_COMMAND) && \                                #10
    $(TF_BINARY) init -backend=false && \
    $(TF_BINARY) test $(TF_TEST_OPTS)
 
.PHONY: terraform_test_root
terraform_test_root:                                      #11
    @echo "Testing Root Module"
    $(TF_ENV_COMMAND) && \                                #12
    $(TF_BINARY) test $(TF_TEST_OPTS)
 
.PHONY: terraform_test                                    #13
terraform_test: $(TERRAFORM_EXAMPLES) terraform_test_root #14

Version-aware Makefile support selects Terraform or OpenTofu, coordinates tenv locally, and skips local version switching in CI. section 9.4.5

How Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu covers it

How deep it goes
Reaches internal resources, data sources, locals, example orchestration, and version constraints, but remains tightly coupled to Terraform releases.
Examples
Uses named-value assertions, example-directory tests, Make targets, backendless initialization, and version-aware local or CI execution.
What it assumes
Assumes familiarity with Terraform modules, resources, examples, and command execution while teaching internal-value assertions and test orchestration.
What you can do after
Apply it via terraform test and Make targets to validate module internals and run tests across examples.
How it connects
Connects Terraform modules with Terraform, OpenTofu, Terratest, Make, tenv, and continuous integration.

Also explained in

Compare how 4 books explain test automation framework →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu. The section links point to the parts of the book it draws on.