$npx -y skills add keep-starknet-strange/starknet-agentic --skill cairo-testingCairo smart-contract testing with snforge. Trigger on "write tests", "add unit tests", "fuzz test", "integration test", "test this contract", "regression test". Guides test strategy, cheatcode usage, and coverage.
| 1 | # Cairo Testing |
| 2 | |
| 3 | You are a Cairo testing assistant. Your job is to understand what the user needs tested, load the right references, write correct tests, verify they pass, and ensure adequate coverage. |
| 4 | |
| 5 | ## When to Use |
| 6 | |
| 7 | - Writing unit, integration, fuzz, or fork tests for Cairo contracts. |
| 8 | - Designing regression tests for known findings. |
| 9 | - Validating event emission, failure semantics, or access control. |
| 10 | - Improving test coverage on an existing contract. |
| 11 | |
| 12 | ## When NOT to Use |
| 13 | |
| 14 | - Contract architecture decisions (`cairo-contract-authoring`). |
| 15 | - Performance tuning (`cairo-optimization`). |
| 16 | - Deployment operations (`cairo-deploy`). |
| 17 | - Security audit of existing code (`cairo-auditor`). |
| 18 | |
| 19 | ## Quick Start |
| 20 | |
| 21 | 1. Classify what needs testing: new contract, specific function, regression, or coverage gap. |
| 22 | 2. Load references based on test type — see the table in [Orchestration](#orchestration). |
| 23 | 3. Output a test plan (functions, positive/negative paths, invariants) and wait for confirmation. |
| 24 | 4. Implement tests following snforge patterns, then run `snforge test`. |
| 25 | 5. Verify coverage: every external tested? auth paths? negative cases? events? |
| 26 | 6. Emit a handoff block using `../references/skill-handoff.md` (`testing → optimization` only for explicit performance work, then run `optimization → auditor` before merge; otherwise `testing → auditor`), then run the next skill. |
| 27 | |
| 28 | ## Rationalizations to Reject |
| 29 | |
| 30 | - "We only need happy-path tests." |
| 31 | - "Access control tests are unnecessary — the contract handles it." |
| 32 | - "Fuzz tests are overkill for this contract." |
| 33 | - "We'll add regression tests after the next audit." |
| 34 | |
| 35 | ## Mode Selection |
| 36 | |
| 37 | - **unit**: Test individual functions using `contract_state_for_testing()`. No deployment needed. |
| 38 | - **integration**: Test deployed contracts via dispatchers. Multi-contract interactions. |
| 39 | - **fuzz**: Property-based tests with `#[fuzzer]` for arithmetic, bounds, invariants. |
| 40 | - **fork**: Test against live Starknet state with `#[fork]`. |
| 41 | - **regression**: Turn a known finding into a failing-before/fixed-after test pair. |
| 42 | |
| 43 | ## Orchestration |
| 44 | |
| 45 | **Turn 1 — Understand.** Classify the request: |
| 46 | |
| 47 | (a) Determine mode: `unit`, `integration`, `fuzz`, `fork`, or `regression`. |
| 48 | |
| 49 | (b) Read the contract under test. Use Glob to find `.cairo` files, then Read to inspect them. Identify: |
| 50 | - All storage-mutating `#[abi(embed_v0)]` impl functions and `#[external(v0)]` functions (these must be tested). |
| 51 | - Storage fields and their types. |
| 52 | - Events that should be emitted. |
| 53 | - Access control patterns (owner checks, role checks). |
| 54 | |
| 55 | (c) Check for existing tests. Use Glob to find `tests/` directories and test files. |
| 56 | |
| 57 | (d) Load references based on what's needed: |
| 58 | |
| 59 | | Request involves | Load reference | |
| 60 | |-----------------|---------------| |
| 61 | | Basic test structure, deployment, assertions | `{skill_dir}/references/legacy-full.md` (Basic Test Structure, Contract Deployment) | |
| 62 | | Cheatcodes (caller, timestamp, block number) | `{skill_dir}/references/legacy-full.md` (Cheatcodes section) | |
| 63 | | Event testing, spy_events | `{skill_dir}/references/legacy-full.md` (Event Testing section) | |
| 64 | | Fuzz / property tests | `{skill_dir}/references/legacy-full.md` (Fuzzing section) | |
| 65 | | Fork testing against mainnet | `{skill_dir}/references/legacy-full.md` (Fork Testing section) | |
| 66 | | Security regression recipes | `../cairo-auditor/references/vulnerability-db/` | |
| 67 | |
| 68 | Where `{skill_dir}` is the directory containing this SKILL.md. Resolve it from the currently loaded SKILL path (preferred), then use `references/...` relative paths from that directory. |
| 69 | |
| 70 | **Turn 2 — Plan.** Before writing any test code, output a brief plan: |
| 71 | |
| 72 | 1. **Functions to test** — list each external function and whether it gets a positive test, negative test, or both. |
| 73 | 2. **Access control tests** — for each guarded function, test: authorized caller succeeds, unauthorized caller reverts. |
| 74 | 3. **Event tests** — list events that should be verified with `spy_events`. |
| 75 | 4. **Edge cases** — zero values, max values, duplicate calls, reentrancy attempts. |
| 76 | 5. **Fuzz targets** — identify functions with numeric inputs that should get `#[fuzzer]` tests. |
| 77 | 6. **Regression tests** — if fixing a known finding, describe the failing-before scenario. |
| 78 | |
| 79 | Keep the plan under 30 lines. Wait for user confirmation before implementing. |
| 80 | |
| 81 | **Turn 3 — Implement.** Write tests following these rules: |
| 82 | |
| 83 | *Structure rules:* |
| 84 | - Use `#[cfg(test)] mod tests { ... }` for unit tests in the same file, or separate `tests/` directory for integration tests. |
| 85 | - |