Tutorials / Disciplined AI-Assisted Development · Lesson 12 of 14

On this page

    Test and AI Review: A Second Look at the Branch

    Step 5 of 7.

    Step 5 of 7 1Explore 2Document 3Specify 4Build 5Test andAI review 6Humanreview 7Refine

    The feature is built, and you tried each "Done when" line by hand. Trying it by hand works once. Tomorrow someone changes something nearby, and nobody tries it again. This step makes the checks repeatable, and gives the work a second look from a different angle.

    Our goal: turn the "Done when" lines into tests, and review the branch with one question at a time.

    Here is the route:

    1. How a team checks work: tests, then a colleague's look.
    2. Tests from the spec.
    3. Tests the agent wrote itself: the trap.
    4. AI review, one hat per pass.
    5. What the AI review cannot be.

    We leave out how tests are written (the agent writes them, and you do not need to read C#), and the person's own read, which is next lesson.


    How a team checks work

    When a developer finishes a feature, two checks follow before anyone merges it. First, tests: small programs that run the feature and fail loudly if it stops working. They run again on every later change, so they keep watching long after the developer has moved on. Second, a colleague looks at the work with fresh eyes and asks what the author missed.

    Tests, then a second look Branch Tests Secondlook Ready findings go back, the author fixes

    An AI can do both jobs, as long as you keep them apart.


    Tests from the spec

    Lesson 09 said the "Done when" lines matter most because the checks come from them. Here is where. Each line becomes a test.

    Done when (the spec) A test
    Adding ISBN 9781234567897 titled "A Sample Book" shows it in the list Adding_a_valid_book_shows_it_in_the_list
    An empty title shows an error and saves nothing An_empty_title_is_rejected_and_nothing_is_saved
    Adding the same ISBN again shows an error Adding_the_same_isbn_twice_is_rejected

    The test names read like the spec on purpose. When one fails, the name tells you which promise broke. Ask for them with the tester hat (lesson 03):

    You are the tester. Read docs/specs/03-add-book.md. Write one test for
    each "Done when" line, named after the line. Then run the tests and
    tell me which pass. Do not change the app code.
    

    An example of what comes back (yours will differ):

    Tests written: 3. Run: 3 passed, 0 failed.
    

    Three green ticks are good news. They are also where the next section starts, because green only means the tests passed. It does not mean the tests are right.


    The trap: tests the agent wrote to fit its own code

    Suppose the same session that built the feature also wrote the tests, looking at its own code. It may write tests that confirm what the code does, whether or not that matches what the spec says. If the code has a mistake, the tests copy the mistake, and everything passes.

    Tests from the code, or from the spec From the code Code has a mistake Tests copy the code All pass. Nobody knows. From the spec Code has a mistake Tests follow the spec One fails. Found.

    Two habits avoid this. Write the tests from the spec, as above, and not from the code. And write them in a fresh session: a new hire that has only read the spec has no loyalty to the code that was just written. Reading the spec is the point of the "Done when" lines. A test also only proves what it tests, so a test that is missing is a promise nobody checks.


    AI review: one hat per pass

    Tests check the promises you wrote down. A review asks what nobody wrote down. Lesson 03 said one hat per pass, because an AI told to "review everything" skims everything. So run the branch past the AI a few times, each with one job.

    Three passes over one branch The branch TesterIs every promise covered? What is missing? ReviewerIs it correct and clear? Does it follow our conventions? ScepticWhat could go wrong? What did nobody think of?

    Ask the prompt writer hat to draft each request (lesson 03), edit it, and keep the ones that work. For example:

    You are a reviewer. Read the branch against docs/specs/03-add-book.md
    and the Conventions in README.md. List problems in order of seriousness,
    with the file and the reason. Do not change anything.
    

    An example of the reply (yours will differ):

    1. The price field accepts a negative number. The spec does not say.
    2. The list is sorted A to Z, but not ignoring capitals, so "apple"
       comes after "Zebra". The spec says A to Z.
    3. No problems with naming or structure against Conventions.
    

    Two kinds of finding:

    • A bug (number 2): the code does not do what the spec says. The agent fixes the branch.
    • A gap (number 1): the spec is silent, so a person decides. Say "no negative prices", change the spec first with a new "Done when" line, then the code (rule 1).

    A review request that found real problems is worth keeping, so save it in the project's files (rule 2). The sceptic pass is for features that touch other people's data. Skip it for the smallest ones.


    An AI review is a second look, not the last

    It reads the same files the author did, so it can share the author's blind spots. It only knows what you wrote down, and it does not answer for the result. A person does. Treat its findings as a list to read, not a verdict. Fix them on the same branch, run the tests again, and the branch is ready for the step the AI cannot do for you.


    Where we ended

    The branch now carries tests as well as code. The list of review requests joins the project documents.

    Before (the end of lesson 11):

    bookshop-backoffice/
    ├── README.md
    ├── CLAUDE.md
    ├── .claude/settings.json
    ├── docs/ ...
    └── src/                       the web app and the add-book pages
    

    After:

    bookshop-backoffice/
    ├── README.md
    ├── CLAUDE.md
    ├── .claude/settings.json
    ├── docs/
    │   ├── tasks.md
    │   ├── specs/                 <- changes  03 gains a "no negative price" line
    │   └── review-requests.md     <- NEW  the review requests worth keeping
    ├── src/                       the web app and the add-book pages
    └── tests/                     <- NEW  one test per "Done when" line
    

    Recap

    • A team checks work two ways: tests that keep running, and a second look from someone else. An AI can do both, kept apart.
    • Each "Done when" line becomes a test, named after the line, written by the tester hat from the spec.
    • Write tests from the spec in a fresh session. Tests written from the code copy its mistakes.
    • Review with one hat per pass: tester, reviewer, sceptic. Ask the prompt writer hat to draft each request, and keep the good ones.
    • A bug is fixed in the code. A gap in the spec is decided by a person, and changed in the spec first (rule 1).
    • AI review is a second look and not the last. Tests prove only what they test.

    Questions to think about

    The answers are left out on purpose. Try them in your own words first.

    1. Why do tests keep their value after the feature is built?
    2. Why write the tests from the spec and not from the code?
    3. Why review with one hat per pass?
    4. What is the difference between a bug and a gap in the spec, and who handles each?
    5. Why is a clean AI review not the end of the checking?

    Next lesson: step 6, Human review. A person reads the branch before anything is pushed.

    ← Build: One Feature, on Its Own BranchHuman Review: A Person Reads It Before It Goes In →