From dotclaude
Write behavior-focused tests. Use when someone says "write tests", "add tests", "test this", "what should we test", or when implementing tests for a feature. Tests describe WHAT the code does, not HOW it does it. Pairs with behavior-map specs.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dotclaude:test-writingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Read the shared philosophy: `${CLAUDE_PLUGIN_ROOT}/skills/shared/philosophy.md`
Read the shared philosophy: ${CLAUDE_PLUGIN_ROOT}/skills/shared/philosophy.md
You are writing behavior-focused tests. Tests are a spec for what the code does. They should read like documentation and survive refactoring.
$ARGUMENTS
The spec's acceptance criteria and decisions are your test list.
A good test answers: "does this feature work correctly?" A bad test answers: "does this function call that function with these args?"
The test: if you refactor the internals completely but the behavior stays the same, do all tests still pass? If not, the tests are coupled to implementation.
Tests read as behavior specs. The name describes the behavior, not the method:
// ✅ Behavior-focused
"returns empty array when user has no orders"
"rejects payment when card is expired"
"sends notification after successful signup"
"preserves existing data when update partially fails"
// ❌ Implementation-focused
"test getOrders"
"test handlePayment calls validateCard"
"test that sendEmail is called"
Every test follows Arrange → Act → Assert, clearly separated:
// Arrange — set up the scenario
// (describe the "Given" state)
// Act — do the thing
// (the "When" trigger, ONE action per test)
// Assert — verify the behavior
// (the "Then" outcome, focused on WHAT happened, not HOW)
One behavior per test. If a test needs "and" in its name, split it.
Mock at boundaries, not internally:
Mock these (external, slow, unpredictable):
Don't mock these (your own code):
If you're mocking 5 things to test 1 behavior, the code is probably too coupled. Flag it as a design issue, don't paper over it with mocks.
Detect the language and apply:
TypeScript/JavaScript:
describe for the feature/module, it for behaviorstoEqual for values, toThrow for errorsbeforeEach for shared arrange, not shared stateawait assertions, use rejects for async errorsPython:
pytest style (functions, not classes — no inheritance in tests either)pytest.raises for error behaviorsGo:
t.Run for sub-behaviorstestify/assert or stdlib — be consistent with the codebaset.Helper() themFor each behavior being tested, output:
Behaviors to test:
Tests:
[actual test code]
Not tested (and why):
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub realdragonium/dotclaude --plugin dotclaude