Skip to main content
Mobile Engineering · March 2026

Mobile App Testing Guide 2026:
Complete QA Strategy

A production-grade QA playbook covering the mobile testing pyramid, tool comparisons (Detox, Appium, XCTest, Espresso, Firebase Test Lab, BrowserStack), CI/CD pipelines, crash reporting, beta testing, and a pre-launch checklist.

22 min read·Updated March 21, 2026·By Codazz Engineering

The Mobile Testing Pyramid

The testing pyramid is the foundational model for building a sustainable, cost-effective mobile QA strategy. It prescribes writing many small, fast tests at the bottom (unit), fewer medium-scope tests in the middle (integration), and a small number of slow, comprehensive tests at the top (E2E).

Mobile teams that invert the pyramid — relying primarily on manual and E2E tests — pay a steep price: slow feedback cycles, brittle test suites that break on every UI change, and an inability to ship confidently at speed. The pyramid keeps your test suite fast, maintainable, and genuinely useful.

Unit Tests — 70% of your suite
Tools: Jest, JUnit, XCTest

Test individual functions, reducers, ViewModels, and business logic in complete isolation. No network calls, no filesystem, no UI rendering. Run in milliseconds. Should cover every edge case in your core logic: authentication state machines, data transformation functions, API response parsing, price calculation, form validation.

Speed

< 1ms per test

Maintenance

Low — pure logic, minimal change when UI evolves

Integration Tests — 20% of your suite
Tools: React Native Testing Library, Espresso (unit mode), XCTest

Test how components and modules work together — without a real device or network. Render components with real (mocked) data, verify that a Redux action updates the UI correctly, confirm that navigation happens after a form submission. Slower than unit tests but far more realistic.

Speed

10ms–200ms per test

Maintenance

Medium — changes when component contracts change

E2E Tests — 10% of your suite
Tools: Detox, Appium, XCUITest, Espresso (UI mode)

Test the full application from the user's perspective on a real device or simulator. Covers complete user journeys: sign up, complete onboarding, make a purchase, receive a push notification. Slow, potentially brittle, and expensive to maintain — but irreplaceable for catching integration failures between app and backend.

Speed

30s–5 min per test

Maintenance

High — tightly coupled to UI structure and backend behavior

The Anti-Pattern: The Ice Cream Cone

Many mobile teams end up with an inverted pyramid — heavy reliance on manual testing and E2E automation, almost no unit tests. This is called the "ice cream cone" and it is a quality crisis waiting to happen. E2E tests break when UI changes, take hours to run, and provide no signal about where the bug actually lives. If your team's QA process is primarily manual with a few flaky E2E tests, reorganizing toward the pyramid is the highest-ROI improvement you can make.

Types of Mobile App Testing

Beyond the pyramid's structural layers, there are specialized testing disciplines that target specific risk areas of mobile apps. A mature QA strategy integrates all of them.

Functional / UI Testing
Critical

Verifies that every feature works as the user expects — buttons respond, forms validate, data displays correctly, navigation flows correctly.

Tools: Detox, Appium, XCUITest, Espresso
Performance Testing
High

Measures app startup time, screen render time, memory usage, CPU usage, battery consumption, and network efficiency. Reveals issues that make the app feel sluggish on real hardware.

Tools: Android Profiler, Instruments (Xcode), Firebase Performance Monitoring
Security Testing
High

Checks for insecure data storage (plaintext secrets in SharedPreferences/UserDefaults), unencrypted API communication, certificate pinning bypass, insecure deep link handling, and sensitive data leakage in logs or screenshots.

Tools: MobSF, OWASP ZAP, Frida, Burp Suite Mobile
Accessibility Testing
High

Ensures the app is usable by people with disabilities. Verifies that all interactive elements have accessibility labels, sufficient color contrast, logical focus order, and that screen readers (VoiceOver/TalkBack) can navigate the app meaningfully.

Tools: Accessibility Inspector (iOS), Accessibility Scanner (Android), axe DevTools Mobile
Compatibility Testing
High

Validates that the app works correctly across different OS versions, screen sizes, device manufacturers (especially on Android), and locale/language settings. Also tests behavior with different system settings: dark mode, large text, reduced motion.

Tools: Firebase Test Lab, BrowserStack, Sauce Labs
Network Condition Testing
Medium

Tests app behavior under poor network conditions — slow 3G, airplane mode, sudden connection drops, flaky WiFi. Verifies that error states are handled gracefully, data is not lost, and the app recovers when connectivity returns.

Tools: Network Link Conditioner (iOS), Android Emulator network settings, Charles Proxy
Installation / Update Testing
Medium

Verifies that fresh installs, updates from previous versions, and uninstall/reinstall cycles work correctly. Particularly important for database migration testing — does upgrading from v2 to v3 correctly migrate all user data?

Tools: Manual + scripted upgrade tests
Localization Testing
Medium (high if you support multiple languages)

Validates that translated strings fit UI layouts (German and Russian strings are often 30–50% longer than English), that date/time/currency formats are correct for each locale, and that RTL languages (Arabic, Hebrew) render the UI correctly.

Tools: Pseudo-localization tools, manual testing in target locales

Tool Comparison: Detox, Appium, XCTest, Espresso

Choosing the right test automation framework shapes your entire QA workflow. Each tool has a distinct architecture and optimal use case.

ToolPlatformApproachLanguageSpeedReliability
DetoxiOS + Android (React Native, Expo)Grey-box (syncs with JS bridge)JavaScript / TypeScriptFastHigh
AppiumiOS, Android, Web, DesktopBlack-box (WebDriver protocol)Any (JS, Python, Java, Ruby, C#)ModerateMedium
XCUITestiOS / iPadOS onlyWhite-box (Apple SDK, in-process)Swift / Objective-CFastHigh
EspressoAndroid onlyWhite-box (Google SDK, in-process)Java / KotlinFastHigh
XCUI + Espresso via AppiumiOS + AndroidBlack-box (WebDriver wrapper)AnyModerateMedium
Detox
Best E2E framework for React Native and Expo in 2026
Strengths

Grey-box design means Detox automatically waits for async operations to complete before running assertions — dramatically reducing flaky tests caused by timing issues. First-class TypeScript support. Ships with React Native CLI. Excellent documentation and active community. Works with simulators and real devices.

Limitations

Only supports React Native and Expo apps. Requires native build process — adds complexity to CI setup. Some Expo managed workflow features require ejecting or using Expo's build service.

Verdict: The default E2E choice for any React Native project. Start here.
Appium
Best when you need cross-platform tests written once in a single language
Strengths

Truly cross-platform — one test suite covers iOS, Android, and mobile web. Supports virtually any programming language via the W3C WebDriver protocol. Works with any app type (native, hybrid, React Native, Flutter). Large ecosystem of drivers and plugins.

Limitations

Black-box approach means you must add explicit waits and sleeps — the primary source of test flakiness. Slower test execution than native frameworks. Requires Appium server setup and management. WebDriver protocol overhead adds latency.

Verdict: Ideal when your team needs a single cross-platform test suite, or when testing hybrid apps, mobile web, or non-React Native frameworks.
XCUITest
Apple's official iOS testing framework — fastest and most reliable for native iOS
Strengths

Runs in-process with your app — no network round-trip to an Appium server. Best possible performance and reliability for iOS. Full access to iOS accessibility tree. First-party Apple support and documentation. Integrates natively with Xcode Cloud CI.

Limitations

iOS and iPadOS only. Tests must be written in Swift or Objective-C. Cannot easily be reused for Android. Requires Xcode and macOS build agents.

Verdict: Essential for native iOS apps. For React Native, Detox wraps XCUITest, so you get the same reliability through a more convenient JavaScript interface.
Espresso
Google's official Android testing framework — fastest for native Android
Strengths

Runs in-process on Android — no WebDriver server overhead. Automatic synchronization with the main thread, AsyncTask, and RecyclerView scroll animations. Deep integration with Android Studio and Firebase Test Lab. Strong Kotlin support.

Limitations

Android only. Kotlin/Java required. Cannot be reused for iOS. RecyclerView interactions require additional Espresso-Contrib library. Idling resource setup can be complex for custom async operations.

Verdict: The correct choice for native Android apps. For React Native, Detox wraps Espresso under the hood on Android — use Detox for a unified JavaScript experience.

Sample Detox Test — React Native Login Flow

// e2e/auth/login.test.ts — Detox E2E test
import { device, element, by, expect } from 'detox';

describe('Login Flow', () => {
  beforeAll(async () => {
    await device.launchApp({ newInstance: true });
  });

  beforeEach(async () => {
    await device.reloadReactNative();
  });

  it('should show login screen on launch', async () => {
    await expect(element(by.id('login-screen'))).toBeVisible();
    await expect(element(by.id('email-input'))).toBeVisible();
    await expect(element(by.id('password-input'))).toBeVisible();
  });

  it('should show validation errors for empty form', async () => {
    await element(by.id('login-button')).tap();
    await expect(element(by.text('Email is required'))).toBeVisible();
    await expect(element(by.text('Password is required'))).toBeVisible();
  });

  it('should show error for invalid credentials', async () => {
    await element(by.id('email-input')).typeText('wrong@example.com');
    await element(by.id('password-input')).typeText('wrongpassword');
    await element(by.id('login-button')).tap();

    // Detox automatically waits for async operations
    await expect(element(by.text('Invalid email or password'))).toBeVisible();
  });

  it('should navigate to dashboard on successful login', async () => {
    await element(by.id('email-input')).typeText('testuser@example.com');
    await element(by.id('password-input')).typeText(process.env.TEST_USER_PASSWORD!);
    await element(by.id('login-button')).tap();

    // Detox waits for navigation to complete
    await expect(element(by.id('dashboard-screen'))).toBeVisible();
    await expect(element(by.id('welcome-message'))).toHaveText('Welcome back, Test User');
  });

  it('should persist session across app restarts', async () => {
    // After successful login from previous test
    await device.sendToHome();
    await device.launchApp({ newInstance: false }); // Do not clear storage
    await expect(element(by.id('dashboard-screen'))).toBeVisible();
  });
});

Device Farms: Firebase Test Lab & BrowserStack

Running automated tests on a single device or simulator catches some bugs, but the real world has thousands of device and OS combinations. Device farms let you run your suite across dozens of real devices in parallel.

Firebase Test Lab
Google's cloud device farm — best integration with Android and free tier available

Firebase Test Lab provides real Android and iOS devices hosted in Google data centers. Supports Espresso, XCUITest, Robo tests (automated exploration without writing test code), and game loops. Integrates natively with Google Cloud CI/CD. The free Spark plan includes limited daily tests on shared devices.

Strengths
  • Native Espresso + XCUITest support
  • Robo test crawls app automatically (no code needed)
  • Free tier (Spark plan: 10 virtual, 5 physical tests/day)
  • Deep Firebase ecosystem integration
  • Detailed video, screenshot, and log output
Limitations
  • Physical device availability varies
  • iOS device selection smaller than Android
  • Pricing can scale quickly at high volume
Pricing: Free Spark tier; Blaze: ~$1/hr virtual, ~$5/hr physical device
BrowserStack App Automate
Most comprehensive device catalogue — best for cross-platform and iOS

BrowserStack offers the largest real device catalogue: 3,000+ Android and iOS devices. Supports Appium, Espresso, XCUITest, and Flutter. Provides live interactive device sessions for exploratory testing alongside automated test execution. Excellent for accessibility testing — ships with screen reader testing support.

Strengths
  • 3,000+ real devices including latest and legacy
  • Best iOS physical device coverage
  • Interactive live device sessions for exploratory testing
  • Accessibility testing with screen reader support
  • Low-latency network simulation built-in
Limitations
  • More expensive than Firebase at scale
  • No free tier for automated testing (only 100-minute trial)
  • Can be slower than native device farms for Espresso/XCUITest
Pricing: Automate plans from ~$249/mo; Team plans scale with parallel sessions
Sauce Labs
Enterprise-grade with the strongest compliance and security story

Sauce Labs targets enterprise teams with strict compliance requirements. Offers real device, virtual device, and browser testing in one platform. GDPR, SOC 2 Type II, and FedRAMP compliant. Excellent for regulated industries (fintech, healthcare) where data residency matters.

Strengths
  • SOC 2, GDPR, FedRAMP compliance
  • Dedicated private device cloud options
  • Unified real device + browser + virtual device platform
  • Strong enterprise SLA and support
Limitations
  • Most expensive option
  • Overkill for small teams
  • UI less polished than BrowserStack
Pricing: Enterprise plans from ~$399/mo; custom pricing for private clouds

Running Detox Tests on Firebase Test Lab

# Run Detox E2E tests on Firebase Test Lab via gcloud CLI
# Step 1: Build your app for testing
yarn detox build --configuration ios.release

# Step 2: Run on Firebase Test Lab
gcloud firebase test ios run \
  --test "ios/build/Build/Products/Release-iphonesimulator/YourAppUITests.zip" \
  --app "ios/build/Build/Products/Release-iphonesimulator/YourApp.app" \
  --device model=iphone15pro,version=17,locale=en_US,orientation=portrait \
  --device model=iphone12,version=16,locale=en_US,orientation=portrait \
  --results-bucket gs://your-project-test-results \
  --results-dir "e2e-$(date +%Y%m%d-%H%M%S)"

# For Android (Espresso) on Firebase Test Lab
gcloud firebase test android run \
  --type instrumentation \
  --app app/build/outputs/apk/debug/app-debug.apk \
  --test app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk \
  --device model=Pixel7,version=33,locale=en,orientation=portrait \
  --device model=GalaxyS21,version=31,locale=en,orientation=portrait \
  --use-orchestrator

Automation vs Manual Testing

Automation and manual testing are complementary, not competing. The question is not "should we automate?" — it is "what should we automate, and what requires human judgment?"

Test TypeAutomate?Rationale
Regression tests for stable featuresAlways automateRun on every commit. Too slow and error-prone to do manually every release.
Happy path critical flows (login, checkout)Always automateMust run on every build. Automation catches regressions immediately.
Edge case business logicAutomate as unit testsFast, precise, and documents the expected behavior.
Visual / UI aesthetics reviewManual (+ visual diffing tools)Pixel differences require human aesthetic judgment. Tools like Percy help flag changes.
Exploratory testing of new featuresManualHuman creativity finds unexpected paths that scripted tests cannot predict.
Accessibility review with screen readersHybridAutomated checks flag obvious issues; manual testing with VoiceOver/TalkBack is required.
Usability / UX assessmentManual (user testing)No tool can assess whether UX is intuitive — requires real user observation.
Complex multi-step payment flowsAutomate in test modeUse sandbox credentials. Automate the flow but do not test with real payment methods.
Device-specific hardware features (camera, GPS)Manual on real devicesSimulators cannot accurately replicate hardware sensors.
When Automation Pays Off
  • Tests that run on every commit (regression suite)
  • Tests across many device/OS combinations
  • Data-driven tests with many input variations
  • Long-running stability and soak tests
  • Tests that require precise timing or speed
When Manual Testing is Irreplaceable
  • First-time UX review of new features
  • Hardware integration (camera, NFC, biometrics)
  • Accessibility testing with real assistive technology
  • Exploratory testing to find unexpected edge cases
  • User acceptance testing before major releases

CI/CD for Mobile Apps

Mobile CI/CD has unique challenges vs web: builds are slow, Apple requires macOS agents, code signing is complex, and distributing to devices requires platform-specific tools. Here is a production-ready pipeline structure.

GitHub Actions — React Native CI Pipeline

# .github/workflows/mobile-ci.yml
name: Mobile CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  # ── Unit & Integration Tests (fast, runs on every PR) ──
  unit-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20', cache: 'yarn' }
      - run: yarn install --frozen-lockfile
      - run: yarn test --coverage --ci
      - uses: codecov/codecov-action@v4

  # ── iOS E2E Tests (slow, runs on main branch merges) ──
  ios-e2e:
    runs-on: macos-14  # Apple Silicon runner
    needs: unit-tests
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20', cache: 'yarn' }
      - run: yarn install --frozen-lockfile

      - name: Install Detox CLI
        run: yarn global add detox-cli

      - name: Install pods
        run: cd ios && pod install

      - name: Build for testing
        run: detox build --configuration ios.sim.release

      - name: Run Detox E2E tests
        run: detox test --configuration ios.sim.release --cleanup
        env:
          TEST_USER_PASSWORD: ${{ secrets.TEST_USER_PASSWORD }}

      - name: Upload Detox artifacts on failure
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: detox-artifacts-ios
          path: artifacts/

  # ── Android E2E on Firebase Test Lab ──
  android-e2e:
    runs-on: ubuntu-latest
    needs: unit-tests
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with: { java-version: '17', distribution: 'temurin' }

      - name: Build Android APKs
        run: |
          cd android
          ./gradlew assembleDebug assembleAndroidTest

      - uses: google-github-actions/auth@v2
        with:
          credentials_json: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}

      - name: Run on Firebase Test Lab
        run: |
          gcloud firebase test android run \
            --type instrumentation \
            --app android/app/build/outputs/apk/debug/app-debug.apk \
            --test android/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk \
            --device model=Pixel7,version=33 \
            --use-orchestrator

Mobile CI/CD Platform Comparison

Bitrise
From $45/mo for 1 concurrency; dedicated macOS machines on higher tiers
Best for: Teams wanting a mobile-first CI/CD service with minimal setup

Pre-built steps for iOS code signing, Fastlane, Firebase, App Store Connect. macOS machines included. Mobile-specific caching for CocoaPods and Gradle.

Xcode Cloud
Free (25 compute hours/mo) with Apple Developer Program; additional compute from $14.99/mo
Best for: Native iOS/macOS apps staying entirely in the Apple ecosystem

Deep Xcode integration, free with Apple Developer membership (limited compute), TestFlight distribution built-in, automatic code signing via Xcode managed profiles.

GitHub Actions (self-hosted macOS)
GitHub Actions free minutes + self-hosted runner cost (~$75–150/mo for a Mac mini)
Best for: Teams already using GitHub who want full control

Full GitHub ecosystem integration, unlimited customization, no vendor lock-in. Requires self-hosted macOS runners (use MacStadium, MacMini.cloud, or your own hardware) for iOS builds.

Fastlane (cross-platform automation)
Free and open source
Best for: Automating code signing, versioning, and app store distribution in any CI

Not a CI platform — a toolchain of lanes for build, test, sign, and deploy automation. match (certificate sync), deliver (App Store upload), supply (Play Store upload). Runs in any CI environment.

Crash Reporting & Performance Monitoring

Testing catches the bugs you know to look for. Crash reporting catches everything else — the edge cases that only surface with real users on real devices in the real world. Set it up before your first TestFlight or Play Store release.

Sentry
Crash reporting + JS error tracking + performance

The best overall choice for React Native. Captures both native crashes (iOS/Android) and JavaScript errors with full React component stack traces. Automatically deobfuscates source maps so stack traces point to your actual source code, not minified bundles. Groups similar errors into issues, tracks error frequency and affected user count, and integrates with Slack, Jira, and GitHub.

Quick setup: yarn add @sentry/react-native then Sentry.init() in your entry file. Run sentry-cli sourcemaps inject in your build script.
Firebase Crashlytics
Native crash reporting (free)

Google's free, best-in-class native crash reporter. Excellent for native iOS and Android crash symbolication with minimal setup. Integrates seamlessly with Firebase Analytics to correlate crashes with user segments, app versions, and custom events. Does not capture JavaScript errors in React Native without additional setup.

Quick setup: Add @react-native-firebase/crashlytics package. iOS: add GoogleService-Info.plist. Android: add google-services.json and apply the Crashlytics Gradle plugin.
Datadog Mobile RUM
Full observability: crashes + performance + user sessions

For teams already using Datadog for backend observability, the Mobile RUM SDK provides end-to-end visibility: crash reports, performance traces, user session replay, and network request tracking — all correlated in a single platform. Expensive but eliminates context switching between tools.

Quick setup: yarn add @datadog/mobile-react-native and configure with your Datadog client token and application ID.

Sentry Setup for React Native

// App.tsx — Sentry initialization
import * as Sentry from '@sentry/react-native';

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: __DEV__ ? 'development' : 'production',
  tracesSampleRate: 0.2,        // 20% of sessions traced
  profilesSampleRate: 0.1,      // 10% of traced sessions profiled
  attachScreenshot: true,       // Attach screenshot on error
  attachViewHierarchy: true,    // Attach view hierarchy on error

  beforeSend(event) {
    // Filter out events you do not care about
    if (event.exception?.values?.[0]?.type === 'NetworkError') {
      return null; // Do not send network errors
    }
    return event;
  },
});

// Wrap your root component for automatic error boundaries
export default Sentry.wrap(App);

// Manual error capture with context
try {
  await processPayment(cart);
} catch (error) {
  Sentry.withScope((scope) => {
    scope.setUser({ id: user.id });
    scope.setTag('flow', 'checkout');
    scope.setContext('cart', { items: cart.length, total: cart.total });
    Sentry.captureException(error);
  });
  throw error;
}

Beta Testing Strategy

Beta testing is the bridge between internal QA and public release. It exposes your app to real users in real environments before it reaches your entire user base. A structured beta program catches the issues that no amount of internal testing finds.

TestFlight (iOS)

Apple's official beta distribution platform. Internal testers (up to 100) can receive builds within minutes of upload. External testers (up to 10,000) receive builds after a one-time Apple review (~24–48 hours). Testers receive crash reports automatically. No additional app required. Essential for any iOS app.

Strategy tip: Use build groups to segment internal team, trusted power users, and general beta testers. Distribute different feature builds to different groups.
Google Play Internal Testing / Beta

Google Play offers internal testing (up to 100 testers, immediate), closed beta (invite via email or link), and open beta (anyone can opt in) tracks. Builds are published via the Play Console. Testers can submit feedback via the Play Store. ANR and crash reports flow into the Play Console.

Strategy tip: Use the staged rollout feature for production releases — roll out to 10% of users first, monitor crash rates and ANRs, then expand to 100%.
Firebase App Distribution

Cross-platform beta distribution for both iOS and Android. Distribute any build (debug or release) to testers via email or a shareable link, without requiring App Store or Play Store submission. Integrates with Fastlane and CI/CD pipelines for automatic distribution after every successful build.

Strategy tip: Combine with Firebase Crashlytics for automatic crash reports from beta testers, correlated with the specific build they installed.
Building a Great Beta Tester Community
Recruit diverse device owners

Target testers with older Android devices and less common screen sizes — they surface the most compatibility issues.

Set clear expectations

Tell testers what you need: crash reports, specific feature feedback, or performance observations. Vague requests get vague feedback.

Make feedback frictionless

Use Shake, Instabug, or a simple in-app feedback button. Testers who have to send an email rarely do.

Reward participation

Early access to features, premium perks, or public acknowledgement increases beta program retention and feedback quality.

Pre-Launch QA Checklist

Use this checklist before every major public release. A green checkmark on all items does not guarantee a bug-free launch, but it dramatically reduces the risk of the most common and damaging launch failures.

Functionality
  • All critical user flows tested end-to-end on real iOS and Android devices
  • Authentication: sign up, sign in, sign out, password reset, OAuth flows
  • Payment or subscription flows tested in sandbox mode
  • Push notifications received and tap-to-open works correctly
  • Deep links open the correct screen from email, SMS, and other apps
  • Offline mode: app degrades gracefully with no network connection
  • App recovers correctly when connection is restored
  • Data persists correctly across app close and re-open
  • All form validation messages are accurate and helpful
Performance
  • Cold start time under 3 seconds on a mid-range Android device
  • No visible jank (dropped frames) during navigation or list scrolling
  • Memory usage stable over 15 minutes of active use (no upward drift)
  • App does not consume excessive battery in the background
  • Images load within 2 seconds on a 4G connection
  • API response times acceptable under normal conditions
Compatibility
  • Tested on iOS 16, 17, and 18 (or current minus two major versions)
  • Tested on Android API 29–35 (Android 10–15)
  • Tested on small (SE/compact), standard, and large screen sizes
  • Works in both portrait and landscape orientation (or locks correctly)
  • Works with system text size set to largest accessibility size
  • Works in dark mode and light mode
  • Correct behavior with reduced motion setting enabled
  • Tested with flaky network (Network Link Conditioner)
Security
  • No API keys, secrets, or credentials hardcoded in the binary
  • All API calls use HTTPS (no HTTP allowed in production)
  • Certificate pinning implemented for sensitive endpoints (banking, health)
  • Sensitive data (tokens, PII) stored in Keychain (iOS) or EncryptedSharedPreferences (Android), not AsyncStorage
  • Screenshots disabled on payment screens (iOS: set isSecureTextEntry, Android: FLAG_SECURE)
  • App passes basic OWASP Mobile Top 10 review
Accessibility
  • All interactive elements have meaningful accessibility labels
  • VoiceOver (iOS) can navigate the full app without getting stuck
  • TalkBack (Android) announces all interactive elements correctly
  • Color contrast ratio meets WCAG 2.1 AA (4.5:1 for normal text)
  • Touch targets are at least 44x44pt (iOS) / 48x48dp (Android)
  • No information conveyed by color alone
App Store Requirements
  • All required permissions have clear usage descriptions (iOS Privacy Manifests)
  • App does not access Contacts, Camera, or Location without requesting permission first
  • Privacy policy URL valid and up to date in store listing
  • App Store screenshots and preview match the current UI
  • Age rating accurately reflects content
  • In-app purchases use the platform payment system (no external payment links for digital goods)

Frequently Asked Questions

Need Help Building a QA Strategy for Your App?

Codazz builds mobile apps with production-grade testing from day one — automated E2E suites, CI/CD pipelines, crash reporting, and beta programs that catch issues before your users do.