- Types of Testing
- Android-Specific Testing
- Automation Frameworks & Tools
- Performance Testing
- Battery & Power Testing
- Graphics & UI Testing
- Modem & Connectivity Testing
- Advanced Testing Concepts
- Best Practices & Tips
-
Unit Testing
- JUnit for Java components
- Robolectric for Android-specific unit tests
- MockK for Kotlin mocking
- Tips: Use
@SmallTestannotation, keep tests isolated
-
Integration Testing
- Testing component interactions
- Database integration tests
- Content provider testing
- Service integration testing
-
System Testing
- End-to-end scenarios
- Cross-app interactions
- System permissions testing
- Hardware integration testing
-
Acceptance Testing
- User acceptance testing (UAT)
- Beta testing
- Field testing
- Dogfooding
-
Performance Testing
- Startup time
- Frame rate (FPS)
- Memory usage
- CPU utilization
- Network performance
- Storage I/O
-
Security Testing
- Penetration testing
- Vulnerability scanning
- Permission model testing
- Data encryption verification
- Secure communication testing
@Test
def test_activity_lifecycle():
# Launch activity
scenario = ActivityScenario.launch(MainActivity::class.java)
# Test different states
scenario.moveToState(State.CREATED)
scenario.moveToState(State.STARTED)
scenario.moveToState(State.RESUMED)
# Verify state
scenario.onActivity { activity ->
assertTrue(activity.isResumed())
}- Fragment scenarios
- Navigation testing
- Configuration change handling
- State preservation testing
- Implicit intents
- Explicit intents
- Intent filters
- Deep linking validation
-
Espresso
- View matchers
- View actions
- View assertions
- IdlingResources for async operations
-
UI Automator
- System UI testing
- Cross-app testing
- Device-level interactions
-
Appium
- Cross-platform testing
- Real device testing
- Cloud device farm integration
def measure_startup_time():
"""
Measures cold and warm start times
"""
adb shell am force-stop com.example.app
start_time = time.time()
# Launch app
subprocess.run(['adb', 'shell', 'am', 'start-activity',
'com.example.app/.MainActivity'])
# Wait for launch complete
while not check_activity_resumed():
if time.time() - start_time > TIMEOUT:
raise TimeoutError("App launch timeout")
return time.time() - start_time-
Startup Performance
- Cold start time
- Warm start time
- Hot start time
- Time to first frame
-
Runtime Performance
- Frame time
- Jank detection
- Memory leaks
- Battery consumption
- Network efficiency
# Capture traces
adb shell perfetto -c /data/misc/perfetto-configs/config.pb -o /data/misc/perfetto-traces/trace.perfetto-trace
# Analyze memory
adb shell dumpsys meminfo package_name
# Check battery stats
adb shell dumpsys batterystats
# Monitor frame metrics
adb shell dumpsys gfxinfo package_name-
Screen-on Tests
- Different brightness levels
- Various refresh rates
- Content types (static vs dynamic)
-
Background Operations
- Background service impact
- Wake lock usage
- Network activity
- Location updates
-
Doze Mode Testing
- App standby buckets
- Background restrictions
- Whitelist behavior
class BatteryTest:
def setup(self):
# Disable auto-brightness
subprocess.run(['adb', 'shell', 'settings', 'put', 'system',
'screen_brightness_mode', '0'])
# Set specific brightness
subprocess.run(['adb', 'shell', 'settings', 'put', 'system',
'screen_brightness', '128'])
def measure_battery_drain(self, duration_minutes):
# Get initial battery level
initial = self.get_battery_level()
# Run test scenario
time.sleep(duration_minutes * 60)
# Get final battery level
final = self.get_battery_level()
return {
'drain_percentage': initial - final,
'drain_rate': (initial - final) / duration_minutes
}- Frame timing
- GPU utilization
- Texture memory usage
- Overdraw analysis
- Layout performance
-
GPU Rendering Analysis
- Profile GPU rendering
- Debug GPU overdraw
- Systrace analysis
-
Layout Inspector
- View hierarchy analysis
- Layout performance
- Memory impact
-
Network Types
- 2G/3G/4G/5G transitions
- WiFi handling
- Bluetooth operations
- NFC testing
-
Network Conditions
- Poor connectivity
- High latency
- Packet loss
- Network transitions
def test_network_transitions():
"""
Tests app behavior during network changes
"""
# Enable airplane mode
subprocess.run(['adb', 'shell', 'settings', 'put', 'global',
'airplane_mode_on', '1'])
# Broadcast change
subprocess.run(['adb', 'shell', 'am', 'broadcast', '-a',
'android.intent.action.AIRPLANE_MODE'])
# Verify app behavior
check_app_state()
# Disable airplane mode
subprocess.run(['adb', 'shell', 'settings', 'put', 'global',
'airplane_mode_on', '0'])def run_monkey_test():
"""
Runs monkey test with specific parameters
"""
cmd = [
'adb', 'shell', 'monkey',
'-p', 'com.example.app',
'--throttle', '500',
'-v', '-v',
'--ignore-crashes',
'--ignore-timeouts',
'--monitor-native-crashes',
'10000'
]
subprocess.run(cmd)-
CI/CD Integration
- Jenkins pipeline setup
- GitHub Actions integration
- Test automation triggers
- Report generation
-
Test Coverage
- Code coverage metrics
- Feature coverage tracking
- Risk-based testing
- Regression coverage
-
Test Planning
- Risk assessment
- Test prioritization
- Resource allocation
- Timeline planning
-
Test Design
- Boundary value analysis
- Equivalence partitioning
- State transition testing
- Error guessing
-
Performance Testing
- Always test on low-end devices
- Use strict mode in development
- Monitor ANR situations
- Track startup performance
-
Battery Testing
- Test with different battery levels
- Monitor wake locks
- Check background operations
- Validate doze mode behavior
-
Automation
- Use page object pattern
- Implement robust waits
- Handle flaky tests
- Maintain test data
-
Testing Efficiency
- Use
testOnlybuild variant - Enable developer options
- Use shell commands for quick testing
- Leverage monkey testing effectively
- Use
-
Debug Techniques
- Use layout bounds
- Enable strict mode
- Track overdraw
- Monitor memory allocations