Part 6 of 7 · Test
Test your reading list.
Turn “it seems to work” into evidence you can watch, repeat and rely on when the app changes.
By Ahmed Gadir9 min read
Your app has every feature in the brief, and you checked each stage by hand as it was built and saved. This part adds automated tests: checks a computer can repeat in seconds. You won’t write or read test code. You’ll decide what the tests should prove, watch them run in a real browser and learn what their results mean.
Why test something that works
You checked editing in Part 4. Since then the agent has added saving, search and filters, and changed many of the same files. Does editing still work? Probably. To be sure you would need to repeat every earlier check after every change, and nobody keeps that up for long.
An automated test performs an action and compares what happens with what should happen. Once written, it runs the same way every time. This matters even more when an agent is doing the building: an agent asked to fix the search box can quietly break undo while it works, and it may not notice. A test for undo notices straight away. Tests are how you hold the agent’s work to your plan without reading its code.
This project uses two kinds, and both tools came with the starter:
- Browser journeys use a tool called Playwright. It opens a real browser and uses your app as a person would: clicking buttons, typing into the form, refreshing the page, then checking what is on screen. These follow the flows you wrote in Part 2.
- Unit tests check one small piece of the logic from Part 3 directly, without a browser. For example, one confirms that saved data with an invalid status is refused. They run in a fraction of a second.
1. Say what correct means
A test can only check what someone has defined. If you ask an agent to “add tests” without saying what matters, it may produce many that pass and prove little. So begin with three behaviours that matter most in this app, written as plain statements:
- A book I add and then edit is still there, with my changes, after refreshing.
- An empty title is rejected, and no book is added.
- Removing a book and choosing undo brings it back with its details.
Each statement has an action and an expected result, and each could plausibly break. The first covers the whole path from the form to localStorage and back. The second protects a rule. The third protects the recovery from a mistake, which is the sort of feature that breaks unnoticed because nobody tries it often.
2. Ask for the tests
Write my tests
Read CLAUDE.md, docs/brief.md, docs/flows.md and docs/epics/04-check.md. Follow that epic. Write one Playwright browser test for each of these three behaviours, and name each test as a plain statement so that I can read the list like a checklist: (1) a book I add and then edit is still there with my changes after refreshing; (2) an empty title is rejected and no book is added; (3) removing a book and choosing undo brings it back with its details. Add a few unit tests for loading saved data and for search combined with the status filter. Then add the further browser tests the epic lists, including damaged saved data and a failed save, using the isolated test browser so my own list is never touched. Run everything. If a test fails, work out whether the app or the test is wrong before changing either, and tell me which it was. Report the results in plain language, then stop.
Paste this into your project conversation.
Playwright drives the Google Chrome already on your computer. If Chrome isn’t installed, the first run stops with an error, and the epic tells your agent to offer you a choice: install Chrome, or download a browser for Playwright to use. Either is fine.
The unit tests run with npm test and the browser journeys with npm run test:browser. You can ask the agent to run either at any time.
Read the report when it finishes. It is common for the first run to find a real problem. For example, your Stage A prompt asked for an empty title to be rejected, and a title made only of spaces may have slipped through. When that happens the tests have done their job.
3. Watch them run
So far the agent has run the tests and told you the outcome. Now look for yourself. Ask your agent to “start npm run test:ui in the background”. Playwright’s visual runner opens in its own window and stays open until you close it, so tell the agent when you have finished with it.

There are three areas to know:
- The test list, on the left. Every test appears by name. The triangle at the top runs them all, and the triangle beside a test runs just that one. A green tick means every expectation in the test was met. A red cross means one was not.
- The steps, in the middle. After a test runs, this lists everything it did in order: click, fill in “An Author”, reload, expect the heading to be visible. You can follow it without understanding the code shown beneath.
- The snapshot, on the right. Select any step to see the app exactly as it was at that moment. Step through the undo test and you can watch the book leave the list and come back.
Run your three main tests one at a time and step through each. You are checking that the test really does what its name claims. A test called “undo brings the book back” that never presses Undo would pass and prove nothing, and you can now spot that yourself.
If you’d like to see Chrome itself open and operate the app, ask your agent to run npm run test:watch-browser. The windows open and close quickly, so ask for one named test at a time if you want to follow along.
4. Read a failure
To trust a green tick, it helps to see a red cross. Try a safe experiment:
Show me a failing test
As a demonstration, temporarily change the app so that an empty title is accepted. Do not change any tests. Run the browser tests and show me which test fails and what the failure message says, in plain language. Then restore the app exactly as it was, run the tests again and confirm everything passes. Use Git to confirm no unintended changes remain.
Paste this into your project conversation.
The test named for empty titles should fail, and the others should pass. If you have the visual runner open, run the failing test there: the steps stop at the expectation that wasn’t met, and the snapshot shows the blank book that shouldn’t exist.
This is how to read any failure. The test’s name tells you which behaviour broke, the failed step tells you what was expected, and the snapshot shows what happened instead. It is the same three-part report you wrote by hand in Part 4.
When a test fails during real work, the question is always whether the app is wrong or the test is. Usually the app is. Occasionally you have deliberately changed the behaviour, and the test needs updating to match the new plan. What you should not accept is an agent that weakens or deletes a failing test to make the run pass without explaining why. The project instructions forbid it, and you now know to ask.
5. Let the agent explore the app
Tests repeat the checks someone thought of. A different kind of checking looks for the problems nobody thought of, and your agent can help if you give it a browser to use.
Playwright MCP is an add-on that lets a coding agent open a visible browser window, then click, type and read the page. MCP is the standard way of connecting extra tools to an agent. Ask your agent to set it up:
Give my agent a browser
Help me add the Playwright MCP server to this project, following the official instructions at github.com/microsoft/playwright-mcp for the agent I am using. Explain what it will be allowed to do before you add it, and tell me if I need to restart this conversation afterwards.
Paste this into your project conversation.
Once it is connected, give the agent an open-ended job:
Explore my app
Using the Playwright browser tools, open my app at its local URL and use it for a few minutes as a curious new visitor would. Try things my flows do not mention: very long titles, the same book twice, searching while the form is open, removing books quickly one after another. Do not change any code. Report anything that looks wrong or confusing, with the exact steps so that I can repeat them.
Paste this into your project conversation.
A Chrome window opens and you can watch the agent work through the app. Treat what it reports as leads to check, not as verdicts. Repeat the steps yourself, decide whether each one matters, and for any you fix, ask for a test so the problem can’t quietly return.
The two approaches do different jobs. Exploration finds surprises once, and tests keep checking a known behaviour every time the app changes.
6. Check it yourself
Some judgements remain yours, because they concern how the app feels more than whether a rule holds. Use disposable entries, and keep to the same local URL and browser.
| Try this | Expected result |
|---|---|
| Add a book with just a title. | It saves; the author and note are optional. |
| Add books in all three statuses. | Each book shows the status you chose. |
| Search for an author, then choose a status filter. | Results match both. Clearing them restores the list. |
| Search for something absent. | A clear “nothing found” message appears. |
| Open the URL in a private window. | The list is empty, and Try example books adds samples only when chosen. |
| Narrow the window to phone width. | Everything is readable and reachable with no sideways scrolling. |
| Press Tab through the page, then Escape in the form. | You can see which control has focus, and the form closes without saving. |
If you find a problem, report it with the three-part pattern. Ask for the fix and a test for it, then repeat your check. Afterwards run all the tests again. This is a regression check: confirming that a change hasn’t broken something that used to work. It now takes seconds, which is the practical benefit of having tests.
7. Save the checked version
Record the checked version
Read CLAUDE.md and docs/epics/04-check.md. Summarise the checks we actually performed and any remaining failures or untested areas. Keep four things separate: unit tests, browser journeys, your exploration, and the manual checks I reported. Inspect the project changes and save a local commit named Check reading-list behaviour. Do not mark untested items as passed, and do not publish anything.
Paste this into your project conversation.
FAQ
How many tests should a small app have?
Enough to cover the behaviour you would be upset to lose. For this app that means the three main journeys, the saving failures and the combined search and filter. Our finished example has eight browser journeys and three unit tests. A long list of tests that check trivial things adds maintenance without adding confidence.
Do the tests change my own saved books?
No. The tests start the app at a separate address and use a fresh, empty browser profile each time, so they have their own storage. As Part 3 explained, storage belongs to one address in one browser.
Do I have to install Playwright MCP?
No. The automated tests and your own checks are the essential evidence. Exploration by the agent is a useful extra, and you can do the same exploring yourself.
Next: Publish your reading list.