skills/cairo-testing/SKILL.md
Cairo 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.
npx skillsauth add keep-starknet-strange/starknet-agentic cairo-testingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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.
cairo-contract-authoring).cairo-optimization).cairo-deploy).cairo-auditor).snforge test.../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.contract_state_for_testing(). No deployment needed.#[fuzzer] for arithmetic, bounds, invariants.#[fork].Turn 1 — Understand. Classify the request:
(a) Determine mode: unit, integration, fuzz, fork, or regression.
(b) Read the contract under test. Use Glob to find .cairo files, then Read to inspect them. Identify:
#[abi(embed_v0)] impl functions and #[external(v0)] functions (these must be tested).(c) Check for existing tests. Use Glob to find tests/ directories and test files.
(d) Load references based on what's needed:
| Request involves | Load reference |
|-----------------|---------------|
| Basic test structure, deployment, assertions | {skill_dir}/references/legacy-full.md (Basic Test Structure, Contract Deployment) |
| Cheatcodes (caller, timestamp, block number) | {skill_dir}/references/legacy-full.md (Cheatcodes section) |
| Event testing, spy_events | {skill_dir}/references/legacy-full.md (Event Testing section) |
| Fuzz / property tests | {skill_dir}/references/legacy-full.md (Fuzzing section) |
| Fork testing against mainnet | {skill_dir}/references/legacy-full.md (Fork Testing section) |
| Security regression recipes | ../cairo-auditor/references/vulnerability-db/ |
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.
Turn 2 — Plan. Before writing any test code, output a brief plan:
spy_events.#[fuzzer] tests.Keep the plan under 30 lines. Wait for user confirmation before implementing.
Turn 3 — Implement. Write tests following these rules:
Structure rules:
#[cfg(test)] mod tests { ... } for unit tests in the same file, or separate tests/ directory for integration tests.helpers module for deploy_contract(), address constants (OWNER(), USER(), ZERO()).test_<function>_<scenario> (e.g., test_transfer_non_owner_rejected).Coverage rules (mandatory):
self: @ContractState) MUST verify return correctness; revert tests are optional unless the function defines a failure path.spy_events + assert_emitted.Cheatcode rules:
start_cheat_caller_address / stop_cheat_caller_address to impersonate callers.start_cheat_block_timestamp for timelock tests — never hardcode timestamps.stop_cheat_* after assertions to avoid leaking state.Fuzz rules:
#[fuzzer(runs: 256, seed: 12345)] with a fixed seed for reproducibility.After writing tests, run snforge test to verify they pass. If any fail, fix and re-run.
Turn 4 — Verify. After tests pass:
(a) Coverage checklist — mentally walk through every external function:
(b) Report any untested functions or missing edge cases to the user.
(c) If the user's project uses cairo-auditor, suggest running it to find additional test targets.
(d) Suggest next steps:
cairo-auditor for a security review — it may surface additional test cases."import { Account, Contract, RpcProvider } from "starknet";
const provider = new RpcProvider({ nodeUrl: process.env.STARKNET_RPC! });
const account = new Account(provider, process.env.ACCOUNT_ADDRESS!, process.env.PRIVATE_KEY!);
const contract = new Contract(abi, process.env.CONTRACT_ADDRESS!, provider).connect(account);
// Execute path (state mutation)
const tx = await contract.invoke("transfer", [process.env.USER_ADDRESS!, 100, 0]);
await provider.waitForTransaction(tx.transaction_hash);
// Read path (view assertion)
const balance = await contract.call("balance_of", [process.env.USER_ADDRESS!]);
console.log({ balance });
| Code | Condition | Recovery |
| --- | --- | --- |
| TEST-001 | snforge test fails to compile | Fix imports/dependencies in Scarb.toml, then rerun full suite. |
| TEST-002 | Access-control negative test missing | Add unauthorized caller case with expected panic message. |
| TEST-003 | Event assertion mismatch | Use spy_events + assert_emitted with full event payload ordering. |
| TEST-004 | Flaky fuzz results | Pin #[fuzzer(seed: ...)], constrain inputs, and rerun deterministic seed. |
These are non-negotiable. Every test suite you write must satisfy all of them:
#[should_panic(expected: '...')] — not bare #[should_panic].spy_events + assert_emitted with full event data — not just event count.../references/skill-handoff.md../cairo-auditor/references/vulnerability-db/When testing/security rules in this skill or its references change, update at least one case in:
evals/cases/contract_skill_benchmark.jsonlevals/cases/contract_skill_generation_eval.jsonldata-ai
SNIP-36 virtual block proving on Starknet. Trigger on "virtual block", "SNIP-36", "off-chain proof", "anonymous vote", "heavy computation off-chain", "prove a transaction". Covers Cairo virtual contract, proof server, starknet.js integration, and on-chain verification.
development
Reference for integrating or maintaining applications built with keep-starknet-strange/starkzap, including StarkSDK setup, onboarding, wallet lifecycle, sponsored transactions, ERC20 flows, staking, and transaction builder usage.
testing
Create and manage Starknet wallets for AI agents. Transfer tokens, check balances, manage session keys, deploy accounts, and interact with smart contracts using native Account Abstraction.
development
Simple P2P payments on Starknet. Generate QR codes, payment links, invoices, and transfer ETH/STRK/USDC. Like Lightning, but native.