LoginSignup
4
2

More than 3 years have passed since last update.

【ReactNative, TypeScript】既存のアプリにJest, Enzyme, Huskyを導入する方法

Last updated at Posted at 2020-07-15

目標

既存のReactNativeで開発したアプリに、Jest, Enzymeを導入し、「多面!フラッシュ暗算」というテキストが正しく表示できるかをテストする。

HomeTitle.tsx
import React from 'react';
import { StyleSheet, Text } from 'react-native';
import {
    widthPercentageToDP as wp,
    heightPercentageToDP as hp
} from 'react-native-responsive-screen';

const HomeTitle: React.FC = () => {
    return <Text style={styles.title}>多面!フラッシュ暗算</Text>;
};

export default HomeTitle;

const styles = StyleSheet.create({
    title: {
        color: '#fff',
        fontSize: wp('7%')
    }
});

Simulator Screen Shot - iPhone SE - 2020-07-15 at 14.34.08.png

初期状態は、TypeScriptで開発できる環境は整っているが、Jest, Enzymeはインストールすらされていない。

package.json
"scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject",
    "prettier": "npx prettier --write '**/*.{ts,tsx}'"
 },

Jestの導入

[参考]
https://reactnative.dev/blog/2018/05/07/using-typescript-with-react-native

公式通りにts-jestをインストールし、package.jsonにJestの設定を書いていく。

$ npm i --save-dev ts-jest 
package.json
"jest": {
    "preset": "react-native",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js"
    ],
    "transform": {
      "^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
      "\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
    },
    "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
    "testPathIgnorePatterns": [
      "\\.snap$",
      "<rootDir>/node_modules/"
    ],
    "cacheDirectory": ".jest/cache"
  },

次も公式通りに必要なパッケージをインストールする。

$ npm i --save-dev @types/jest @types/react-test-renderer

ここで試しにjestコマンドを打ってテストが走るかどうかを確認する。

スクリーンショット 2020-07-15 12.20.41.png

babel-jestがないようなので、インストールする。

$ npm i --save-dev babel-jest

jestコマンドを叩いて、テストが走るかを確認する。

スクリーンショット 2020-07-15 12.21.45.png

無事に走っているようなので、試しに__tests__フォルダを作成して、JavaScriptで簡単なテストを試してみる。

__tests__/index.test.js
it(' 1+2=3 である', () => {
    expect(1+2).toBe(3)
})

スクリーンショット 2020-07-15 12.25.14.png

無事にテストが通ったので、package.jsonに設定した"transform"がうまく機能するか確かめるため、TypeScriptで簡単なテストを試してみる。

sum.tsx
export const sum = (x: number, y: number) => x + y
__test__/sum.test.tsx
import { sum } from '../sum'

it(' 1+2=3 である', () => {
    expect(sum(1, 2)).toBe(3)
})

スクリーンショット 2020-07-15 12.52.19.png

いろいろと警告が出ているが、テストは通っているので一旦無視しておく。

.jestフォルダが作られているので、gitに反映させないように.gitignoreに追記する。

.gitignore
# jest
.jest

目的である、HomeTitleコンポーネントのテストをするため、公式通りに必要なパッケージをインストールし、テストを書いて試してみる。

$ npm i --save-dev react-addons-test-utils
__test__/HomeTitle.test.tsx
import React from 'react'
import renderer from 'react-test-renderer'

import HomeTitle from '../elements/HomeTitle'

it('renders correctly with defaults', () => {
    const title = renderer
      .create(<HomeTitle />)
      .toJSON()
    expect(title).toMatchSnapshot()
})

jestコマンドを実行していろいろ試すと、下記の3パターンのエラーが起こった。

スクリーンショット 2020-07-15 12.37.02.png
スクリーンショット 2020-07-15 14.06.20.png
スクリーンショット 2020-07-15 14.06.57.png

私の場合は、react-test-rendererをインストールしていなかった(@types/react-test-rendererをインストールしていた)、jest.config.jsの設定をしていなかった、ということが問題だった。
[参考]
https://github.com/kulshekhar/ts-jest/issues/937
https://github.com/storybookjs/storybook/issues/1409

エラーを解消するため、下記のインストールと設定を行う。

$ npm i react-test-renderer
jest.config.js
module.exports = {
    preset: 'react-native',
    transform: {
      '^.+\\.tsx?$': 'babel-jest',
    },
}

再びjestコマンドを実行すると、テストが通り、__snapshots__フォルダが作成された。

__tests__/__snapshots__/HomeTitle.test.tsx.snap
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders correctly with defaults 1`] = `
<Text
  style={
    Object {
      "color": "#fff",
      "fontSize": 52.5,
    }
  }
>
  多面!フラッシュ暗算
</Text>
`;

HomeTitle.tsxの「!」を半角に変えてから再びテストを実行すると、差分が検知された。

スクリーンショット 2020-07-15 14.09.53.png

Enzymeの導入

せっかくだからEnzymeも導入してみた。
[参考]
https://enzymejs.github.io/enzyme/docs/guides/react-native.html
https://medium.com/@hdsenevi/unit-testing-in-react-native-with-jest-and-enzyme-40cd7dabb6f1

必要なパッケージをインストールしていく。

$ npm i --save-dev enzyme enzyme-adapter-react-16 react-dom

TypeScriptで書いている場合はこちらも必要なようです。

$ npm i --save-dev @types/enzyme @types/enzyme-adapter-react-16 @types/react-dom

同じくHomeTitleコンポーネントのテストをするため、試しにデバッグを実行してみる。

__tests__/HomeTitle-enzyme.test.tsx
import React from 'react'
import { configure, shallow } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16';

import HomeTitle from '../elements/HomeTitle'

configure({ adapter: new Adapter() });

it('Should render HomeTitle', () => {
    const component = shallow(<HomeTitle />)
    console.log(component.debug())
})

スクリーンショット 2020-07-15 14.26.39.png

うまくEnzymeが導入できていることがわかる。
今回は、<Text>コンポーネントが正しくレンダリングされているかをテストするため、テスト用にdata-test="homeTitle"を付加し、テストを実行する。

HomeTitle.tsx
...
const HomeTitle: React.FC = () => {
    return <Text style={styles.title} data-test="homeTitle">多面フラッシュ暗算</Text>;
};
...
__tests__/HomeTitle-enzyme.test.tsx

...
it('Should render HomeTitle', () => {
    const component = shallow(<HomeTitle />)
    const wrapper = component.find(`[data-test='homeTitle']`)
    expect(wrapper.length).toBe(1)
})

スクリーンショット 2020-07-15 14.31.57.png

HomeTitle-enzyme.test.tsxは通っているが、data-test="homeTitle"を付加したため、先ほどJestで書いたスナップショットテストが通っていない。

テスト実行時にスナップショットを更新するために、-uオプションをつけて実行する。

jest -u

スクリーンショット 2020-07-15 14.33.11.png

無事にテストが通る。

Huskyを導入

せっかくテストを書いたので、git push時にテストが走るようにしていく。
[参考]
https://github.com/typicode/husky

まずは、npm run testでJestを実行するscriptをpackage.jsonに追記する。

package.json
"scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject",
    "prettier": "npx prettier --write '**/*.{ts,tsx}'",
    "test": "jest" // 追加
  },

npm run testを実行して確認する。

スクリーンショット 2020-07-15 15.12.30.png

Huskyをインストールする。

$ npm i --save-dev husky

package.jsonにHuskyの設定を追記する。

package.json
"husky": {
    "hooks": {
      "pre-push": "CI=true npm run test"
    }
 },

git push時にテストが走るかどうか確認する。
スクリーンショット 2020-07-15 15.17.43.png

まとめ

とりあえず Jest, Enzyme, Husky の導入はできた。
正直、スナップショットテストもEnzymeの仕様も深くは知らないので、これを機に深めていきたい。
Jest, Enzymeは下のyoutubeの動画の教材がとても分かりやすかった。
React Redux Unit & Integration Testing with Jest and Enzyme

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2