[ PROMPT_NODE_23369 ]
Mobile Testing
[ SKILL_DOCUMENTATION ]
# Mobile Testing Patterns
> **Mobile testing is NOT web testing. Different constraints, different strategies.**
> This file teaches WHEN to use each testing approach and WHY.
> **Code examples are minimal - focus on decision-making.**
---
## ? MOBILE TESTING MINDSET
```
Mobile testing differs from web:
├── Real devices matter (emulators hide bugs)
├── Platform differences (iOS vs Android behavior)
├── Network conditions vary wildly
├── Battery/performance under test
├── App lifecycle (background, killed, restored)
├── Permissions and system dialogs
└── Touch interactions vs clicks
```
---
## ? AI MOBILE TESTING ANTI-PATTERNS
| ❌ AI Default | Why It's Wrong | ✅ Mobile-Correct |
|---------------|----------------|-------------------|
| Jest-only testing | Misses native layer | Jest + E2E on device |
| Enzyme patterns | Deprecated, web-focused | React Native Testing Library |
| Browser-based E2E (Cypress) | Can't test native features | Detox / Maestro |
| Mock everything | Misses integration bugs | Real device testing |
| Ignore platform tests | iOS/Android differ | Platform-specific cases |
| Skip performance tests | Mobile perf is critical | Profile on low-end device |
| Test only happy path | Mobile has more edge cases | Offline, permissions, interrupts |
| 100% unit test coverage | False security | Pyramid balance |
| Copy web testing patterns | Different environment | Mobile-specific tools |
---
## 1. Testing Tool Selection
### Decision Tree
```
WHAT ARE YOU TESTING?
│
├── Pure functions, utilities, helpers
│ └── Jest (unit tests)
│ └── No special mobile setup needed
│
├── Individual components (isolated)
│ ├── React Native → React Native Testing Library
│ └── Flutter → flutter_test (widget tests)
│
├── Components with hooks, context, navigation
│ ├── React Native → RNTL + mocked providers
│ └── Flutter → integration_test package
│
├── Full user flows (login, checkout, etc.)
│ ├── Detox (React Native, fast, reliable)
│ ├── Maestro (Cross-platform, YAML-based)
│ └── Appium (Legacy, slow, last resort)
│
└── Performance, memory, battery
├── Flashlight (RN performance)
├── Flutter DevTools
└── Real device profiling (Xcode/Android Studio)
```
### Tool Comparison
| Tool | Platform | Speed | Reliability | Use When |
|------|----------|-------|-------------|----------|
| **Jest** | RN | ⚡⚡⚡ | ⚡⚡⚡ | Unit tests, logic |
| **RNTL** | RN | ⚡⚡⚡ | ⚡⚡ | Component tests |
| **flutter_test** | Flutter | ⚡⚡⚡ | ⚡⚡⚡ | Widget tests |
| **Detox** | RN | ⚡⚡ | ⚡⚡⚡ | E2E, critical flows |
| **Maestro** | Both | ⚡⚡ | ⚡⚡ | E2E, cross-platform |
| **Appium** | Both | ⚡ | ⚡ | Legacy, last resort |
---
## 2. Testing Pyramid for Mobile
```
┌───────────────┐
│ E2E Tests │ 10%
│ (Real device) │ Slow, expensive, essential
├───────────────┤
│ Integration │ 20%
│ Tests │ Component + context
├───────────────┤
│ Component │ 30%
│ Tests │ Isolated UI
├───────────────┤
│ Unit Tests │ 40%
│ (Jest) │ Pure logic
└───────────────┘
```
### Why This Distribution?
| Level | Why This % |
|-------|------------|
| **E2E 10%** | Slow, flaky, but catches integration bugs |
| **Integration 20%** | Tests real user flows without full app |
| **Component 30%** | Fast feedback on UI changes |
| **Unit 40%** | Fastest, most stable, logic coverage |
> ? **If you have 90% unit tests and 0% E2E, you're testing the wrong things.**
---
## 3. What to Test at Each Level
### Unit Tests (Jest)
```
✅ TEST:
├── Utility functions (formatDate, calculatePrice)
├── State reducers (Redux, Zustand stores)
├── API response transformers
├── Validation logic
└── Business rules
❌ DON'T TEST:
├── Component rendering (use component tests)
├── Navigation (use integration tests)
├── Native modules (mock them)
└── Third-party libraries
```
### Component Tests (RNTL / flutter_test)
```
✅ TEST:
├── Component renders correctly
├── User interactions (tap, type, swipe)
├── Loading/error/empty states
├── Accessibility labels exist
└── Props change behavior
❌ DON'T TEST:
├── Internal implementation details
├── Snapshot everything (only key components)
├── Styling specifics (brittle)
└── Third-party component internals
```
### Integration Tests
```
✅ TEST:
├── Form submission flows
├── Navigation between screens
├── State persistence across screens
├── API integration (with mocked server)
└── Context/provider interactions
❌ DON'T TEST:
├── Every possible path (use unit tests)
├── Third-party services (mock them)
└── Backend logic (backend tests)
```
### E2E Tests
```
✅ TEST:
├── Critical user journeys (login, purchase, signup)
├── Offline → online transitions
├── Deep link handling
├── Push notification navigation
├── Permission flows
└── Payment flows
❌ DON'T TEST:
├── Every edge case (too slow)
├── Visual regression (use snapshot tests)
├── Non-critical features
└── Backend-only logic
```
---
## 4. Platform-Specific Testing
### What Differs Between iOS and Android?
| Area | iOS Behavior | Android Behavior | Test Both? |
|------|--------------|------------------|------------|
| **Back navigation** | Edge swipe | System back button | ✅ YES |
| **Permissions** | Ask once, settings | Ask each time, rationale | ✅ YES |
| **Keyboard** | Different appearance | Different behavior | ✅ YES |
| **Date picker** | Wheel/modal | Material dialog | ⚠️ If custom UI |
| **Push format** | APNs payload | FCM payload | ✅ YES |
| **Deep links** | Universal Links | App Links | ✅ YES |
| **Gestures** | Some unique | Material gestures | ⚠️ If custom |
### Platform Testing Strategy
```
FOR EACH PLATFORM:
├── Run unit tests (same on both)
├── Run component tests (same on both)
├── Run E2E on REAL DEVICE
│ ├── iOS: iPhone (not just simulator)
│ └── Android: Mid-range device (not flagship)
└── Test platform-specific features separately
```
---
## 5. Offline & Network Testing
### Offline Scenarios to Test
| Scenario | What to Verify |
|----------|----------------|
| Start app offline | Shows cached data or offline message |
| Go offline mid-action | Action queued, not lost |
| Come back online | Queue synced, no duplicates |
| Slow network (2G) | Loading states, timeouts work |
| Flaky network | Retry logic, error recovery |
### How to Test Network Conditions
```
APPROACH:
├── Unit tests: Mock NetInfo, test logic
├── Integration: Mock API responses, test UI
├── E2E (Detox): Use device.setURLBlacklist()
├── E2E (Maestro): Use network conditions
└── Manual: Use Charles Proxy / Network Link Conditioner
```
---
## 6. Performance Testing
### What to Measure
| Metric | Target | How to Measure |
|--------|--------|----------------|
| **App startup** | < 2 seconds | Profiler, Flashlight |
| **Screen transition** | **Remember:** Good mobile testing is about testing the RIGHT things, not EVERYTHING. A flaky E2E test is worse than no test. A failing unit test that catches a bug is worth 100 passing trivial tests.
Source: claude-code-templates (MIT). See About Us for full credits.