【備忘録⑤】React & TypeScript & Webpack4 & Babel7 & dev-server の最小構成ボイラープレートの作成 -Jestの導入-
この記事はQiitaの記事をエクスポートしたものです。内容が古くなっている可能性があります。
前回の記事 で作成したボイラープレートにJestを導入する。
各種設定
モジュールの追加
今回は Jest と Enzyme をインストールする。
$ npm install -D jest ts-jest enzyme enzyme-to-json enzyme-adapter-react-16
TypeScript を使用するので以下もインストールする。
$ npm install -D @types/jest @types/enzyme @types/enzyme-adapter-react-16
Jest設定ファイルの作成
Jestの設定ファイルを追加する。
// <プロジェクトルート>/jest.config.js module.exports = { // 起点となるディレクトリを指定 "roots": [ "./src" ], // アセットの変換方法を指定 "transform": { "^.+\\.tsx?$": "ts-jest" }, // Jestで実行するテストコードの配置場所とテストコードの正規表現での指定 // __tests__下の hoge.test.tsx または hoge.spec.tsx を対象とする "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$", // テスト対象となる拡張子を列挙 "moduleFileExtensions": [ "ts", "tsx", "js", "jsx", "json", "node" ], // Enzymeの設定 snapshotSerializers: ['enzyme-to-json/serializer'], // Enzymeの設定ファイル(自分で作成する) setupFilesAfterEnv: ['./test/setupEnzyme.ts'], };
上記で設定した__tests__
ディレクトリを作成しておく。
$ mkdir ./src/__tests__
Enzyme設定ファイルの作成
今回は、Enzymeを使用するので、こちらも設定ファイルを用意する。
// <プロジェクトルート>/test/setupEnzyme.ts import { configure } from 'enzyme'; import * as EnzymeAdapter from 'enzyme-adapter-react-16'; configure({ adapter: new EnzymeAdapter() });
tsconfig.jsonを作成
TypeScriptの設定ファイルを用意する。
{ "compilerOptions": { "outDir": "./dist/", "sourceMap": true, "strictNullChecks": true, "strictPropertyInitialization": true, "noImplicitAny": true, "noImplicitReturns": true, "module": "es2015", ← common.jsも設定できるが、静的解析の精度が落ちるのでes2015おすすめらしい "target": "es5", "jsx": "react", "esModuleInterop": true }, "include": [ "./src/**/*" ] }
package.jsonにJest実行用設定を追加
package.jsonにJest実行用設定を追加する。
"scripts": { "start": "webpack-dev-server --open", "build": "webpack", "build-prod": "webpack --mode=production", "storybook": "start-storybook -p 6006", "build-storybook": "build-storybook", "test": "jest" ←ここ追加 },
以上で、実行環境の構築は完了。
動作確認
確認用コンポーネント作成
前回作成したコンポーネントを使用する。
// <プロジェクトルート>/src/components/Button/index.tsx import * as React from 'react'; export interface IButtonProps { text: string; flag?: boolean; action(): void; } const Button = (props: IButtonProps) => { const { text, flag, action } = props; return ( <React.Fragment> { flag && <p>{text}</p> } <button onClick={ action }>Button</button> </React.Fragment> ); }; export default Button;
テストファイル作成
__tests__
内にコンポーネントと同じディレクトリ構造を作成する。
$ mkdir ./src/__tests__/components/Button
テストコードを作成する。
// <プロジェクトルート>/src/__tests__/components/Button/index.test.tsx import * as React from 'react'; import {shallow} from 'enzyme'; import Button from '../../../components/Button'; test('小コンポーネントが存在すること', () => { const wrapper = shallow(<Button text="ボタンです" flag={true} action={() => console.log("test")} />); expect(wrapper.find("button").length).toBe(1); expect(wrapper.find("p").length).toBe(1); expect(wrapper.find("p").text()).toEqual("ボタンです"); expect(wrapper).toMatchSnapshot(); }); test('pコンポーネントが表示されないこと', () => { const wrapper = shallow(<Button text="ボタンです" flag={false} action={() => console.log("test")} />); expect(wrapper.find("button").length).toBe(1); expect(wrapper.find("p").length).toBe(0); expect(wrapper).toMatchSnapshot(); }); test('イベント発火時にコールバック関数が呼び出されること', () => { const Spy = jest.fn(); const wrapper= shallow( <Button text="ボタンです" flag={true} action={Spy} /> ); wrapper.find('button').simulate('click'); expect(Spy).toHaveBeenCalledWith(); expect(wrapper).toMatchSnapshot(); });
実行
コンソールからテストコマンドを実行する。 実行すると、以下のようにテスト結果が出力される。
$ npm run test > react-ts-webpack@1.0.0 test /Users/kento/Programing/VScodeProjects/ts-react-sass-simple-boiler-v4 > jest PASS src/__tests__/components/Button/index.test.tsx ✓ 小コンポーネントが存在すること (33ms) ✓ pコンポーネントが表示されないこと (3ms) ✓ イベント発火時にコールバック関数が呼び出されること (6ms) Test Suites: 1 passed, 1 total Tests: 3 passed, 3 total Snapshots: 3 passed, 3 total Time: 2.182s, estimated 5s Ran all test suites.
テスト実行後、__tests__
ディレクトリ内に、__snapshots__
ディレクトリが作成され、中にスナップショットファイルが作成される。
$ tree ./src/__tests__ ./src/__tests__ └── components └── Button ├── __snapshots__ │ └── index.test.tsx.snap └── index.test.tsx
index.test.tsx.snap
の中身は以下の通り。
// Jest Snapshot v1, https://goo.gl/fbAQLP exports[`pコンポーネントが表示されないこと 1`] = ` <Fragment> <button onClick={[Function]} > Button </button> </Fragment> `; exports[`イベント発火時にコールバック関数が呼び出されること 1`] = ` <Fragment> <p> ボタンです </p> <button onClick={ [MockFunction] { "calls": Array [ Array [], ], "results": Array [ Object { "type": "return", "value": undefined, }, ], } } > Button </button> </Fragment> `; exports[`小コンポーネントが存在すること 1`] = ` <Fragment> <p> ボタンです </p> <button onClick={[Function]} > Button </button> </Fragment> `;
以上で、Jestの導入は完了。 作成したボイラープレートは こちら