React Nativeユニットテストの実践
6428 ワード
React Nativeユニットのテストは現在ネット上の資料が少ないです.ほとんどは点から点までで、実用的な用途はありません.Github上のオープンソースプロジェクトのユニットテストも多くないので、提供する参考も限られています.この点は自分で少しずつ模索するしかないです.ここではこの数日間の模索の心得とプロジェクトに対してユニットテストを行い、問題と解決方法を記録します.
ユニットテストフレーム-Jest
JestはFacebookのJavascriptユニットのテストを専門に行うツールであり、RNが持っているテストフレームです.だから使わない理由はない.just公式文書アドレス:https://facebook.github.io/jest/docs/getting-started.html#content ここで重点的に見ることができます.Testing React Native Appsは、RNのために書かれたjustテストマニュアルです.多くはないですが、退屈は無に勝ります.
justテスト運転方式は、端末でコマンド:
次はJestテストで問題があります.
プロジェクトは原生モジュールの第三者ライブラリを使用しています.
いくつかのRN構成要素または第三者構成要素は、元のAPIに依存して実装され、この場合、npm testコマンドを実行するとエラーが発生する(ただし、テストは通過する可能性がある).例えばプロジェクトの中でreact-native-linear-gradientという第三者ライブラリを引用しましたが、この線形グラデーションライブラリは原生モジュールを使用していますので、justテストには以下の問題があります.
enter description here
解決方法:index.ios.js/index.android.jsファイルにmockローカルモジュールを追加します.例えば、
プロジェクトでは自分で作成した原生モジュールを使用して、参照は
enter description here
参照元モジュールのサードパーティライブラリソリューションを使用して、MyPageAppliFunctionが元のモジュール名、getMyPageInfoが元のモジュール中の方法、jst.fn()がjustに提供するシミュレーション方法を同じ方法で解決します.
UIコンポーネントテストは、現在知られているUIコンポーネントテストのための2つの方法があります.一つはフラッシュテスト(Snapshot)で、もう一つはライトレンダリングテスト(Shallow Rendering)です.
スナップショットテストSnapshot
UIが意外に変更されないことを確認するには、スナップショットテストは非常に有用なツールです.RNで初めてあるコンポーネントをスナップショットテストすると、同じディレクトリの下にsnapshotsフォルダを作成し、スナップショットの結果をこのフォルダに保存します.スナップショット結果ファイルはxxx.js.snapと命名され、その内容はある状態のUIコンポーネントツリーである.以下はスナップショットのテスト例です.
浅いレンダリングテスト(Shallow Rendering)
浅いレンダリング(Shallow Rendering)は、上のコンポーネントに対してテストを行う時、そのサブコンポーネントをレンダリングしなくてもいいので、サブコンポーネントの表現と行為を心配しなくてもいいです.このようにして、特定のコンポーネントの論理とレンダリング出力だけをテストします.Facebookの公式はreact-addons-test-utilsを提供しています.この特性を浅いレンダリングで仮想DOMオブジェクト、すなわちReact.Componentの例をテストします.しかし、ここで紹介したのはreact-addons-test-utilsではなく、Enzymeです.JavaScriptオープンソースコミュニティで活躍するAirbban公司から来たのです.公式テストツールバンクのパッケージです.jQueryのAPIをシミュレートしています.とても直感的で使いやすいです.いくつかの異なるインターフェースといくつかの方法を提供して、テストのサンプルコードを低減します.あなたの判断、操作、およびReact Componentsの出力を遍歴し、テストコードと実現コードとの結合を低減します.以下は公式の簡単な例である.
スナップショットテストであろうと、浅いレンダリングテストであろうと、いくつかのピットに注意が必要です.は、スナップショットテストにおいて、テストされるコンポーネントがタッチパネルのコンポーネントを有する場合、期待されるコンポーネントの中でタッチパネルのコンポーネントを無視する必要がある.そうでなければ、運行は のエラーを報告します.スナップショットテストと浅いレンダリングテストでは、コンポーネントとアニメーションが関連している場合は、Anime.componentのこれらのコンポーネントを使用して、実行時にも 元のモジュールに加入しているイベントのAPIは、まだシミュレーションが成功していません.
スナップショットテストと浅いレンダリングテストについては、完全な工程を確認してください.https://github.com/ferrannp/react-native-testing-example
コードのカバー率について
補充が必要です
RNのユニットテストについてはまだ深く分かりませんが、今後も引き続き改善していきます.
ユニットテストフレーム-Jest
JestはFacebookのJavascriptユニットのテストを専門に行うツールであり、RNが持っているテストフレームです.だから使わない理由はない.just公式文書アドレス:https://facebook.github.io/jest/docs/getting-started.html#content ここで重点的に見ることができます.Testing React Native Appsは、RNのために書かれたjustテストマニュアルです.多くはないですが、退屈は無に勝ります.
justテスト運転方式は、端末でコマンド:
npm test
を介して実行される.次はJestテストで問題があります.
プロジェクトは原生モジュールの第三者ライブラリを使用しています.
いくつかのRN構成要素または第三者構成要素は、元のAPIに依存して実装され、この場合、npm testコマンドを実行するとエラーが発生する(ただし、テストは通過する可能性がある).例えばプロジェクトの中でreact-native-linear-gradientという第三者ライブラリを引用しましたが、この線形グラデーションライブラリは原生モジュールを使用していますので、justテストには以下の問題があります.
enter description here
解決方法:index.ios.js/index.android.jsファイルにmockローカルモジュールを追加します.例えば、
react-native-linear-gradient
のこの第三者ライブラリは、jst.mock方法でシミュレーションして、元のモジュールの影響を除去します.mockの方法は以下の通りですjest.mock('react-native-linear-gradient', () => 'react-native-linear-gradient')
プロジェクトは自分で作成した原生モジュールを使用しています.プロジェクトでは自分で作成した原生モジュールを使用して、参照は
NativeModules.
で行いますが、テスト時には以下のエラーが報告されます.enter description here
参照元モジュールのサードパーティライブラリソリューションを使用して、MyPageAppliFunctionが元のモジュール名、getMyPageInfoが元のモジュール中の方法、jst.fn()がjustに提供するシミュレーション方法を同じ方法で解決します.
jest.mock('NativeModules', () => {
return {
MyPageApiFunction: {
getMyPageInfo: jest.fn(),
},
};
});
それでもまだ解決されていません.苦労して模索した結果、やっとGithubのissueで解決策を見つけました.package.jsonファイルを修正して、justノードに以下の構成を追加します."jest": {
"preset": "react-native",
"setupFiles": ["./jest/setup.js"]
}
プロジェクトのルートディレクトリの下で、jstフォルダとsetup.jsファイルを新規作成します.setup.jsは一言を追加するだけでいいです.これでnpm testコマンドを再実行するとnative module cannot be null
のエラーに遭いません.UIコンポーネントテストは、現在知られているUIコンポーネントテストのための2つの方法があります.一つはフラッシュテスト(Snapshot)で、もう一つはライトレンダリングテスト(Shallow Rendering)です.
スナップショットテストSnapshot
UIが意外に変更されないことを確認するには、スナップショットテストは非常に有用なツールです.RNで初めてあるコンポーネントをスナップショットテストすると、同じディレクトリの下にsnapshotsフォルダを作成し、スナップショットの結果をこのフォルダに保存します.スナップショット結果ファイルはxxx.js.snapと命名され、その内容はある状態のUIコンポーネントツリーである.以下はスナップショットのテスト例です.
// Intro.js
import React, {Component} from 'react';
import {
StyleSheet,
Text,
View,
} from 'react-native';
const styles = StyleSheet.create({
container: {
alignItems: 'center',
backgroundColor: '#F5FCFF',
flex: 1,
justifyContent: 'center',
},
instructions: {
color: '#333333',
marginBottom: 5,
textAlign: 'center',
},
welcome: {
fontSize: 20,
margin: 10,
textAlign: 'center',
},
});
export default class Intro extends Component {
render() {
return (
Welcome to React Native!
This is a React Native snapshot test.
);
}
}
スナップショットテストを作成します.// __tests__/Intro-test.js
import 'react-native';
import React from 'react';
import Intro from '../Intro';
// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';
test('renders correctly', () => {
const tree = renderer.create(
).toJSON();
expect(tree).toMatchSnapshot();
});
npm test
コマンドを実行すると、snapshotsフォルダでスナップショットの結果を出力します.// __tests__/__snapshots__/Intro-test.js.snap
exports[`Intro renders correctly 1`] = `
Welcome to React Native!
This is a React Native snapshot test.
`;
次回テストを実行する時、レンダリングの出力は前に作成したスナップショットと比較します.スナップショットはコードに沿って変更して提出します.スナップショットのテストに失敗した場合、予期しない変更であるか確認する必要があります.予定の変更であれば、npm test -- -u
コマンドを使って既存のスナップショットを上書きすることができます.浅いレンダリングテスト(Shallow Rendering)
浅いレンダリング(Shallow Rendering)は、上のコンポーネントに対してテストを行う時、そのサブコンポーネントをレンダリングしなくてもいいので、サブコンポーネントの表現と行為を心配しなくてもいいです.このようにして、特定のコンポーネントの論理とレンダリング出力だけをテストします.Facebookの公式はreact-addons-test-utilsを提供しています.この特性を浅いレンダリングで仮想DOMオブジェクト、すなわちReact.Componentの例をテストします.しかし、ここで紹介したのはreact-addons-test-utilsではなく、Enzymeです.JavaScriptオープンソースコミュニティで活躍するAirbban公司から来たのです.公式テストツールバンクのパッケージです.jQueryのAPIをシミュレートしています.とても直感的で使いやすいです.いくつかの異なるインターフェースといくつかの方法を提供して、テストのサンプルコードを低減します.あなたの判断、操作、およびReact Componentsの出力を遍歴し、テストコードと実現コードとの結合を低減します.以下は公式の簡単な例である.
import { shallow } from 'enzyme'
describe('Enzyme Shallow', () => {
it('App should have three components', () => {
const app = shallow()
expect(app.find('Todo')).to.have.length(3)
})
}
sharllow方法はコンポーネントの第1層DOM構造をレンダリングするだけで、その入れ子コンポーネントはレンダリングされないので、レンダリングの効率が高くなり、セルテストの速度も速くなります.下記は天翼雲プロジェクトが表の部品に対して書いた浅いレンダリングテストの例です.it('renders a MineGridItem using Enzyme without backup animation', () => {
const wrapper = shallow(
);
const {title, image, keyIndex, enableAutoBackup} = infos[0];
expect(wrapper.contains(
{title}
)).toBe(true);
});
MineGridItemコンポーネントは以下の通りです.
{title}
浅いレンダリングの一般的な使い方:show方法を使ってテスト待ちコンポーネントを包み、expect方法で期待を書き出してUIをレンダリングし、両者を比較する.スナップショットテストであろうと、浅いレンダリングテストであろうと、いくつかのピットに注意が必要です.
TypeError: Cannot read property 'validAttributes' of undefined
をエラーします.解決策がまだ見つからないです.スナップショットテストと浅いレンダリングテストについては、完全な工程を確認してください.https://github.com/ferrannp/react-native-testing-example
コードのカバー率について
補充が必要です
RNのユニットテストについてはまだ深く分かりませんが、今後も引き続き改善していきます.