写在前面:为什么你的 React Native 应用需要自动化测试?
想象一下:你刚发布了一个新版本,用户反馈登录页面崩溃了。你紧急修复,重新打包,App Store 审核等了 3 天,终于上线——结果另一个隐藏 Bug 又炸了……
如果能提前发现这些问题呢?
自动化测试就是你的“代码保镖”,它能在你提交代码时自动检查逻辑错误、UI 错位、性能问题,甚至模拟用户操作,确保每次改动不会破坏已有功能。
本篇将带你从 单元测试 到 E2E 测试,再到 CI/CD 集成,构建一个坚如磐石的 React Native 测试体系。
1. React Native 测试金字塔:该测什么?怎么测?
测试策略遵循经典的 测试金字塔(Test Pyramid):
- 单元测试(Unit Tests) - 测试独立函数、工具类
- 组件测试(Component Tests) - 测试 React 组件渲染 & 交互
- 集成测试(Integration Tests) - 测试多个组件协作
- 端到端测试(E2E Tests) - 模拟真实用户操作
📌 黄金法则:
- 底层测试(单元/组件)要快、多、稳定(80% 覆盖率)
- 高层测试(E2E)要少而精(核心业务流程)
2. 单元测试:Jest + React Testing Library
(1)配置 Jest
React Native 默认支持 Jest,只需在 package.json
中配置:
{
"jest": {
"preset": "react-native",
"setupFilesAfterEnv": ["@testing-library/jest-native/extend-expect"]
}
}
(2)测试工具函数
假设有一个 utils.js
:
export const sum = (a, b) => a + b;
测试文件 utils.test.js
:
import { sum } from './utils';
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
运行测试:
npm test
(3)测试 React 组件
安装依赖:
npm install @testing-library/react-native
测试一个 Button
组件:
import { render, fireEvent } from '@testing-library/react-native';
import Button from '../Button';
test('Button calls onPress', () => {
const mockFn = jest.fn();
const { getByText } = render(<Button onPress={mockFn} title="Click Me" />);
fireEvent.press(getByText('Click Me'));
expect(mockFn).toHaveBeenCalled();
});
📌 关键点:
render
渲染组件fireEvent
模拟用户交互jest.fn()
创建 mock 函数
3. 组件快照测试:防止 UI 意外更改
快照测试会记录组件渲染的 HTML 结构,后续测试对比是否有意外改动。
import renderer from 'react-test-renderer';
import Button from '../Button';
test('Button renders correctly', () => {
const tree = renderer.create(<Button title="Submit" />).toJSON();
expect(tree).toMatchSnapshot();
});
如果组件 UI 有变化,运行 npm test -- -u
更新快照。
4. 集成测试:测试 Redux / API 调用
(1)Mock API 请求(axios/fetch)
使用 jest.mock
模拟 API:
import { render, waitFor } from '@testing-library/react-native';
import UserList from '../UserList';
jest.mock('axios');
test('UserList fetches and displays users', async () => {
axios.get.mockResolvedValue({ data: [{ id: 1, name: 'John' }] });
const { getByText } = render(<UserList />);
await waitFor(() => {
expect(getByText('John')).toBeTruthy();
});
});
(2)测试 Redux 状态
安装 redux-mock-store
:
npm install redux-mock-store
测试 Redux action:
import configureStore from 'redux-mock-store';
import { fetchUsers } from '../userActions';
const mockStore = configureStore([]);
test('fetchUsers dispatches correct action', () => {
const store = mockStore({});
store.dispatch(fetchUsers());
const actions = store.getActions();
expect(actions[0].type).toBe('FETCH_USERS_REQUEST');
});
5. E2E 测试:Detox(跨平台 UI 自动化)
Detox 是 React Native 最流行的 E2E 测试框架,支持 iOS/Android。
(1)安装 & 配置
npm install detox --save-dev
npx detox init
在 package.json
添加脚本:
{
"scripts": {
"test:e2e": "detox test",
"build:e2e": "detox build"
}
}
(2)编写 E2E 测试
测试登录流程:
describe('Login Flow', () => {
beforeAll(async () => {
await device.launchApp();
});
it('should login successfully', async () => {
await element(by.id('emailInput')).typeText('test@example.com');
await element(by.id('passwordInput')).typeText('password123');
await element(by.id('loginButton')).tap();
await expect(element(by.text('Welcome'))).toBeVisible();
});
});
(3)运行测试
# iOS 模拟器
detox build --configuration ios.simulator
detox test --configuration ios.simulator
# Android 模拟器
detox build --configuration android.emu
detox test --configuration android.emu
6. CI/CD 集成(GitHub Actions / Bitrise)
(1)GitHub Actions 配置
创建 .github/workflows/e2e.yml
:
name: E2E Tests
on: [push]
jobs:
test:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v2
- run: npm install
- run: npm run build:e2e
- run: npm run test:e2e
(2)Bitrise(移动端 CI)
- 在 Bitrise 创建项目
- 添加
Script
步骤运行detox test
- 配置模拟器环境
7. 最佳实践 & 常见坑
✅ DO
- 单元测试覆盖工具函数、业务逻辑
- E2E 测试核心用户流(登录、支付)
- 在 CI 里自动运行测试
❌ DON’T
- 过度依赖快照测试(容易误报)
- E2E 测试所有细节(慢且脆弱)
- 忽略 Android/iOS 差异(Detox 需双端测试)
总结:你的 React Native 测试策略
- 单元测试(Jest + React Testing Library)→ 确保函数逻辑正确
- 组件测试 → 检查 UI 渲染 & 交互
- 集成测试 → 验证 API/Redux 交互
- E2E 测试(Detox)→ 模拟真实用户操作
- CI/CD 集成 → 每次提交自动测试
📌 终极目标:每次提交代码时,都能自信地说:“这个版本绝对没问题!”
如果觉得写的不错,请动动手指点赞、关注、评论哦
如有疑问,可以评论区留言~