Testing Mobile Apps
Testing is crucial for building reliable mobile apps. Let's explore the different types of tests and how to write them in both React Native and Flutter.
Types of Tests
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Testing Pyramid β
βββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β β±β² β
β β± β² β
β β± E2Eβ² End-to-End Tests β
β β±βββββββ² (Few, slow, expensive) β
β β± β² β
β β±Integrationβ² Integration Tests β
β β±βββββββββββββββ² (Some, medium) β
β β± β² β
β β± Unit Tests β² Unit Tests β
β β±βββββββββββββββββββββ² (Many, fast) β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
React Native: Jest Tests
// __tests__/UserCard.test.js
import React from 'react';
import { render } from '@testing-library/react-native';
import UserCard from '../components/UserCard';
describe('UserCard', () => {
it('renders user name correctly', () => {
const { getByText } = render(
<UserCard name="John Doe" email="john@example.com" />
);
expect(getByText('John Doe')).toBeTruthy();
});
it('renders user email correctly', () => {
const { getByText } = render(
<UserCard name="John Doe" email="john@example.com" />
);
expect(getByText('john@example.com')).toBeTruthy();
});
it('calls onPress when tapped', () => {
const mockOnPress = jest.fn();
const { getByText } = render(
<UserCard name="John Doe" onPress={mockOnPress} />
);
fireEvent.press(getByText('John Doe'));
expect(mockOnPress).toHaveBeenCalledTimes(1);
});
});
Flutter: Widget Tests
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:my_app/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame
await tester.pumpWidget(MyApp());
// Verify counter starts at 0
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify counter incremented
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
testWidgets('App displays title', (WidgetTester tester) async {
await tester.pumpWidget(MyApp());
expect(find.text('My App'), findsOneWidget);
});
}
Testing Best Practices
- Write tests early: TDD helps catch bugs before they happen
- Test user interactions: Focus on what users actually do
- Mock external dependencies: Don't rely on real APIs or databases
- Use descriptive names: Tests should document expected behavior
- Test edge cases: Empty states, errors, loading states