在使用 React Native 进行前端开发时,测试是一个不可避免的问题。而 Enzyme 是一个流行的 React 测试工具,它提供了许多方便的 API 来测试 React 组件。然而,Enzyme 在 React Native 上的适配器存在一些问题,本文将探讨这些问题并提供解决方案。
问题描述
Enzyme 的适配器可以使用户在使用 Enzyme 时与不同的 React 实现(如 React DOM、React Native)进行交互。然而,React Native 并不是用浏览器渲染的,所以对于一些浏览器特性,如 DOM 等,Enzyme 的测试并不能同样适用于 React Native。即使是类似于 mount()
或 shallow()
这样的基本操作,在 React Native 上也有所不同。
具体来说,以下是 Enzyme 在 React Native 上的主要问题:
- Enzyme 的适配器在运行 React Native 建立的应用程序时会崩溃。
div
、span
、form
等标签在 React Native 上并不存在。Enzyme 在适配器中定义了这些浏览器特有的标签,但在 React Native 上并不起作用。- Enzyme 的
simulate()
方法无法模拟原生事件,如onPress
。 - Enzyme 的某些选择器可能无法运行在 React Native 上,例如
:first-child
。 - React Native 需要一个设备或模拟器才能运行,这使得测试的速度非常缓慢。
解决方案
1. 使用 React Native TestUtils
React Native 提供了自己的测试库:React Native TestUtils。这个库提供了一些专门为 React Native 设计的测试工具,用于解决 Enzyme 在 React Native 上的一些限制。这些工具不需要设备或模拟器,可以直接在本地运行。
React Native TestUtils 提供了类似于 Enzyme 的 shallow()
和 mount()
方法,以及一些由于 React Native 特性而新增的方法。例如,createRenderer()
方法是一个轻量级的渲染器,它能快速渲染组件并返回一个轻量级的 JavaScript 对象,方便我们进行进一步的测试。
以下代码是一个使用 React Native TestUtils 的例子:
-- -------------------- ---- ------- ------ ----- ---- -------- ------ - -------------- - ---- -------------------------- ------ ----------- ---- ---------------- ----------- ----------- -- -- - ----- -------- - ----------------- ---------------------------- ---- ----- ------ - --------------------------- --------------------------------- ---
使用 createRenderer()
方法可以得到一个渲染器,使用 render()
方法可以渲染组件,使用 getRenderOutput()
方法可以获取渲染结果。你可以使用 Jest 的 toMatchSnapshot()
方法来生成组件的快照并进行比较。
2. 替换 Enzyme 的适配器
如果你已经熟悉了 Enzyme 的 API,而且希望继续使用它来测试 React Native 组件,那么你可以替换它的适配器。第三方开发者已经写了一些 React Native 适配器,例如:
- enzyme-to-json-react-native: 将 Enzyme 渲染的组件转换成一个 JSON 对象,以方便我们进行 JavaScript 对象比较测试。
- enzyme-react-native-adapter: 提供与 React Native 的适配器,适配器本身还是非常基础的。可以使用
expect()
来比较渲染的结果。 - enzyme-native-touch-events: 添加了
tap()
和swipe()
等原生事件的 Emulate,旨在让 React Native 的测试更加自然。
如果你对自定义适配器比较感兴趣,可以尝试自己实现。
3. 模拟原生事件
React Native 中的事件与浏览器中的事件略有不同,所以 Enzyme 同时也不能与它们进行交互。
幸运的是,我们可以使用一个第三方库:react-native-testing-library,它提供了能够与 Enzyme 配合使用的方法,可以模拟这些原生事件。
以下是如何使用 react-native-testing-library
来模拟原生事件:
-- -------------------- ---- ------- ------ ----- ---- -------- ------ - --------- - ---- ------------------------------- ------ ----------- ---- ---------------- ------------- ------- ------- -- -- - ----- ------- - ---------- ----- - ----------- - - ------------------- ----------------- ---- --------------------------------------- ----------------------------------- ---
这里的 fireEvent.press()
方法模拟了 onPress
事件,可以快速触发组件中的函数并对其进行测试。
4. 使用更加本地化的选择器
你可以使用基于属性的选择器,例如 getByTestId()
。在组件中,你可以将每个组件都有一个唯一的 testID
,用于测试和识别组件。以下是如何在组件中设置 testID
:
-- -------------------- ---- ------- ------ ----- ---- -------- ------ - ----- ---- - ---- --------------- ----- ----------- - -- -- - ----- ---------------- ----- ---------------------- ------------- ------- -- ------ ------- ------------
在测试用例中,你可以使用 getByTestId()
方法来访问这些元素:
-- -------------------- ---- ------- ------ ----- ---- -------- ------ - ------ - ---- ------------------------------- ------ ----------- ---- ---------------- ------------ ------- --- -------- -- -- - ----- - ----------- - - ------------------- ---- ----- ------ - ---------------------- ----- ------ - ---------------------- ----------------------------- ----------------------------- ---
使用 testID
可以使测试用例更简单、更清晰,而且不受 HTML 标签的影响。
结论
本文介绍了 Enzyme 在 React Native 上的一些适配器问题,并提供了解决方案。你可以选择使用 React Native TestUtils 来测试组件,也可以自定义适配器,并使用第三方库来模拟原生事件。最后,使用 testID
选择器可以使测试更本地化。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/670f2a6c5f55128102632242