Verdict
Yes
Write one automated test of the MVP's main path, from signup to the core action, and skip unit tests and coverage targets until the MVP handles money or private data.
Why
- Blast radiususers
- Change frequencyconstantly
- Detectabilitysame-day
- Reversibilitytrivial
- Test costmoderate
Write one automated test of the MVP's main path and nothing more until the MVP takes money or holds private data. My typical case is a web app that one or two people ship to its first hundred users. Blast radius is users, because early users see a broken feature and some leave. Change frequency is constantly, because the MVP changes in most weeks. Detectability is same-day, because an error tracker or a user reports a broken page within a day, and Reversibility is trivial, because a redeploy fixes most MVP bugs. Test cost is moderate: a browser test of the main path takes about an hour and needs an update when the flow changes. Rule R12 gives Test minimally; if Test cost rises to heavy, the decision becomes Do not test.
| When | Decision | Why |
|---|---|---|
| The MVP charges a card, through Stripe Checkout or a subscription | Test mandatory: the charged amount, the plan the customer gets, and the webhook that grants access | Blast radius rises to money and Reversibility to costly: a double charge needs a refund and costs an early customer's trust |
| The MVP shows each user records that other users must not see, such as their files or health notes | Test mandatory: one test that a second user is denied the first user's record | Blast radius rises to safety-or-legal and Detectability moves to never: a leaked record looks like a normal page |
| The MVP saves records that users build on, such as saved projects or notes | Test: the code that writes each record, with a test that reads back every saved field | Reversibility rises to with-effort: wrong records need a repair script and an email to each affected user |
| The MVP has no error tracker, and users who hit a bug leave without writing in | Test: the main path and the failure cases of signup and the core action (a duplicate email, a failed save) in CI, and add an error tracker so failures reach you the same day | Detectability moves to eventually: a broken signup looks like weak demand in the analytics |
| Every early user tries the MVP on a video call while you watch the screen | Do not test the MVP yet; write down each bug you see and fix it after the call | Detectability moves to immediately: you see each failure as it happens, and Reversibility stays trivial |
What breaks if you don't test
You rename a form field on the settings page, the signup handler reads the old name, and new accounts fail to save. Nobody on the team signs up after a deploy, because everyone has an account. The error tracker reports the failed saves the next morning, a redeploy restores signup, and the loss is the visitors who tried to sign up that day.
What you lose if you over-test
Unit tests for every screen of an MVP break with each redesign. A coverage target of 80 percent forces tests onto features you delete next month, so each change of direction means rewriting tests with the code. For a team of two, that time comes out of talking to users.
How to test
- Write one end-to-end browser test that walks the main path: sign up, do the core action, see the result.
- Find elements by role and label, as the Playwright guide shows, so a new layout does not break the test.
- Run the test in CI on every push, and block the deploy when it fails.
- Add a regression test each time a bug reaches a user.
- Before the first real charge, test the payment path with Stripe test cards.
Keep an error tracker on production: it keeps Detectability same-day.
Procedure and references
When the answer changes
- The first customer pays: the charge path moves to Test mandatory.
- Users depend on data the MVP stores, so a bug needs a repair script instead of a redeploy.
- Signups fall while the error tracker stays quiet: failures reach users without a report.
Code example
The one test I write on day one
The first test I write for an MVP looks like this, in Playwright:
import { test, expect } from '@playwright/test';
test('a new user signs up and creates a first project', async ({ page }) => {
const email = `smoke+${Date.now()}@example.com`;
await page.goto('/signup');
await page.getByLabel('Email').fill(email);
await page.getByLabel('Password').fill('correct-horse-battery-9');
await page.getByRole('button', { name: 'Create account' }).click();
await page.getByRole('button', { name: 'New project' }).click();
await page.getByLabel('Project name').fill('First project');
await page.getByRole('button', { name: 'Save' }).click();
await expect(page.getByRole('heading', { name: 'First project' })).toBeVisible();
});
The test asserts no colours or positions, only labels, so a weekly redesign leaves it green unless the path breaks. One run passes through the router, the form, the database and the session, and a failure in any of them fails the test.
Related questions
FAQ
- Should you write tests for an MVP?
Yes, an MVP needs one automated test of its main path, from signup to the core action, and no more until it handles money or private data. A browser test of the main path takes about an hour and fails when new users cannot sign up.
- Is TDD worth it for an MVP?
TDD for a whole MVP costs more than it saves, because most MVP features change or disappear within weeks. Use TDD for the MVP code that computes money or checks access.
- Should I test payments in an MVP?
Yes, test the payment path of an MVP before the first real charge: the amount, the plan the customer gets, and the webhook that grants access. A double charge needs a refund and costs an early customer's trust, so the framework gives Test mandatory.
- When should I add more tests to my MVP?
Add tests to an MVP when it starts charging, when users rely on data it stores, and each time a bug reaches a user. Charging moves Blast radius to money, stored data moves Reversibility to with-effort, and a bug that users find first shows where Detectability is weak.