Terraform
Value Comparers
Note
Value Comparers are for use in conjunction with State Checks, which leverage the terraform-json representation of Terraform state.
Value comparers can be used to assert a resource or data source attribute value across multiple Test Steps, like asserting that a randomly generated resource attribute doesn't change after multiple apply steps. This is done by creating the value comparer, typically before the test case is defined, using the relevant constructor function:
func TestExample(t *testing.T) {
// Create the value comparer so we can add state values to it during the test steps
compareValuesDiffer := statecheck.CompareValue(compare.ValuesDiffer())
resource.Test(t, resource.TestCase{
// Provider definition omitted.
Steps: []resource.TestStep{
// .. test steps omitted
},
})
}
Once the value comparer is created, state values can be added in TestStep.ConfigStateChecks
:
func TestExample(t *testing.T) {
// Create the value comparer so we can add state values to it during the test steps
compareValuesDiffer := statecheck.CompareValue(compare.ValuesDiffer())
resource.Test(t, resource.TestCase{
// Provider definition omitted.
Steps: []resource.TestStep{
{
Config: `resource "test_resource" "one" {}`,
ConfigStateChecks: []statecheck.StateCheck{
// Add the current state value of "computed_attribute" to the value comparer.
// Since there are no other state values at this point, no assertion is made.
compareValuesDiffer.AddStateValue(
"test_resource.one",
tfjsonpath.New("computed_attribute"),
),
},
},
{
Config: `resource "test_resource" "one" {}`,
ConfigStateChecks: []statecheck.StateCheck{
// Add the current state value of "computed_attribute" to the value comparer.
// Since there is an existing state value in the value comparer at this point,
// if the two values are equal, the test will produce an error.
compareValuesDiffer.AddStateValue(
"test_resource.one",
tfjsonpath.New("computed_attribute"),
),
},
},
},
})
}
The value comparer implementation (defined by the ValueComparer
interface) determines what assertion occurs when a state value is added. The built-in value comparers are:
Values Differ
The ValuesDiffer value comparer verifies that each value in the sequence of values supplied to the CompareValues()
method differs from the preceding value.
Example usage of ValuesDiffer in a CompareValue state check.
package example_test
import (
"testing"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-testing/compare"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/statecheck"
"github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
)
func TestCompareValue_CheckState_ValuesDiffer(t *testing.T) {
t.Parallel()
compareValuesDiffer := statecheck.CompareValue(compare.ValuesDiffer())
resource.Test(t, resource.TestCase{
// Provider definition omitted.
Steps: []resource.TestStep{
{
Config: `resource "test_resource" "one" {}`,
ConfigStateChecks: []statecheck.StateCheck{
// Add the current state value of "computed_attribute" to the value comparer.
// Since there are no other state values at this point, no assertion is made.
compareValuesDiffer.AddStateValue(
"test_resource.one",
tfjsonpath.New("computed_attribute"),
),
},
},
{
// Add the current state value of "computed_attribute" to the value comparer.
// Since there is an existing state value in the value comparer at this point,
// if the two values are equal, the test will produce an error.
Config: `resource "test_resource" "one" {}`,
ConfigStateChecks: []statecheck.StateCheck{
compareValuesDiffer.AddStateValue(
"test_resource.one",
tfjsonpath.New("computed_attribute"),
),
},
},
},
})
}
Values Same
The ValuesSame value comparer verifies that each value in the sequence of values supplied to the CompareValues()
method is the same as the preceding value.
Example usage of ValuesSame in a CompareValue state check.
package example_test
import (
"testing"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-testing/compare"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/statecheck"
"github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
)
func TestCompareValue_CheckState_ValuesSame(t *testing.T) {
t.Parallel()
compareValuesSame := statecheck.CompareValue(compare.ValuesSame())
resource.Test(t, resource.TestCase{
// Provider definition omitted.
Steps: []resource.TestStep{
{
Config: `resource "test_resource" "one" {}`,
ConfigStateChecks: []statecheck.StateCheck{
// Add the current state value of "computed_attribute" to the value comparer.
// Since there are no other state values at this point, no assertion is made.
compareValuesSame.AddStateValue(
"test_resource.one",
tfjsonpath.New("computed_attribute"),
),
},
},
{
Config: `resource "test_resource" "one" {}`,
ConfigStateChecks: []statecheck.StateCheck{
// Add the current state value of "computed_attribute" to the value comparer.
// Since there is an existing state value in the value comparer at this point,
// if the two values are not equal, the test will produce an error.
compareValuesSame.AddStateValue(
"test_resource.one",
tfjsonpath.New("computed_attribute"),
),
},
},
},
})
}