Running Tests and State Reconciliation
Learn how to execute testform plan and testform apply to compute diffs between your local Git feature files and remote platforms safely and reproducibly.
The Plan and Apply Lifecycle
Section titled “The Plan and Apply Lifecycle”Testform strictly decouples change analysis from physical mutation:
testform plan(Read-Only): Compares local files against the state ledger and remote APIs. Produces an exact preview of all resources to create, update, or destroy without touching any remote systems.testform apply(Safe Mutation): Acquires a distributed backend lock, dispatches API mutations to configured providers, and commits the resulting ledger.
Step 1: Run testform plan
Section titled “Step 1: Run testform plan”Run the planner in your terminal:
testform planReading Plan Output
Section titled “Reading Plan Output”Testform v1.0.0Configured backend: local (testform.state)Acquiring state lock... Lock acquired successfully.
Building dependency graph and calculating reconciliation diff...
Testform will perform the following actions:
# tests/features/checkout.case.feature.@tc-checkout-001 will be created + resource "testcase" "tests/features/checkout.case.feature.@tc-checkout-001" { + title = "Successful transaction with sufficient funds" + feature = "Online Checkout Process" + component = "billing" + priority = "Critical" + suite = "smoke" + steps_count = 8 + status = "draft" }
# tests/features/auth.case.feature.@tc-auth-001 will be updated in-place ~ resource "testcase" "tests/features/auth.case.feature.@tc-auth-001" { title = "Successful login with valid email and password" ~ priority = "Medium" => "High" ~ steps_count = 5 => 6 }
Plan: 1 to add, 1 to change, 0 to destroy.Releasing state lock... Lock released.Diff Symbols
Section titled “Diff Symbols”| Symbol | Action | Description |
|---|---|---|
+ |
create | Declared in Git but does not yet exist in the ledger or remote QA platform. |
~ |
update | Exists in the ledger; metadata or steps changed and will be updated in-place. |
- |
destroy | File removed from Git; Testform will archive or delete the remote record. |
- / + |
replace | Structural changes require destroying and re-creating the resource from scratch. |
Step 2: Save Plan to a Binary File
Section titled “Step 2: Save Plan to a Binary File”In CI/CD environments, saving the speculative plan prevents race conditions between plan approval and apply:
# Save speculative plantestform plan -out=testform.plan.bin
# Apply exact planned artifacttestform apply testform.plan.binStep 3: Run testform apply
Section titled “Step 3: Run testform apply”Apply changes interactively by approving the prompt:
testform applyInteractive confirmation prompt:
Do you want to perform these actions? Only 'yes' will be accepted to approve.
Enter a value: yesFor automated headless CI pipelines, pass -auto-approve:
testform apply -auto-approveTargeted Execution (-target)
Section titled “Targeted Execution (-target)”Narrow execution to a single resource or feature file using -target:
# Plan only a specific test casetestform plan -target="tests/features/auth.case.feature.@tc-auth-001"
# Apply mutations only to that resourcetestform apply -target="tests/features/auth.case.feature.@tc-auth-001" -auto-approveDetailed Exit Codes for CI/CD
Section titled “Detailed Exit Codes for CI/CD”Enable programmatic pipelines with the -detailed-exitcode flag:
testform plan -detailed-exitcode- Exit code
0: Succeeded, diff is empty (0 changes pending). - Exit code
1: Execution error, syntax error, or backend lock failure. - Exit code
2: Succeeded, non-empty diff present (pending changes to apply).