Testing what matters
The reorder app works on your phone. Before a shop owner trusts it with a real order, you need proof that the few things that would hurt him cannot quietly break. This lesson shows how to choose those things, and how to cover them with fast unit tests, a handful of API tests and one end-to-end test of the core flow.
By the end you can
- Turn the reorder app's promises into a short risk list and pick the layer that can prove each one
- Pull business rules out of route handlers so a unit test can check them in milliseconds with Vitest
- Test the API over HTTP with supertest against a real test database, including a retry that must not double an order
- Write one Maestro end-to-end flow for sign in, repeat and status, with stable test IDs and no fixed sleeps
The everyday picture
Think of a small restaurant that takes orders through a food delivery app. Before the evening rush, the cook tastes each sauce. That takes seconds, so she does it for every pot. Then the head cook checks a few full plates at the pass: right dish, right portion, right price on the ticket. Once, just before opening, a friend places a real order through the delivery app and watches it arrive at the door.
Nobody tastes the salt shaker or weighs every napkin. The checks follow what a customer would notice and complain about: a burnt sauce, a wrong dish, an order that never comes. Each check also sits at the cheapest level that can catch its problem. You do not order a whole meal through the app to find out whether the soup has salt.
Software tests work the same way. Unit tests taste the sauces, API tests check plates at the pass, and one end-to-end test is the friend ordering through the app.
Start from what would hurt
A beginner's instinct is to test everything, or to test whatever is easiest. Both waste time. Start instead from the promises the app makes to its users, the ones in your spec from From idea to one-page spec and the acceptance criteria from User stories and acceptance criteria. For each promise, ask two questions: how likely is it to break, and how bad is it for the shop owner if it does?
For the reorder app, a short list covers most of the harm:
- The repeat uses today's prices. The past order stored last week's prices. If the new order copies them, Mangrove sends an invoice that does not match the app, and the shop owner stops trusting the total.
- A retry never doubles the order. Shops are on patchy mobile data. If the response is lost and the app sends again, the shop must still get one order, as in idempotency.
- A shop sees only its own orders. One shop reading another shop's orders is a privacy failure, even if it happens once.
- Edits are respected. Quantity 0 removes a line, quantities stay within limits, and an item no longer sold is shown and refused, never dropped silently.
- The core flow works on a phone. Sign in, repeat, see the status. If any screen in that path is broken, nothing else matters.
Notice what is missing: the colour of the buttons, the exact wording of the weekly summary, the settings screen. Those can break too, but a person looking at the app will notice quickly and the harm is small. You check them by hand before a release.
Write the list down in the repository, for example in TESTING.md, with the test that covers each line. When someone asks "is the retry case tested?", the answer is a file name, not a memory.
Quick check
You have time for one more automated test this week. Which risk deserves it most?
A double order is likely on patchy data and costly: two deliveries, a refund and a shop owner who stops trusting the app. The other two are small and easy for a person to spot. Wording and fonts are real problems, but a manual check covers them well.