// Analyze and improve Terraform provider test coverage using terraform-plugin-testing v1.13.3+ patterns. Use when (1) analyzing test coverage gaps, (2) adding missing tests (drift detection, import, idempotency), (3) converting legacy patterns to modern state checks, (4) tracking optional field coverage, (5) verifying test quality, or (6) validating example accuracy. Supports automated coverage analysis, guided pattern improvements, and example testing.
| name | terraform-provider-tests |
| description | Analyze and improve Terraform provider test coverage using terraform-plugin-testing v1.13.3+ patterns. Use when (1) analyzing test coverage gaps, (2) adding missing tests (drift detection, import, idempotency), (3) converting legacy patterns to modern state checks, (4) tracking optional field coverage, (5) verifying test quality, or (6) validating example accuracy. Supports automated coverage analysis, guided pattern improvements, and example testing. |
Analyze test coverage and improve Terraform provider acceptance tests using modern patterns from terraform-plugin-testing v1.13.3+.
When invoked, I will:
python3 scripts/analyze_gap.py ./internal/provider/ --output ./ai_reports/tf_provider_tests_gap_$(date +%Y%m%d_%H%M%S).md./ai_reports/Priority levels:
Communication style: Be succinct. Provide summary + single recommended next step.
Analyze test modernization gaps:
python3 scripts/analyze_gap.py ./internal/provider/ --output ./ai_reports/tf_provider_tests_gap_$(date +%Y%m%d_%H%M%S).md
Analyze a specific test file: "Analyze resource_example_test.go for coverage gaps"
Verify compilation after changes:
./.claude/skills/terraform-provider-tests/verify_compilation.sh ./internal/provider/
Validate all examples:
export BCM_ENDPOINT="https://..." BCM_USERNAME="..." BCM_PASSWORD="..."
./.claude/skills/terraform-provider-tests/test-examples.sh
All gap analysis reports should use the tf_provider_tests_* naming pattern in the ./ai_reports/ directory:
| Report Type | Filename Pattern | Example |
|---|---|---|
| Initial gap analysis | ./ai_reports/tf_provider_tests_gap_YYYYMMDD_HHMMSS.md | ./ai_reports/tf_provider_tests_gap_20251123_225128.md |
| Final analysis | ./ai_reports/tf_provider_tests_final_YYYYMMDD_HHMMSS.md | ./ai_reports/tf_provider_tests_final_20251123_230145.md |
| One-time analysis | ./ai_reports/tf_provider_tests_gap.md | ./ai_reports/tf_provider_tests_gap.md |
Timestamp format: $(date +%Y%m%d_%H%M%S) generates YYYYMMDD_HHMMSS
Starting a modernization project? → Begin with Gap Analysis
Have gap analysis report? → Proceed to Pattern Application
Made code changes? → Run Verification
All changes complete? → Complete Testing
Need to validate examples? → Run Example Testing
Tool: scripts/analyze_gap.py
Automatically scan test files and generate comprehensive gap analysis report.
python3 scripts/analyze_gap.py <test_directory> [--output report.md]
Example (recommended naming pattern):
python3 scripts/analyze_gap.py ./internal/provider/ --output ./ai_reports/tf_provider_tests_gap_$(date +%Y%m%d_%H%M%S).md
Simple filename (for one-time analysis):
python3 scripts/analyze_gap.py ./internal/provider/ --output ./ai_reports/tf_provider_tests_gap.md
Check: resource.TestCheckResourceAttr() patternsMarkdown report with:
Review the report to understand:
Focus on high-impact changes first:
For each file, apply patterns in this order:
Missing drift detection? → See references/pattern_templates.md → "Drift Detection Test"
Missing import test? → See references/pattern_templates.md → "Import Test Step"
Missing idempotency checks? → See references/pattern_templates.md → "Idempotency Verification"
Replace Check: resource.ComposeAggregateTestCheckFunc() with ConfigStateChecks.
Before:
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("example_resource.test", "name", "expected"),
),
After:
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(
"example_resource.test",
tfjsonpath.New("name"),
knownvalue.StringExact("expected"),
),
},
Type mapping → See references/pattern_templates.md
import (
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/plancheck"
"github.com/hashicorp/terraform-plugin-testing/statecheck"
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
"github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
"github.com/hashicorp/terraform-plugin-testing/compare"
)
For drift tests, also add: "context", "encoding/json", "time"
Tool: scripts/verify_compilation.sh
Quick compilation check without running tests.
./.claude/skills/terraform-provider-tests/scripts/verify_compilation.sh <test_directory>
Example:
./.claude/skills/terraform-provider-tests/scripts/verify_compilation.sh ./internal/provider/
If compilation fails:
go test -c ./internal/provider/ -o /tmp/provider_tests
Tool: scripts/run_tests_parallel.sh
Run acceptance tests concurrently per file for faster execution.
Usage:
# Run all acceptance tests with 15 concurrent files
./.claude/skills/terraform-provider-tests/scripts/run_tests_parallel.sh
# Run only resource tests with higher concurrency
./.claude/skills/terraform-provider-tests/scripts/run_tests_parallel.sh --resources-only -c 8
# Run only data source tests
./.claude/skills/terraform-provider-tests/scripts/run_tests_parallel.sh --data-sources-only
# Run tests matching specific pattern
./.claude/skills/terraform-provider-tests/scripts/run_tests_parallel.sh -p "TestAccCMPartSoftwareImage"
# Run tests from specific file
./.claude/skills/terraform-provider-tests/scripts/run_tests_parallel.sh -f resource_cmpart_softwareimage_test.go
# Verbose output with detailed test logs
./.claude/skills/terraform-provider-tests/scripts/run_tests_parallel.sh --verbose
Options:
-d, --dir DIR - Test directory (default: ./internal/provider)-p, --pattern PATTERN - Test pattern to match (default: TestAcc)-c, --concurrency N - Max concurrent test files (default: 4)-t, --timeout DURATION - Timeout per test file (default: 30m)-f, --file FILE - Run only tests from specific file--resources-only - Run only resource tests--data-sources-only - Run only data source tests--verbose - Show detailed test output--no-color - Disable colored outputBenefits:
TF_ACC=1 go test -v -timeout 30m ./internal/provider/ -run "^TestAccResource_Specific$"
TF_ACC=1 go test -v -timeout 120m ./internal/provider/
Tool: scripts/test-examples.sh
Validate all Terraform examples in the examples/ directory by building the provider, executing examples, and cleaning up test resources.
# Run all examples (requires BCM credentials)
export BCM_ENDPOINT="https://172.21.15.254:8081"
export BCM_USERNAME="root"
export BCM_PASSWORD="your-password"
./scripts/test-examples.sh
# Quick validation with existing provider build
SKIP_BUILD=true ./scripts/test-examples.sh
# Test only data sources (parallel, ~10s)
./scripts/test-examples.sh --data-sources-only
# Test only resources (sequential, ~19s)
./scripts/test-examples.sh --resources-only
# Debug a failing test
./scripts/test-examples.sh --verbose --no-cleanup
# Cleanup orphaned resources from failed tests
./scripts/test-examples.sh --cleanup-only
Data Sources (parallel):
PARALLEL_LIMIT)Resources (sequential):
SKIP_BUILD=true).tf files in examples/data-sources/*/ and examples/resources/*/Required:
BCM_ENDPOINT - BCM API endpointBCM_USERNAME - BCM authentication usernameBCM_PASSWORD - BCM authentication passwordOptional:
PROVIDER_VERSION - Provider version (default: 0.1.0)SKIP_BUILD - Skip build phase (default: false)PARALLEL_LIMIT - Max parallel data source tests (default: 4)CLEANUP_RETRIES - Max cleanup retry attempts (default: 4)VERBOSE - Enable verbose logging (default: false)0 - All tests passed, cleanup successful1 - One or more tests failed2 - Configuration error (missing env vars)3 - Provider build failed130 - Interrupted by user (Ctrl+C)Example Naming:
citest- prefix for resources that need cleanuptest-citest/ directories undergo full apply/destroyProvider Configuration:
insecure_skip_verify = true for self-signed certsResource Cleanup:
citest- prefix--cleanup-only to manually cleanup orphaned resourcesRun example testing when:
examples/ directoryExample testing complements acceptance tests:
Acceptance Tests (make testacc):
Example Tests (./scripts/test-examples.sh):
A fully modernized test file has:
Check blocksstatecheck.ExpectKnownValue()ImportStateVerifyCompareValueThe analyzer detects inconsistent usage of the .id property across test steps.
Resource IDs should remain stable across:
Inconsistent ID handling can indicate:
| Issue | Description | Severity |
|---|---|---|
| Missing CompareValue | Multiple test steps without ID consistency tracking | High |
| Partial ID tracking | Some steps track ID, others don't | Medium |
| Legacy ID checks | Uses TestCheckResourceAttr for "id" instead of modern patterns | Medium |
| No ID verification | Resource tests that never verify ID | High |
| Modern without tracking | Uses ExpectKnownValue for ID but no CompareValue | Low |
func TestAccResource_Complete(t *testing.T) {
// Initialize ID tracker BEFORE Steps
compareID := statecheck.CompareValue(compare.ValuesSame())
resource.Test(t, resource.TestCase{
Steps: []resource.TestStep{
// Step 1: Create - track ID
{
Config: testAccResourceConfig(name),
ConfigStateChecks: []statecheck.StateCheck{
compareID.AddStateValue("example_resource.test", tfjsonpath.New("id")),
},
},
// Step 2: Import - track ID
{
ResourceName: "example_resource.test",
ImportState: true,
ImportStateVerify: true,
ConfigStateChecks: []statecheck.StateCheck{
compareID.AddStateValue("example_resource.test", tfjsonpath.New("id")),
},
},
// Step 3: Update - track ID
{
Config: testAccResourceConfig(name, "updated"),
ConfigStateChecks: []statecheck.StateCheck{
compareID.AddStateValue("example_resource.test", tfjsonpath.New("id")),
},
},
},
})
}
Anti-pattern 1: Legacy ID checks
// ❌ Bad - uses legacy pattern
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet("example_resource.test", "id"),
),
Anti-pattern 2: Inconsistent tracking
// ❌ Bad - only tracks ID in Create step, not Import/Update
Steps: []resource.TestStep{
{
Config: testAccConfig(name),
ConfigStateChecks: []statecheck.StateCheck{
compareID.AddStateValue("example_resource.test", tfjsonpath.New("id")), // ✅
},
},
{
ResourceName: "example_resource.test",
ImportState: true,
// ❌ Missing: compareID.AddStateValue
},
{
Config: testAccConfig(name, "updated"),
// ❌ Missing: compareID.AddStateValue
},
}
Anti-pattern 3: No tracking at all
// ❌ Bad - multiple steps with no ID consistency tracking
compareID := statecheck.CompareValue(compare.ValuesSame()) // Declared but never used!
Missing imports → Add all required imports from Phase 3, Step 3
Wrong knownvalue matcher → Match types correctly: String→StringExact, Bool→Bool, Int64→Int64Exact
Duplicate validation
→ Remove Check block, keep only ConfigStateChecks
This skill includes comprehensive reference documentation:
Complete step-by-step modernization workflow with detailed guidance for each phase, common pitfalls, and completion criteria.
When to read: For detailed phase-by-phase instructions.
Ready-to-use code templates for all modern patterns:
When to read: When applying specific patterns to code.
Consolidated HashiCorp official documentation:
When to read: For authoritative information on terraform-plugin-testing features.
Total project (7 resource + 7 data source files): 4-8 hours across multiple sessions.
This skill uses a hybrid approach:
Automation for:
Guided assistance for:
This balance maintains control while automating tedious tasks.