•
Drizz raises $2.7M in seed funding •
•
Featured on Forbes
•
Drizz raises $2.7M in seed funding •
•
Featured on Forbes

Key takeaways
Installation testing on mobile is practice of verifying your app installs, launches, and behaves correctly across every path a user can get it onto their device. Fresh install from App Store. Upgrade from an older version. Restore from an iCloud or Google backup. TestFlight beta. Sideload APK. Each is a different code path, and each can break independently.
Most "installation testing" checklists list "install from store" and stop. That's testing 20% of surface. This post covers other 80% with paths iOS and Android actually have and what to test in each.
Installation testing verifies four things:
That's it. Anything beyond that is functional testing pretending to be install testing.
Installation testing is step one, before anything else on this list runs. If install is broken, none of your other test cases matter because user never got past loading screen.
Not every user gets your app same way. Here's real set.
iOS install paths:
Android install paths:
That's 6 iOS paths and 8 Android paths. You don't need to test all 14 on every release. You need to know which ones apply to your app and which ones actually differ.
Where they differ:
The IPA is artifact your installation testing run consumes on iOS, and signing state of that IPA determines which install path it can actually take. Similar story for .apk and .aab on Android. Fastlane can automate build-to-device path that feeds every installation testing cycle across App Store, TestFlight, and Play track uploads.
These three are highest-value scenarios. Skip any and you'll ship bugs.
Fresh install. Device has never seen your app. No stored data. Full permission prompts. Onboarding runs. This is what most people test and it's easiest.
Upgrade install. Existing version replaced by newer one. The user has stored data. Preferences. Cached tokens. Saved cards. Whatever schema your app used, it needs to migrate cleanly to new schema.
This is where Room migrations, Core Data lightweight migrations, and SharedPreferences renames go wrong. v2.1 had a table with a nullable=false column. v2.3 added a new column with nullable=false. If your Migration didn't set a default, existing users crash on first launch after update.
Test upgrade from at least last two public versions. Not three months back. Two versions back.
Restore-from-backup. User bought a new phone. Restored from iCloud or Google backup. Your app appears on home screen, but data behind it is from backup, not from your servers. This is where you find bugs where app assumes it was freshly installed but has stored files from another device.
On iOS, Documents/ gets restored. On Android, files marked for backup get restored. If your session token was in either, user is now on a new device with a valid token that was minted for old device.
You don't need 300 tests. You need a small matrix that hits real bug surfaces.
Path axis: Fresh install, upgrade from N-1, upgrade from N-2, restore-from-backup. Storage axis: Plenty of storage, low storage (below 500MB free). Network axis: Wi-Fi, cellular only, offline during install completion.
That's 4 paths × 2 storage × 3 network = 24 test cases. Trim to ones that matter for your app.
A minimum viable set:
Six tests. Real devices only. Repeat on your top iOS and Android devices. Twelve to eighteen runs per release. That catches majority of shipped install bugs.
Things iOS has that Android doesn't.
"Delete App" vs "Offload App." iOS lets users offload an app, which keeps user data (documents, Core Data database) but removes binary. When user taps offloaded icon, app re-downloads. Your first launch after re-install with existing data is a code path you probably never tested. Test it.
App Clips. If your app has an App Clip, that's a separate install artifact with its own limits (10MB max, subset of entitlements). Test that App Clip → full app upgrade preserves any user actions taken in Clip.
Restore from backup with Sign in with Apple. SIWA identities are per-Apple-ID. Restoring to a new device with same Apple ID should preserve identity. Restoring to a different Apple ID's device should not. Test both.
Universal Links after install. A user tapped a Universal Link that opened App Store, then installed. Does install remember original link and route them there on first launch? Deferred deep linking. Very few teams test this.
Android has its own set.
Split APKs (App Bundle). Play Store delivers your .aab as multiple split APKs based on device configuration. The user only downloads what their device needs. This means APK that lands on a Pixel 8 is different from one that lands on a Galaxy S22. Test on both. Split APK bugs are real.
Auto-updates in background. Play Store can update your app while user isn't using it. Existing running Activity might have a different code version than newly installed one. Sounds absurd but happens. Test that app handles version mismatch on next launch.
Auto-restore from backup. Android 12+ enables cloud backup by default for most apps. Your app data gets backed up unless you opt out or configure android:allowBackup="false" explicitly. Users on new devices will restore your app with data. Test with a specific backup, not just any restore.
Google Play install referrer. The Play Store passes install attribution through Install Referrer API. If you're using this for attribution (most consumer apps do), test actual chain: campaign URL → Play Store → install → first launch → your attribution code reads referrer.
Six recurring bugs I see across teams that skipped install testing.
Room migration missing. New column added to a table without a Migration class. First launch after upgrade throws IllegalStateException: Room cannot verify data integrity. All existing users crash.
Provisioning profile expired in Enterprise build. Enterprise apps use certificates that expire yearly. When they do, every user's app stops launching. Not a bug you catch in testing unless you specifically watch expiration.
Sign in with Apple identity mismatch after restore. User restored their phone, but SIWA identifier changed subtly (case sensitivity, edge whitespace). Your backend rejects login. User can't get in.
App Group container permissions after enterprise install. Enterprise builds sometimes fail to write to shared app group containers because entitlement path differs from App Store builds. Extensions can't read shared data.
Split APK missing native library on specific device. Your .aab had a native library gated on ARMv8. A user with an older ARMv7 device installed. The library isn't in their APK bundle. First launch crashes with UnsatisfiedLinkError.
Attribution lost on Play Store deferred install. User clicked a campaign link, redirected to Play Store, closed browser, then installed 3 days later. The install referrer window expired. Your attribution shows organic. Marketing budget miscounted.
Automation of install flows is limited by what your test framework can control.
Selector-based frameworks (Appium, XCUITest, Espresso) can automate app launch and post-install onboarding, but they can't easily automate actual install step. Appium has some support for installing an APK before test start, but doesn't help with upgrade path testing across versions.
For real install testing you often need a wrapper script that:
Every step is a place your test can flake. Steps 3, 4, and 7 depend on interacting with app UI. Selector-based tools fail if any locator changed between versions. Which they usually did. Otherwise you wouldn't be upgrading.
We built Drizz partly for this shape of problem. Tests are written as plain English commands. Tap "Get started". Type "user@example.com" into "Email". Vision AI reads screen like a person does. When your v2.1 onboarding said "Continue" and your v2.3 says "Next," a Drizz test for step 3 above still works if you tell it to look for what a user would look for.
For upgrade testing specifically, this matters because you're driving different app versions in same test suite. Selector-based tests need per-version test files. Drizz tests describe what user does, not what DOM looks like, so same test can drive an upgrade flow from v2.1 to v2.3.
Concrete before-and-after on "upgrade from v2.1 with cart preserved" test.
Before, on Appium: Test in v2.1 taps com.app:id/get_started_btn. Test in v2.3 needs to tap com.app:id/onboard_primary_cta because ID was renamed. QA lead maintains two test files, or a lookup table of "which ID for which version." Debug time on every version bump.
After, on Drizz: Same test. Tap "Get started" in v2.1. Tap "Continue" in v2.3, written as Tap primary onboarding button and Drizz Vision AI finds it in both cases. One test file, both versions.
For teams shipping every two weeks, this changes install testing from a chore that gets skipped to something that runs on every release.
Verifying an app installs, launches, and behaves correctly across fresh install, upgrade, restore, and sideload paths.
Fresh install starts with no data. Upgrade starts with data from a previous version and must migrate it correctly.
Yes. iOS App Store, TestFlight, and Ad-hoc use different signing. Android Play Store and sideload behave differently too.
Database migration failures during upgrade. A new column without a proper Migration class crashes every existing user.
Install a version, generate user data, back up device, restore to a different device, and verify data integrity.
Partially. Install and uninstall commands script easily. UI verification after install needs a reliable test framework.