TerraformXXI · Testing, Linting, and Static AnalysisTesting
terraform test: The Native Test Framework
What you'll learn
- Use terraform test to write unit tests
- Use plan tests to verify resource changes
- Use mock providers to test without real resources
- Recognise when terraform test is appropriate
Prerequisites
Verified against Terraform CLI 1.9.x · OpenTofu 1.7.x · HCL 2.0 · bpg/proxmox provider 0.66+ · hashicorp/local provider 2.5+ · hashicorp/null provider 3.2+ · hashicorp/random provider 3.6+ · hashicorp/http provider 3.4+ · Ubuntu 24.04 LTS · Debian 12 (Bookworm) · 2026-08-12
terraform test is the native test framework for Terraform. It
runs .tftest.hcl files that contain test blocks. The tests
can be unit tests, plan tests, or integration tests. The lesson
teaches the test framework and the production patterns.
Test files
A terraform test run discovers *.tftest.hcl files in the
current directory:
tests/
├── main.tftest.hcl
├── outputs.tftest.hcl
└── variables.tftest.hcl
Each file contains a sequence of run blocks:
# tests/main.tftest.hcl
run "test_greeting_is_hello" {
command = plan
expect {
resources = {
local_file.hello = {
content = "Hello, world!\n"
}
}
}
}
The run block:
- Specifies the command (
planorapply). - Specifies the expected outputs (
expectblock).
The test commands
The command argument can be:
plan— runsterraform planand inspects the result.apply— runsterraform applyand inspects the result.
The plan command is read-only. The apply command
modifies the real world (or the mock providers).
The expect block
The expect block specifies the expected output:
run "test_greeting_content" {
command = plan
expect {
resources = {
local_file.hello = {
content = "Hello, world!\n"
}
}
}
}
The expect block can match:
resources— the resources in the plan.outputs— the outputs in the plan.inputs— the variables passed to the module.state— the state (forapplytests).
Mock providers
For unit tests, mock providers are used to avoid real resources:
# tests/greeting.tftest.hcl
mock_provider "local" {
mock_resource "local_file" {
defaults = {
filename = "/tmp/hello.txt"
content = "Hello, world!\n"
}
}
}
run "test_greeting_with_mock" {
command = plan
expect {
resources = {
local_file.hello = {
filename = "/tmp/hello.txt"
content = "Hello, world!\n"
}
}
}
}
The mock provider returns the configured defaults. The test runs without real resources.
The plan test
The plan test verifies the plan matches the expectation:
run "test_plan_no_changes" {
command = plan
expect {
# No changes expected
changes = {}
}
}
The test fails if the plan is not empty.
The apply test
The apply test verifies the real-world matches the configuration:
run "test_apply_creates_file" {
command = apply
expect {
resources = {
local_file.hello = {
filename = "/tmp/hello.txt"
content = "Hello, world!\n"
}
}
}
}
The apply test creates a real resource. The test cleans up the resource after the run.
The test runner
The test runner:
# Run all tests
terraform test
# Run a specific test file
terraform test tests/main.tftest.hcl
# Run with verbose output
terraform test -verbose
# Run with a specific filter
terraform test -filter test_greeting
The output:
tests/main.tftest.hcl... in progress
run "test_greeting_is_hello"... pass
run "test_greeting_content"... pass
tests/main.tftest.hcl... pass
Success! 2 passed.
The production pattern
A production Terraform module has tests:
modules/network/
├── main.tf
├── variables.tf
├── outputs.tf
├── versions.tf
└── tests/
├── main.tftest.hcl
├── outputs.tftest.hcl
└── variables.tftest.hcl
The tests are:
- Unit tests with mock providers.
- Plan tests with the actual configuration.
- Apply tests with the actual configuration.
The tests run in CI. The tests are the production control for the module.
What comes next
The next lesson is linting — tflint and the production
control for configuration style.
Verification
Knowledge check · 7 questions
Q1. What is the role of the layered testing model?
Q2. What is terraform test?
Q3. terraform test is a separate tool that requires installation.
Q4. What is the role of mock providers in tests?
Q5. Which of the following are part of the layered testing model? (Select all that apply.)
Q6. What is the role of the plan test in terraform test?
Q7. A terraform test fails. What is the next step?
Passing score: 75%. Answers are checked in this browser.