Skip to content

Day 4 of 52 · about 20 min · Basics

Fix a bug and prove it with a test

Claude stops guessing when it has something to check against. A failing test is the clearest target you can give it, and the same test proves the fix.

You’ll finish with

  • A failing test that pins the bug
  • A fix from Claude, proved by the tests and by you

You’ll need

  • Claude Code set up as on Day 1
  • The practice project with Node.js 22+, or a bug of your own you can reproduce

Before you start

Tell us about your setup and the steps change to fit it. Your answers stay in this browser, and you can change them at any time.

Which system are you on?

Commands differ between systems. Pick the one you’ll run Claude Code on.

The steps

One step at a time. When a step’s check matches, tick it and the next one opens.

0 of 4 steps done0%
  1. Step 1 of 4: See the bug

    Price 50 minutes of development and compare the result with the maths.
    Terminal

    Run: node src/cli.js dev:0.833

    Output: Development, 0.833 h at EUR 95.00 EUR 79.13

    What happens: 0.833 × 95 is 79.135, which should round up to EUR 79.14.

    Fifty minutes is 0.833 h. Everywhere else in Acme Quotes, a half cent rounds up.

    In your own project, pick a bug you can show with one command.

    Check it worked

    The Development line ends in EUR 79.13, one cent short.

  2. Step 2 of 4: Pin it with a failing test

    Save a test that states the right answer, then watch it fail.
    test/rounding.test.jsJavaScript
    import assert from 'node:assert/strict';
    import { test } from 'node:test';
    
    import { priceLine } from '../src/quote.js';
    
    // A fixed rate card, so this test keeps passing when data/rates.json changes.
    const RATES = {
      currency: 'EUR',
      vatPercent: 20,
      roles: { dev: { label: 'Development', hourly: 95 } },
    };
    
    test('rounds half a cent up when pricing part hours', () => {
      // 50 minutes is 0.833 h. 0.833 h at EUR 95.00 is EUR 79.135,
      // which rounds up to EUR 79.14, like every other half cent.
      assert.equal(priceLine({ role: 'dev', hours: 0.833 }, RATES).amountCents, 7914);
    });
    
    Terminal

    Run: npm test

    What happens: The summary shows fail 1. The failure reads actual: 7913 and expected: 7914.

    The failure is the target: Claude can run it, read it and try again.

    Check it worked

    Exactly one test fails: rounds half a cent up when pricing part hours. Every other test still passes.

  3. Step 3 of 4: Hand Claude the failing test

    Ask Claude to find the cause and fix the code, not the test.
    Paste into Claude Code
    npm test fails in test/rounding.test.js. Find the cause in src/ and fix it. Don't change the test. When you're done, run npm test and show me the pass and fail counts.

    In order:

    1. Shell

      Claude runs the test

    2. Claude

      Reads src/quote.js

    3. Tool

      Edits the code

    4. Shell

      Runs npm test again

      Repeats until it passes

    A check Claude can run closes the loop without you.

    Check it worked

    Claude changes src/quote.js, leaves test/rounding.test.js alone, and shows fail 0.

    If it didn’t work

    Claude changed the test instead

    Undo that edit, then say: “The test is right. Fix the rounding in src/quote.js.”

  4. Step 4 of 4: Prove the fix yourself

    Run the tests and both quotes yourself, and trust the output over the summary.
    Terminal

    Run: npm test

    Run: node src/cli.js dev:0.833

    Output: Development, 0.833 h at EUR 95.00 EUR 79.14

    Run: node src/cli.js design:10 dev:24 --discount 10

    What happens: The total is still EUR 3,326.40.

    Same commands in PowerShell. The finished kit holds one possible fix.

    Check it worked

    The tests show fail 0, the Development line reads EUR 79.14, and the sample total hasn’t moved.

Finish · 4 of 4 steps to go

The bug is fixed, and a test keeps it fixed

Whenever you can, turn a bug report into a failing test first. Claude gets a target it can check, and you get proof instead of a promise.

What you’ll have checked

  • test/rounding.test.js passes
  • The sample quote total is still EUR 3,326.40

Lesson updates by email

Get lesson updates by email

Leave your email and we’ll tell you when we add or update a lesson.

We’ll email you when we add or update a lesson. We use your email only for this. Privacy policy

Claude Code for your team

Want Claude Code set up across your team?

HorizonLux sets up and repairs Claude Code for teams: CLAUDE.md rules, hooks that enforce them and reviewed MCP servers. Book a free call to talk it through.

Questions

Questions about Day 4

Why give Claude a test instead of describing the bug?

Without a check it can run, Claude stops when the work looks done. With a failing test, it runs the check, reads the result and keeps going until the test passes.

Sources

Checked against the official Claude Code docs on .

Independent resource, not affiliated with Anthropic. HorizonLux wrote this lesson; Claude Code is made by Anthropic.