From theo-calvin-testing
Differential testing with Theodore Calvin's framework (tc). Use when writing tc tests, reasoning about test scenarios, creating input/expected JSON pairs, or debugging test failures.
npx claudepluginhub a3lem/my-claude-plugins --plugin theo-calvin-testingThis skill uses the workspace's default tool permissions.
> "In the AI age, specifications and tests are permanent while implementations are disposable."
Guides strict Test-Driven Development (TDD): write failing tests first for features, bugfixes, refactors before any production code. Enforces red-green-refactor cycle.
Guides systematic root cause investigation for bugs, test failures, unexpected behavior, performance issues, and build failures before proposing fixes.
Guides A/B test setup with mandatory gates for hypothesis validation, metrics definition, sample size calculation, and execution readiness checks.
"In the AI age, specifications and tests are permanent while implementations are disposable."
Differential testing compares actual output against expected output. No assertions, no matchers, no framework magic - just a diff.
Tests are nothing more than a script that takes input.json and produces output.json, which is then diffed against expected.json. This simple model:
input.json → run → output.json ←→ diff ←→ expected.json
input.json from stdinexpected.json{"a":1,"b":2} equals {"b":2,"a":1}[1,2,3] does NOT equal [3,2,1]tests/
└── my-test-suite/
├── run # Executable (any language)
└── data/
└── scenario-name/
├── input.json # Test input
└── expected.json # Expected output
run ExecutableThe run file is any executable that:
Example (bash):
#!/usr/bin/env bash
jq '.value * 2'
Example (python):
#!/usr/bin/env python3
import json, sys
data = json.load(sys.stdin)
print(json.dumps({"result": data["value"] * 2}))
For dynamic values, use patterns in expected.json:
| Pattern | Matches |
|---|---|
<uuid> | UUID v4 format |
<timestamp> | ISO 8601 datetime |
<number> | Any number |
<string> | Any string |
<boolean> | true/false |
<any> | Any value |
<null> | null |
Example expected.json:
{
"id": "<uuid>",
"created_at": "<timestamp>",
"count": "<number>"
}
tc # Run all tests in current directory
tc run path/to/suite # Run specific suite
tc new path/to/suite # Create new test suite scaffold
tc list # List available test suites
tc tags # Show available tags
tc explain suite # Describe what a test does
tc --parallel # Run tests in parallel
tc --tags=unit # Filter by tag
tc new tests/user-creation
This creates:
tests/user-creation/
├── run
└── data/
└── basic/
├── input.json
└── expected.json
run tests one thingdata/ subdirectories for variationsdata/empty-input/, data/unicode-handling/run minimal - just wire input to your code and format output