This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.

使用 Jest 进行单元测试

编辑页面

了解如何设置和配置 jest-expo 库,以使用 Jest 为你的项目编写单元测试和快照测试。


Jest 是使用最广泛的 JavaScript 单元测试和快照测试框架。在本指南中,你将学习如何在项目中设置 Jest、编写单元测试、编写快照测试,以及在 React Native 中使用 Jest 时组织测试的最佳实践。

你还将使用 jest-expo 库,它是一个 Jest 预设,用于模拟 Expo SDK 的原生部分,并处理 Expo 项目所需的大部分配置。

安装和配置

创建 Expo 项目后,请按照以下说明在项目中安装并配置 jest-expo

1

在项目中安装 jest-expo 和其他必需的开发依赖。从项目根目录运行以下命令:

Terminal
npx expo install jest-expo jest @types/jest --dev

如果你的项目使用 TypeScript,请将 "jest" 添加到 tsconfig.json 中的 types 数组,以启用 Jest 的类型定义:

tsconfig.json
{ "compilerOptions": { "types": ["jest"] } }

2

打开 package.json,添加一个用于运行测试的脚本,并添加用于使用 jest-expo 基础配置的预设:

package.json
{ "scripts": { "test": "jest --watchAll" %%placeholder-start%%... %%placeholder-end%%}, "jest": { "preset": "jest-expo" } }

3

package.json 中添加 jest-expo 作为预设,以便为 Jest 的配置建立基础:

package.json
{ "jest": { "preset": "jest-expo" } }
使用 transformIgnorePatterns 的附加配置

你可以通过在 package.json 中配置 transformIgnorePatterns 来转换项目使用的 node_modules。这个属性的值是一个正则表达式模式:

package.json
"jest": { "preset": "jest-expo", "transformIgnorePatterns": [ "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg)" ] }

Jest 有许多配置选项,但以上配置应能满足你大部分需求。不过,你始终可以继续向这个模式列表中添加内容。更多详情请参阅 配置 Jest

安装 React Native Testing Library

React Native Testing Library (@testing-library/react-native) 是一个用于测试 React Native 组件的轻量级方案。它提供实用函数,并与 Jest 配合使用。

要安装它,请运行以下命令:

Terminal
npx expo install @testing-library/react-native --dev

单元测试

单元测试用于检查最小的代码单元,通常是一个函数。要编写你的第一个单元测试,请看下面的示例:

1

在项目的 src/app 目录中,创建一个名为 index.tsx 的新文件,并添加以下代码来渲染一个简单组件:

index.tsx
import { PropsWithChildren } from 'react'; import { StyleSheet, Text, View } from 'react-native'; export const CustomText = ({ children }: PropsWithChildren) => <Text>{children}</Text>; export default function HomeScreen() { return ( <View style={styles.container}> <CustomText>欢迎!</CustomText> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });

2

在项目根目录创建一个 tests 目录。如果项目中已经存在这个目录,就使用现有目录。然后创建一个名为 home-screen-test.tsx 的新文件。jest-expo 预设会自定义 Jest 配置,使其也能将带有 -test.ts|tsx 扩展名的文件识别为测试。

home-screen-test.tsx 中添加以下示例代码:

home-screen-test.tsx
import { render } from '@testing-library/react-native'; import HomeScreen, { CustomText } from '@/app/index'; describe('<HomeScreen />', () => { test('Text renders correctly on HomeScreen', async () => { const { getByText } = await render(<HomeScreen />); getByText('Welcome!'); }); });

在上面的示例中,getByText 查询帮助你的测试在应用的用户界面中找到相关元素,并断言某个元素是否存在。React Native Testing Library 提供了这个查询,而且每种 查询变体 的返回类型都不同。更多示例和详细 API 信息,请参阅 React Native Testing Library 的 查询 API 参考

3

在终端窗口中运行以下命令来执行测试:

Terminal
npm run test

你会看到一个测试通过。

组织测试结构

整理测试文件很重要,这样更便于维护。一个常见模式是创建一个 tests 目录,并将所有测试放在其中。

下面展示了一个与 components 目录并列的测试结构示例:

__tests__
themed-text-test.tsx
src
components
  themed-text.tsx
  themed-view.tsx

或者,你也可以为项目的不同区域设置多个 tests 子目录。例如,为 components 单独创建一个测试目录,等等:

src
components
  themed-text.tsx
  __tests__
   themed-text-test.tsx
utils
  index.tsx
  __tests__
   index-test.tsx

这完全取决于你的偏好,由你来决定如何组织项目目录。

快照测试

快照测试 用于确保 UI 保持一致,尤其是在项目使用可能在各组件之间共享的全局样式时。

要为 <HomeScreen /> 添加快照测试,请在 home-screen-test.tsx 中的 describe() 内添加以下代码片段:

home-screen-test.tsx
describe('<HomeScreen />', () => { %%placeholder-start%%... %%placeholder-end%% test('CustomText renders correctly', async () => { const tree = (await render(<CustomText>Some text</CustomText>)).toJSON(); expect(tree).toMatchSnapshot(); }); });

运行 npm run test 命令后,你会看到在 tests\snapshots 目录中创建了一个快照,并且有两个测试通过。

代码覆盖率报告

代码覆盖率报告可以帮助你了解有多少代码得到了测试。要以 HTML 格式查看项目中的代码覆盖率报告,请在 package.jsonjest 下将 collectCoverage 设置为 true,并使用 collectCoverageFrom 指定在收集覆盖率时要忽略的文件列表。

package.json
"jest": { ... "collectCoverage": true, "collectCoverageFrom": [ "**/*.{ts,tsx,js,jsx}", "!**/coverage/**", "!**/node_modules/**", "!**/babel.config.js", "!**/expo-env.d.ts", "!**/.expo/**" ] }

运行 npm run test。你会看到项目中创建了一个 coverage 目录。找到 lcov-report/index.html 并在浏览器中打开它以查看覆盖率报告。

Jest 流程(可选)

你也可以使用不同的流程来运行测试。下面是一些你可以尝试的示例脚本:

package.json
"scripts": { "test": "jest --watch --coverage=false --changedSince=origin/main", "testDebug": "jest -o --watch --coverage=false", "testFinal": "jest", "updateSnapshots": "jest -u --coverage=false" %%placeholder-start%%... %%placeholder-end%% }

更多信息请参阅 Jest 文档中的 CLI 选项

其他信息

React Native Testing Library 文档

查看 React Native Testing Library 文档,它提供测试工具并鼓励良好的测试实践,并与 Jest 配合使用。

Expo Router 的测试配置

了解在使用 Expo Router 时如何为你的应用创建集成测试。

使用 EAS Workflows 的 E2E 测试

了解如何使用 Maestro 在 EAS Workflows 上设置并运行 E2E 测试。