Guide · updated 22 September 2026
What to test before you ship an update
You cannot retest everything on every build, and you do not need to. Four groups of checks catch almost everything that breaks between releases.
Between two builds, most of the app did not change. The risk sits in four places: what you changed, what it touches, the paths that must never break, and the fixes you are claiming to have made. A release pass built around those takes an hour or two, not a week.
1. Check every fix, on the platform it was reported on
This is the group teams skip, and it is the one that embarrasses them. A bug marked fixed is a claim, not a result. Reproduce the original report step by step — on the platform it was reported on, since a fix that works on iOS may never have shipped to Android.
It helps to have this enforced rather than remembered. In qarunbook, marking an issue fixed does not return the check to passing: it reads R — retest, because the person who passed it last was looking at a build without the fix in it. It clears when somebody actually looks again.
2. Test what changed, and the screen it sits on
Test the new work on its happy path, then on its refused path: permission denied, no network, an empty list, a declined card. Then use the rest of the screen it lives on. Most regressions are not in the new feature — they are next to it.
3. The paths that must never break
Keep a short fixed list that runs every single time, no matter how small the change: sign up, sign in, sign out, reset a password, the one journey the app exists for, and taking a payment. Six to ten checks. If any of these fail, nothing else about the release matters.
4. The ship checks
The last group is about the release itself rather than the code: version raised, crash reporting arriving, emails landing in inboxes rather than spam, legal links working, and a rollback somebody actually knows how to perform.
The pass
# Release pass — build 42 ## Fixes from last round (FIX) | ID | Journey | Preconditions | Steps | Expected result | WEB | AND | IOS | |---|---|---|---|---|---|---|---| | FIX-01 | Every issue marked fixed is checked again | The list of issues closed since the last release | 1. Reproduce the original report step by step. | The original steps no longer produce the bug, on the platform it was reported on. | | | | | FIX-02 | The fix did not break its neighbours | As above | 1. Use the screen around each fix. | Nothing next to the fix has changed behaviour. | | | | ## What changed (CHG) | ID | Journey | Preconditions | Steps | Expected result | WEB | AND | IOS | |---|---|---|---|---|---|---|---| | CHG-01 | The new feature, happy path | Whatever the feature needs | 1. Use it the way it was designed. | It does what the release notes claim. | | | | | CHG-02 | The new feature, refused path | As above | 1. Deny it what it needs — permission, network, an empty state. | It fails clearly, without losing the user's work. | | | | | CHG-03 | The screen the change sits on | The changed screen | 1. Use the rest of that screen. | Everything else on it still works. | | | | ## Never ship broken (CORE) | ID | Journey | Preconditions | Steps | Expected result | WEB | AND | IOS | |---|---|---|---|---|---|---|---| | CORE-01 | Sign up | No account | 1. Create an account end to end. | Account created, verification arrives, app opens. | | | | | CORE-02 | Sign in and sign out | An existing account | 1. Sign in. 2. Sign out. | Both work; sign-out clears the session. | | | | | CORE-03 | Password reset | An existing account | 1. Run the reset flow to a new password. | The new password works, the old one does not. | | | | | CORE-04 | The one thing the app is for | Signed in | 1. Complete the main journey end to end. | It completes, with the result the user expects. | | | | | CORE-05 | Take a payment | A card on file | 1. Pay for something real. | Payment succeeds, receipt matches, nothing is charged twice. | | | | | CORE-06 | Upgrade over the previous build | Previous version installed, signed in | 1. Install this build over it. | Still signed in, data intact, no re-onboarding. | N/A | | | ## Before you press publish (SHIP) | ID | Journey | Preconditions | Steps | Expected result | WEB | AND | IOS | |---|---|---|---|---|---|---|---| | SHIP-01 | Build number and version raised | The build under test | 1. Check the version in the app and the store listing. | Both raised from the last release. | | | | | SHIP-02 | Crash reporting reaches the dashboard | The build under test | 1. Trigger a test crash. | It appears in the dashboard within minutes, with a readable stack. | | | | | SHIP-03 | Emails go out, and not to spam | A test address | 1. Trigger the verification and reset emails. | Both arrive, in the inbox, with working links. | | | | | SHIP-04 | Links in the app work | The build under test | 1. Tap privacy, terms and support links. | Each opens the right page. | | | | | SHIP-05 | Rollback plan exists | The previous build | 1. Confirm the previous build can be restored. | Someone knows how, and it is written down. | | | |
Or take the file: Markdown·CSV·Excel·no email, no sign-up.
Decide what "done" means before you start
Agree the rule in advance, or it gets negotiated at 9pm on release night. A workable one: no failures in the never-break group, no open issue on the changed work, and every fix from last round checked again. Anything else is a judgement call for the owner, recorded rather than remembered.
Let the machine do the boring half
The repetitive parts of a release pass — reading what failed, re-running steps, recording results — are exactly what an AI assistant is good at. Connected over MCP, it can read the plan, work through the checks it can drive itself, record each result under its own name, and pick up the issues your testers left. The human pass then spends its time where judgement is actually needed.