Mobile app crash testing: how to find crashes before launch
Crashes are the bugs users forgive least and the ones store algorithms punish most. This guide explains what makes mobile apps crash, how to trigger those conditions on purpose before launch, how to read Android and iOS crash data, and a stability task your AI beta tester can run on every build.
Who it’s for
- Mobile developers preparing an Android or iOS release
- Teams whose crash-free rate dropped after a recent update
- QA engineers building a stability pass for each build
- Founders who want to know whether the app is stable enough to launch
Updated 2026-10-25.
Why crash testing is its own test type
A crash is any time the app disappears from under the user: a real exception, the system killing the app for using too much memory, or an unresponsive app that the OS offers to close. Users do not distinguish between these. They see a broken app and leave a one-star review.
Both stores watch stability. Google Play's Android vitals tracks crash rate and ANR rate against bad behavior thresholds and can reduce the visibility of apps that cross them. Apple surfaces crash data in Xcode Organizer and App Store Connect, and review can reject a build that crashes on launch. The exact thresholds change, so check the current Play Console documentation rather than quoting a number.
Normal feature testing follows the happy path. Crash testing deliberately walks the edges: rotating mid-animation, denying a permission the code assumed it had, returning from the background after the session expired. Most production crashes live in those edges.
Types of crashes and freezes
- Uncaught exceptions: null references, out-of-range indexes, failed casts, parsing unexpected API responses.
- Native crashes: memory faults in native libraries, often inside third-party SDKs.
- ANRs on Android (application not responding): the main thread is blocked for roughly five seconds, and the system offers to close the app. Network calls, database work or heavy JSON parsing on the main thread are the usual causes.
- Watchdog terminations on iOS: the system kills the app for taking too long to launch or to respond to a lifecycle event.
- Memory terminations: iOS jetsam and Android low-memory kills. Users see the app "crash" when they switch back to it.
- Freezes and blank screens: technically not crashes, but to the user they are the same thing.
Conditions that trigger crashes
Work through each of these in every core flow:
- Rotation and configuration changes: rotate during loading, with a dialog open and while typing. Android recreates activities on rotation; state that lives in the wrong place is lost or dereferenced as null.
- Background and foreground: switch apps mid-flow, lock the screen, wait, come back. Expired tokens, released resources and stale views cause many crashes here.
- Permission denial: deny camera, location, photos or notifications, then use the feature that needs them. Also revoke a permission in system settings while the app is open and return.
- Low memory: open many image-heavy screens in a row, or use the developer options to simulate memory pressure, then return to the first screen.
- Offline and slow network: turn on airplane mode before launching, in the middle of a request and after a request started; test a slow connection where responses arrive after the user left the screen.
- Interruptions: an incoming call, an alarm or a notification during a purchase or upload.
- Cold start from a deep link or notification: open a link to a detail screen when the app is not running. Code that assumes the home screen loaded first crashes here.
- Input edge cases: empty fields, very long text, emoji, pasted content, double taps on submit, rapid back presses.
- Locale and accessibility settings: right-to-left languages, the largest font sizes, large display size, and date formats that do not parse.
- First launch and upgrade: a clean install with no data, and an upgrade from the previous production version with existing data.
Reading crash data
Android
- Logcat shows the stack trace for Java and Kotlin crashes and the "ANR in" lines for freezes. Filter by your package name or by
AndroidRuntime. - Android vitals in the Play Console aggregates crashes and ANRs from users who opted in to sharing data, by device and Android version.
- Keep ProGuard or R8 mapping files for every release build so stack traces can be deobfuscated.
iOS
- Xcode Organizer and App Store Connect collect crash reports from users who share analytics; TestFlight testers' crashes arrive with their optional comments.
- Crash logs must be symbolicated with the dSYM files from the same build, so upload dSYMs with every release and keep them.
- MetricKit reports hangs, crashes and memory terminations that do not always appear as classic crash logs.
Crash reporting tools
Firebase Crashlytics, Sentry, Bugsnag and similar SDKs group crashes, show breadcrumbs of what the user did before the crash, and alert you when a new crash spikes. Add one before the beta, not after launch.
Reproducing and reporting a crash
A crash report that cannot be reproduced is a crash that will not be fixed. Capture:
- Device model, OS version, build number and distribution channel.
- Exact steps, including timing (for example, "rotate while the spinner is visible").
- Whether it happens on a clean install, after upgrade, or both.
- A screen recording of the steps up to the crash.
- The stack trace or the crash log, attached rather than pasted into the title.
Title: Crash on rotation while the Upload progress dialog is open Environment: Pixel 7a, Android 15, build 4.0.1 (520), internal testing track Severity: Critical (crash in a core flow, reproducible every time) Steps to reproduce: 1. Log in with the test account and open Projects > New upload. 2. Pick any photo and tap Upload. 3. While the progress dialog is visible, rotate the phone to landscape. Expected: The upload continues and the dialog is shown in landscape. Actual: The app closes immediately. On reopening, the upload is not listed. Evidence: screen recording of steps 2-3; logcat shows IllegalStateException: Fragment UploadDialog not attached to an activity. Notes: Does not happen when rotation is locked. Also reproduced on an emulator at API 34.
Mobile crash testing checklist
- Clean install and first launch with no account, then with the test account.
- Upgrade over the previous production version.
- Rotate on every screen, including during loading and with sheets or dialogs open.
- Background and return on every screen; lock the device for a few minutes and return.
- Deny each permission, use the related feature, then grant it later in settings.
- Airplane mode before launch and mid-request; slow network with late responses.
- Cold start from a deep link and from a notification.
- Rapid double taps on submit, back and navigation items.
- Largest font size, RTL language, dark mode.
- Image-heavy navigation to provoke memory pressure.
How to prioritize crashes
- Crashes on launch or on first run: these block everyone.
- Reproducible crashes in core flows: signup, login, the main action, payments.
- Crashes tied to common devices or OS versions in your audience.
- ANRs and freezes in frequent flows.
- Rare crashes in secondary features, scheduled for later releases.
Crash testing with an AI beta tester
An AI beta tester like betatest.ing runs your uploaded build on Android emulators and real Android devices, and on real iPhones and iOS simulators, and deliberately applies the conditions above: it rotates, backgrounds and resumes, denies permissions, interrupts flows, goes through cold starts and tries edge-case input on every screen. When the app closes, freezes, shows an ANR dialog or lands on a blank screen, it files a finding with the exact steps, severity, an annotated screenshot and a recording of the moments before the crash. It does not collect your device logs, so pair its reports with your crash reporter or logcat for the stack trace. Because the pass is repeatable, run it on every build as a stability check and compare the stability score over time.
The test task
What you send your AI beta tester. It works out the steps and tests like a real user.
Run a crash and stability test on my mobile app [UPLOADED BUILD OR PUBLIC STORE LINK]. It is [WHAT THE APP DOES]. Sign in with the saved test login if needed. On every screen and in each core flow ([CORE FLOWS, E.G. SIGNUP, CREATE A PROJECT, CHECKOUT]), try the conditions that cause crashes: rotate the device during loading and with dialogs open, background the app and return after a while, deny each permission prompt and then use the related feature, turn the network off before and during requests, open the app cold from a deep link if there is one, double-tap submit and back buttons, and use very long text and emoji in inputs. Also try the largest system font size. Do not make any real purchases. Treat every crash, freeze, app-not-responding dialog or blank screen as a finding with exact steps to reproduce, severity, an annotated screenshot and a recording of the steps leading to it. End with a report that scores stability, error handling and recovery with the top fixes.
Fill in your details
Here, or later in the chat with your tester.
- [UPLOADED BUILD OR PUBLIC STORE LINK] "the uploaded .ipa/.apk/.aab" or a public store link
- [WHAT THE APP DOES] One sentence about the app and its users
- [CORE FLOWS, E.G. SIGNUP, CREATE A PROJECT, CHECKOUT] The three to five flows that must never crash
What the AI beta tester checks
- Clean install, first launch and login
- Rotation during loading and with dialogs or sheets open
- Background and resume on every screen
- Permission denied, then the related feature used
- Offline before launch and mid-request
- Cold start from a deep link or notification
- Rapid double taps and fast back navigation
- Very long text, emoji and pasted input
- Largest font size and dark mode
- Freezes, blank screens and ANR dialogs
What you get
- A finding for every crash, freeze or blank screen with exact steps and severity
- Annotated screenshots of the last state before each crash
- Recordings of the steps leading to each crash
- A report scoring stability, error handling and recovery with the top fixes
How to run it with betatest.ing
- Add your app as a project in betatest.ing and upload the .apk, .aab or .ipa build.
- Add a test login and list the core flows that must never crash.
- Send the crash testing task; the tester applies rotation, background, permission, network and input edge cases.
- Match each finding with the stack trace in your crash reporter, fix, and re-run on the next build.
Tips
- Add a crash reporting SDK before the beta so every crash comes with a stack trace and breadcrumbs.
- Upload dSYMs and keep R8 mapping files for every build or crash logs will be unreadable.
- Test upgrades from the previous production version, not only clean installs.
- Move network, database and parsing work off the main thread to avoid ANRs.
- Re-run the same stability pass on every build and watch the score, not just the count.
Mobile app crash testing: FAQ
What is the difference between a crash and an ANR?
A crash is the app terminating, usually from an uncaught exception or a native fault. An ANR (application not responding) is Android's dialog when the main thread has been blocked for roughly five seconds; the app has not crashed yet, but the user is offered to close it. Both count against your app in Android vitals.
How do I find crash logs on iOS?
Crashes from users who share analytics appear in Xcode Organizer and App Store Connect, and TestFlight crashes arrive with optional tester comments. Logs need to be symbolicated with the dSYM files of the same build, so upload and keep dSYMs for every release.
How do I read Android crash logs?
Run the app with a connected device or emulator and watch logcat, filtered by your package name or AndroidRuntime, for the stack trace. In production, Android vitals in the Play Console and a crash reporting SDK like Crashlytics show grouped crashes by device and version.
What crash rate is acceptable?
Google Play defines bad behavior thresholds for crash rate and ANR rate and may reduce an app's visibility above them; the values are documented in the Play Console and can change, so check the current text. Aim for crashes to be rare enough that a session almost never ends in one.
Can an AI beta tester find crashes?
Yes. betatest.ing runs your uploaded build on emulators, simulators and real devices and deliberately rotates, backgrounds, denies permissions, interrupts and goes offline on every screen. Every crash, freeze, ANR dialog or blank screen becomes a finding with steps, a screenshot and a recording.
Does it give me the stack trace?
No. It reports what it observes on the device with exact steps and a recording. Match the time and steps against your crash reporter or logcat to get the stack trace.
Why does my app crash only on some devices?
Device-specific crashes usually come from manufacturer customizations, different Android versions, memory limits, missing hardware features or a native SDK built for some architectures only. Reproduce on an emulator with the same API level first, then on the real device model if you can.
Should I test crashes on emulators or real devices?
Both. Emulators and simulators reproduce most logic and lifecycle crashes quickly across many OS versions. Real devices catch memory limits, manufacturer behavior, real sensors and performance. See our emulator vs real device guides.
Related beta testing guides
- Android emulator vs real device testing — The Android emulator is fast, free and covers dozens of screen sizes and API levels; real phones show you manufacturer skins, true performance and hardware. This guide explains what each one catches, when the emulator is enough, and how to split your beta test between them, with a task your AI beta tester can run on emulators and real Android devices.
- iOS simulator vs real device testing — The iOS Simulator is where most iPhone development happens, but it is not an iPhone. This guide lists what the simulator handles well, what only a real device can show you, and how to split a beta test between the two, with a task your AI beta tester can run on real iPhones and simulators from an uploaded .ipa.
- Bug severity levels — A shared severity scale lets beta testers, developers and product managers agree on how bad a bug is in seconds. Here is a simple four-level scale with examples, plus how severity differs from priority.
- How to write a bug report — A good bug report lets a developer reproduce the problem in minutes without asking a single question. Here is what to include, how to write each part, and an example you can copy.
- Mobile app beta testing — Mobile apps reach testers through store testing tracks, run on hardware you do not control, and get interrupted constantly. This guide covers how to distribute a mobile beta, what to test that is specific to phones, and how an AI beta tester fits alongside your human testers.
- Free tool: Beta testing checklist generator — An interactive checklist for websites, SaaS, mobile apps, stores and extensions. Progress saved, Markdown export.