Run Clarity contract tests and diagnose common errors. Use when the user wants to run tests, check coverage, or debug test failures in a Stacks/Clarinet project.
Install
npx skillscat add kenny-stacks/stacks-claude-plugin/run-tests Install via the SkillsCat registry.
Run Tests Skill
This skill runs Clarity contract tests using Vitest + Clarinet SDK and helps diagnose common errors.
When to Use
- User wants to run tests
- User asks about test coverage
- User encounters test failures or errors
- After implementing contract changes to verify correctness
Instructions
Step 1: Verify Project Setup
Check for Clarinet project:
ls Clarinet.toml 2>/dev/null && echo "Clarinet project found" || echo "No Clarinet.toml found"If no Clarinet.toml, check common monorepo locations:
clarity/Clarinet.tomlcontracts/Clarinet.tomlpackages/contracts/Clarinet.toml
If found in subdirectory, cd there first.
Check test setup exists:
ls vitest.config.js vitest.config.ts 2>/dev/null
ls package.json 2>/dev/nullIf missing vitest config, tell the user:
"I don't see a Vitest configuration. Would you like me to set up the testing environment? I'll create:
vitest.config.jswith Clarinet SDK setup- Test scripts in
package.json - A sample test file"
Step 2: Run Contract Check First
Always run clarinet check before tests to compile contracts:
clarinet checkCommon errors:
- Syntax errors - Show the error and offer to fix
- Unknown function - Contract may reference undefined function
- Type mismatch - Function argument types don't match
If clarinet check fails, diagnose and fix before proceeding to tests.
Step 3: Run Tests
Detect test command from package.json:
cat package.json | grep -A 5 '"scripts"'Run tests (in order of preference):
- If
testscript exists:npm run test - Otherwise:
npx vitest run
npm run testStep 4: Diagnose Common Errors
Error: "toBeOk is not a function" or "toBeErr is not a function"
This means the Clarinet SDK vitest setup file is missing.
Check vitest.config.js:
cat vitest.config.jsFix: Ensure setupFiles includes the Clarinet SDK setup:
import { vitestSetupFilePath } from "@hirosystems/clarinet-sdk/vitest";
export default defineConfig({
test: {
setupFiles: [vitestSetupFilePath],
// ...
}
});Error: "Contract not found" or "Unknown contract"
The contract hasn't been compiled or isn't registered in Clarinet.toml.
Fix:
- Run
clarinet checkto compile - Verify contract is in
Clarinet.toml:
cat Clarinet.toml | grep -A 2 '\[contracts\.'Error: Type mismatches in test arguments
Common Cl.* helper mistakes:
| Clarity Type | Correct Helper |
|---|---|
uint |
Cl.uint(123) |
int |
Cl.int(-5) |
bool |
Cl.bool(true) |
principal |
Cl.principal("ST1...") or Cl.standardPrincipal("ST1...") |
(string-ascii N) |
Cl.stringAscii("hello") |
(string-utf8 N) |
Cl.stringUtf8("hello") |
(buff N) |
Cl.buffer(Uint8Array.from([...])) or Cl.bufferFromHex("deadbeef") |
(optional T) |
Cl.some(value) or Cl.none() |
(list T) |
Cl.list([...]) |
(tuple {...}) |
Cl.tuple({ key: value }) |
Error: Block height not advancing / timing issues
Tests that depend on block height need to mine blocks:
// Mine empty blocks to advance chain
simnet.mineEmptyBlocks(10);
// Or mine block with specific transactions
simnet.mineBlock([
tx.callPublicFn("contract", "function", [], sender)
]);Error: "simnet is not defined"
The global simnet is provided by the Clarinet SDK setup file. Ensure:
vitestSetupFilePathis in vitest configglobals: trueis set in vitest config
Step 5: Run Coverage (Optional)
If the user asks for coverage or wants to see test coverage:
npm run test:coverageOr if no coverage script exists:
npx vitest run --coverageInterpret coverage results:
- Lines/Statements: Percentage of code lines executed
- Branches: Percentage of conditional branches tested
- Functions: Percentage of functions called
Recommend 90%+ coverage for production contracts.
If coverage is low:
- Identify untested functions from the report
- Suggest specific test cases for uncovered branches
- Check for untested error conditions
Step 6: Summarize Results
If all tests pass:
"All tests passed! Summary:
- X test suites
- Y tests passed
- Coverage: Z% (if run)"
If tests fail:
"Test run completed with failures:
- X tests passed
- Y tests failed
Failed tests:
test name- Brief description of failure
Suggested fix: ...
Would you like me to help fix these failures?"
Common Test Patterns Reference
Testing successful public function:
const response = simnet.callPublicFn("contract", "function", [Cl.uint(100)], sender);
expect(response.result).toBeOk(Cl.bool(true));Testing error conditions:
const response = simnet.callPublicFn("contract", "function", [Cl.uint(0)], sender);
expect(response.result).toBeErr(Cl.uint(400));Testing read-only functions:
const result = simnet.callReadOnlyFn("contract", "get-value", [], sender);
expect(result.result).toBeUint(100);Testing events/prints:
const response = simnet.callPublicFn("contract", "function", [], sender);
expect(response.events).toContainEqual(
expect.objectContaining({ event: "print_event" })
);Notes
- Always run
clarinet checkbefore tests to ensure contracts compile - The
simnetglobal is provided by Clarinet SDK setup - Use
simnet.getAccounts().get("wallet_1")for test accounts - Contracts are auto-deployed to simnet based on
Clarinet.toml