--- name: review-tests-helpers description: "Review Terraform AWS Provider test helpers: Exists/Destroy check functions, exports_test.go wiring, create.Error wrapping, data source tests, list resource tests (querycheck + Terraform version floor), and unit tests. Use when reviewing a PR that changes check helpers or data-source/list/unit tests in internal/service/**/*_test.go." --- # Review: Test Helpers, Data Source Tests, List Resource Tests, Unit Tests Assume the `@maintainer` persona. Scope: Exists/Destroy helpers, data source tests, list resource tests, unit tests. See `review-tests` for per-resource basics. Loaded from `review-pr`. ## Exists / Destroy helpers `testAccCheckExists` should: - Look up the resource state with `s.RootModule().Resources[name]`. - Verify `rs.Primary.ID != ""`. - Use `acctest.ProviderMeta(ctx, t).Client(ctx)` for the client — never construct a fresh client. - Call the **exported** finder `tf.FindByID(ctx, conn, ...)`. `testAccCheckDestroy` should: - Skip rows where `rs.Type != "aws__"`. - Treat `retry.NotFound(err)` as success (`return nil`). - Use `errs.IsA[*awstypes.]` rather than type assertions if it inspects errors directly. Wrap real failures with `create.Error(names., create.ErrActionCheckingExistence|ErrActionCheckingDestroyed, tf.ResName, id, err)` rather than `fmt.Errorf` / `errors.New`. ## exports_test.go Test files reach into the package via a sibling `exports_test.go`: ```go package var ( Resource = newResource // Framework // or: Resource = resource // SDKv2 FindByID = findByID ) ``` Flag PRs that export production identifiers (capitalize the real `findByID`) instead of using `exports_test.go`, or reach into the package via build tags or `internal/` traversal hacks. The package is imported in tests as `tf "github.com/hashicorp/terraform-provider-aws/internal/service/"`. ## Data source tests Data source tests follow the resource conventions with these differences: - Reference `dataSourceName := "data.aws__.test"`. - Prefer `resource.TestCheckResourceAttrPair(dataSourceName, attr, resourceName, attr)` over hard-coded values when the data source mirrors a resource. - No `_disappears` test. - A `CheckDestroy` is still required when the test creates a backing resource. ## List resource tests List resources require three scenarios for parity: - `_List_basic` — basic listing. - `_List_includeResource` — with `include_resource = true` and full attribute checks. - `_List_regionOverride` — region override; requires `acctest.PreCheckMultipleRegion(t, 2)`. List resource tests use static testdata, not inline configs: ```go ConfigDirectory: config.StaticDirectory("testdata//list_/"), ConfigVariables: config.Variables{ acctest.CtRName: config.StringVariable(rName), ... }, ``` A separate `Step` with `Query: true` exercises the list operation. Identity assertions use `tfstatecheck.Identity()` / `identity.GetIdentity(resourceName)` and the `tfquerycheck.*` helpers under `internal/acctest/querycheck`. List resource tests also require a Terraform version floor (currently 1.14): ```go TerraformVersionChecks: []tfversion.TerraformVersionCheck{ tfversion.SkipBelow(tfversion.Version1_14_0), }, ``` ## Unit tests Unit tests are for logic that doesn't touch AWS — parsers, custom flatteners/expanders, ID composition, validators. They: - Run in parallel (`t.Parallel()` at top and inside subtests). - Are table-driven with `t.Run(tc.TestName, ...)`. - Must not call `acctest.Context`, `acctest.PreCheck`, or instantiate an AWS client. Flag unit tests added for trivial pass-through flatteners/expanders — they're noise. Flag acceptance-style tests mis-named without the `TestAcc` prefix.