Skip to content

Commit

Permalink
update example for value comparers
Browse files Browse the repository at this point in the history
  • Loading branch information
austinvalle committed Aug 7, 2024
1 parent 5d34e1c commit bcdd810
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 87 deletions.
2 changes: 1 addition & 1 deletion website/docs/plugin/testing/acceptance-tests/testcase.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ but before any test steps are executed. The [Terraform Version Checks](/terrafor
are generic checks that check logic against the Terraform CLI version and can
immediately pass or fail a test before any test steps are executed.

The tfversion package provides built-in checks for common scenarios.
The [`tfversion`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/tfversion) package provides built-in checks for common scenarios.

**Example usage:**

Expand Down
215 changes: 133 additions & 82 deletions website/docs/plugin/testing/acceptance-tests/value-comparers/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,70 @@ description: >-

# Value Comparers

Value Comparers are for use in conjunction with [State Checks](/terraform/plugin/testing/acceptance-tests/state-checks), which leverage the [terraform-json](https://pkg.go.dev/github.com/hashicorp/terraform-json) representation of Terraform state.

## Usage
<Note>

Example uses in the testing module include:

- The [`CompareValue()`](/terraform/plugin/testing/acceptance-tests/state-checks/resource#comparevalue-state-check), [`CompareValueCollection()`](/terraform/plugin/testing/acceptance-tests/state-checks/resource#comparevaluecollection-state-check) and [`CompareValuePairs()`](/terraform/plugin/testing/acceptance-tests/state-checks/resource#comparevaluepairs-state-check) [built-in state checks](/terraform/plugin/testing/acceptance-tests/state-checks) use value comparers for comparing specific resource attribute, or output values.
Value Comparers are for use in conjunction with [State Checks](/terraform/plugin/testing/acceptance-tests/state-checks), which leverage the [terraform-json](https://pkg.go.dev/github.com/hashicorp/terraform-json) representation of Terraform state.

## Using a Value Comparer
</Note>

The value comparer types are implemented within the `terraform-plugin-testing` module in the [`compare` package](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/compare). Value comparers are instantiated by calling the relevant constructor function.
Value comparers can be used to assert a resource or data source attribute value across multiple [Test Steps](/terraform/plugin/testing/acceptance-tests/teststep), 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:
```go
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`:
```go
compare.ValuesDiffer()
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 types implement the [`ValueComparer` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/compare#ValueComparer). The `CompareValues()` method accepts a variadic argument of type `any`, which allows for comparison of arbitrary data structures.
The value comparer implementation (defined by the [`ValueComparer` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/compare#ValueComparer)) determines what assertion occurs when a state value is added. The built-in value comparers are:
- [`CompareValue()`](/terraform/plugin/testing/acceptance-tests/state-checks/resource#comparevalue-state-check)
- [`CompareValueCollection()`](/terraform/plugin/testing/acceptance-tests/state-checks/resource#comparevaluecollection-state-check)
- [`CompareValuePairs()`](/terraform/plugin/testing/acceptance-tests/state-checks/resource#comparevaluepairs-state-check)

## Values Differ Comparer Type
## Values Differ

The [ValuesDiffer](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/compare#ValuesDiffer) value comparer verifies that each value in the sequence of values supplied to the `CompareValues()` method differs from the preceding value.

Expand All @@ -35,50 +80,53 @@ Example usage of [ValuesDiffer](https://pkg.go.dev/github.com/hashicorp/terrafor
package example_test

import (
"testing"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"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"
"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{
{
// Example resource containing a computed attribute named "computed_attribute"
Config: `resource "test_resource" "one" {}`,
ConfigStateChecks: []statecheck.StateCheck{
compareValuesDiffer.AddStateValue(
"test_resource.one",
tfjsonpath.New("computed_attribute"),
),
},
},
{
// Example resource containing a computed attribute named "computed_attribute"
Config: `resource "test_resource" "one" {}`,
ConfigStateChecks: []statecheck.StateCheck{
compareValuesDiffer.AddStateValue(
"test_resource.one",
tfjsonpath.New("computed_attribute"),
),
},
},
},
})
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 Comparer Type
## Values Same

The [ValuesSame](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/compare#ValuesSame) value comparer verifies that each value in the sequence of values supplied to the `CompareValues()` method is the same as the preceding value.

Expand All @@ -88,45 +136,48 @@ Example usage of [ValuesSame](https://pkg.go.dev/github.com/hashicorp/terraform-
package example_test

import (
"testing"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"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"
"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{
{
// Example resource containing a computed attribute named "computed_attribute"
Config: `resource "test_resource" "one" {}`,
ConfigStateChecks: []statecheck.StateCheck{
compareValuesSame.AddStateValue(
"test_resource.one",
tfjsonpath.New("computed_attribute"),
),
},
},
{
// Example resource containing a computed attribute named "computed_attribute"
Config: `resource "test_resource" "one" {}`,
ConfigStateChecks: []statecheck.StateCheck{
compareValuesSame.AddStateValue(
"test_resource.one",
tfjsonpath.New("computed_attribute"),
),
},
},
},
})
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"),
),
},
},
},
})
}
```
4 changes: 0 additions & 4 deletions website/docs/plugin/testing/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ plugins, **it is highly recommended to use an account dedicated to testing, to
ensure no infrastructure is created in error in any environment that cannot be
completely and safely destroyed.**

HashiCorp runs nightly acceptance tests of providers found in the [Terraform
Providers GitHub Organization](https://github.com/terraform-providers) to ensure
each Provider is working correctly.

For a given plugin, Acceptance Tests can be run from the root of the project by
using a common make task:

Expand Down

0 comments on commit bcdd810

Please sign in to comment.