Tech Update / Adventures with Claude Code #18
Tests first – the best prompt is a failing test
"Build me a function that calculates discounts." Claude delivers. The code looks good, compiles, and is still wrong, because I forgot to mention that discounts can't be combined.
The problem isn't Claude. The problem is my description. And the most precise description I know is a test.
🔴 The workflow that works for us
- Claude writes only the tests first. Explicitly: "No implementation yet."
- I read the tests. This is where I find the gaps in my own requirement.
- Claude runs the tests and confirms: they fail.
- I commit the tests.
- Only now: "Implement until all tests pass. Don't change the tests."
🔁 Why it works so well
Claude gets a clear, verifiable goal. Instead of guessing once, a loop runs: write code, run tests, read errors, fix. Claude can do that without me, and it's pretty persistent about it.
And in the end I don't have to understand every line of the implementation to know whether it does the right thing. The tests tell me.
💡 My tip
"Don't change the tests" isn't just a line in our prompt. During this phase, a PreToolUse hook (part 11) blocks writes to *.spec.ts. Anyone who wants to change a test has to justify it, the AI included.
A word of caution:
Claude gets creative when it comes to making tests pass. A hard-coded return value, a skip, an expect that's a little too loose. So look at the diff carefully. Also: tests written by Claude sometimes test the implementation rather than the requirement. Good test cases are still your job.
My rule of thumb:
- Requirement clear and testable? Tests first, then code.
- Requirement still fuzzy? Plan mode first (part 10), then tests.
- UI, prototype, throwaway code? Trying it and looking at it is enough.
Deutsch
English