Back to Blog
On this page3 sections

// deep dive

Testing app updates without breaking existing users

qa.codesqa.codes · 13 June 2026 · 9 min read
AdvancedMobile QAQA Engineers
mobile-testingapp-updatesmigrationregression

A fresh install is the one path almost everyone tests and almost no real user takes. The dangerous path is the upgrade: an existing user with old data, old settings, and an old session opening your new build.

part ofMobile QA

Here's the structural blind spot in mobile testing: QA almost always installs the new build clean, onto a fresh simulator or a wiped device. Real users don't. They have the previous version installed, with months of accumulated local data, a saved login, cached content, and preferences set long ago. When they update, your new code runs on top of all of that — and that's a code path your clean install never exercises. It's the mobile cousin of the daylight-saving bug: a transition no one tested.

Why upgrades break when fresh installs don't

A fresh install starts from nothing: empty database, default settings, no session, latest schema. An upgrade starts from whatever the last version left behind. The two diverge in specific places:

  • Local database / schema migrations. The new version expects a new schema; the old version's data is still on disk in the old shape. If the migration is missing, wrong, or untested, the app crashes on launch or loses data — for everyone who had the old version, which is to say everyone who matters.
  • Stored preferences and cached data. A setting that changed meaning, a cached response in an old format, a feature flag stored locally. The new code reads old data and misinterprets it.
  • Auth and sessions. The user was logged in on the old version. Does the new version keep them logged in, or dump them at the login screen? Either can be a bug depending on what changed.
  • Deep links and saved state. A notification or deep link saved under the old version's routing, opened in the new one.

How to actually test it

The core technique is simple and almost no one does it: install the previous production version first, use it like a real user, then upgrade in place. Don't wipe. Don't fresh-install. The steps:

  1. Install the current App Store / Play Store version (the one users actually have), not last week's build.
  2. Use it: log in, create data, change settings, accumulate the state a real user would have.
  3. Install the new build over the top, without uninstalling.
  4. Launch and verify nothing was lost, nothing crashed, and the user is in the state they expect.

The version you upgrade from matters. Users skip versions — someone might jump from a build three releases old straight to yours. If you only ever test N-1 → N, the N-3 → N migration chain is untested. For anything touching the local schema, test the oldest version you still meaningfully support.

App-update test pass

  • Install the live production version first; build real state (login, data, settings)
  • Upgrade in place over the old version — never uninstall, never wipe
  • Launch: no crash, no data loss, schema migration succeeded
  • Auth: session preserved (or re-auth handled cleanly) — no surprise logout that loses unsynced data
  • Settings/preferences from the old version still apply and still mean the right thing
  • Cached/offline data from the old version reads correctly under the new code
  • Test a multi-version jump (oldest supported → latest), not just N-1 → N
  • Forced-update / minimum-version gate (if any) triggers correctly for old clients
  • Repeat on both iOS and Android — migration code and OS update behaviour differ

The data-loss case deserves its own attention

Of all upgrade bugs, silent data loss is the worst, because it's irreversible and often unreported — the user just quietly loses their notes, their cart, their drafts, and may not connect it to the update. Treat any change to the local database, storage format, or sync logic as a flag for an explicit upgrade test with real pre-existing data. A migration that works on an empty database tells you nothing; the whole point is the data that's already there. Before you sign off, ask the question that separates a clean install from a real one: what does an existing user with months of data see when this lands?

// RELATED QA.CODES RESOURCES


// related

Deep dives·13 June 2026 · 9 min read

iOS vs Android testing differences QA should know

Fragmentation, permissions, system-back, lifecycle, hardware layout, and notifications diverge between platforms — so a pass on one isn't evidence for the other.

mobile-testingiosandroidcross-platform
Deep dives·13 June 2026 · 8 min read

p95 latency explained for QA engineers

What p95 actually means, why averages hide the bugs, and how to read a latency distribution as a tester.

performance-testinglatencymetrics