React Nativeでのテストは公式のドキュメントでも述べられてます。テストはやや貧弱なイメージがあります。Xcodeだと2015年のキーノートで発表されたUI Testを利用が難しかったりします。
またAndroid用のIntegration環境がドキュメントにないので、Androidで結合テストは現時点では外部モジュールに頼る必要がります。
方針として、ロジックとコンポーンネントを切り離し、ロジックをしっかりテストしていくことが良いかと思います。
Unit Test on React Native
Unitテストは基本的にJestを使ってテストしていきます。
Jest設定方法
ドキュメント通りにpackage.jsonに下記を設定。
...
"scripts": {
...
"test": "jest"
},
...
"jest": {
"scriptPreprocessor": "node_modules/react-native/jestSupport/preprocessor.js",
"setupEnvScriptFile": "node_modules/react-native/jestSupport/env.js",
"testPathIgnorePatterns": [
"/node_modules/",
"packager/react-packager/src/Activity/"
],
"testFileExtensions": [
"js"
],
"unmockedModulePathPatterns": [
"promise",
"source-map"
]
},
...
実行方法
__tests__
と__mocks__
ディレクトリを作り、
$ tree __*
__mocks__
└── react-native.js
__tests__
├── actions-test.js
├── component-test.js
└── reducers-test.js
下記コマンドでテストします。
$ npm test
Jest
詳しくはJestを参照して欲しいのですが、Jestはデフォルトでmockする挙動なので、慣れが必要な気がします。コンポーネントのmockは手間がかかり大変なので、どこまでテストしていくのかははっきり考える必要があると思います。このことを考慮してプロジェクトのテスト方針をまずはじめに決める必要があると思います。
Componentのユニットテスト
下記のコードをテストします。(コード自体は意味のないものなのはご容赦ください)
import React, { WebView } from 'react-native';
let terms = React.createClass({
render(){
return(
<WebView
url={this.props.url}
/>
);
}
});
export default terms;
これをテストするためにreact-shallow-renderer-helpers
というモジュールをイントールします。shallow renderの説明はReactのshallow renderのセクションを参考にしてくれれば良いと思いますが、1階層だけテストするイメージになります。
$ npm install react-shallow-renderer-helpers --save
そして、下記のようなコードを書きます。
まず、テスト対象のWebViewはmockしない宣言をします。
jest.dontMock('../app/components/WebView');
const React = require('react-native');
const WebView = require('../app/components/WebView');
const shallowHelpers = require('react-shallow-renderer-helpers');
function setup(){
let renderer = shallowHelpers.createRenderer();
renderer.render(() => <WebView />)
let output = renderer.getRenderOutput()
let instance = renderer.getMountedInstance();
return {
output,
instance,
renderer
}
}
describe('components', () => {
describe('App', () => {
it('has WebView', () => {
const { output, instance } = setup();
expect(output.type.name).toBe('WebView');
})
})
})
そして次にReactをロードするのですが、これはmock処理する必要があり、__mock__
ディレクトリにファイルを作ります。
jest.dontMock('react');
var React = require('react');
var ReactNative = React;
ReactNative.StyleSheet ={
create: function(styles) {
return styles;
}
};
class WebView extends React.Component {
render(){
return <div {...this.props}/>
}
}
ReactNative.WebView = WebView;
ReactNative.NativeModules = {};
module.exports = ReactNative;
上記のように、React NativeのcomponentをReactの要素でmockしていきます。
あとはnpm test
でテストするだけです。
Summary
今回はReact NativeのComponentのユニットテストを解説しました。モックするのがReactを使っていくので、大変というのが分かったと思います。現実問題、本当に必要な部分だけテストしていくのが良いかと思います。明日はロジックのテストをreduxのテストと絡めて説明します。