JavaScript のテストランナー Jest はモジュールやタイマーのモックのような機能を組み合わせて 高速にイテレーションを回すことができ、コードをどう実行するかをよりコントロールできる。 多くの場合、ユニットテストとインテグレーションテストの境界線は曖昧である。
- npm test(npm scripts でテスト実行)
- test case(テストケースの追加)
- expect(期待値と実績値の比較)
実装の詳細に依存せずに React コンポーネントをテストすることができるツールセットです。 このアプローチはリファクタリングを容易にし、さらにアクセシビリティのベスト・プラクティスへと手向けてくれます。 コンポーネントを children 抜きに「浅く」レンダーする方法は提供していませんが、 Jest のようなテストランナーで モック することで可能です。 TestingLibrary は 2018 年リリースで Enzyme に取って代わるライブラリとなった。 ユーザ視点でのテストが可能
- userEvent
- render
- custome hook など
Props や State に任意の値を入れてコンポーネントの整合成を見るテスト よりも ユーザに操作された後の状態がどのようになっているか どのように見えて、操作されるかをトレースできるテスト
同じ
- インストールモジュール
yarn add jest babel-jest jest-watch-typeahead react-test-renderer babel-preset-react-app @types/jest @testing-library/react @testing-library/react-hooks eslint-plugin-jest
yarn add @storybook/addon-storyshots
- @testing-library/react-hooks : React が提供する Hooks テストのためのユーティリティ・ヘルパー
- @testing-library/jest-dom : DOM チェックのために Jest のマッチャーを拡張
TypeScript support in Babel is just transpilation, Jest will not type-check your tests as they are ran. If you want that, you can use ts-jest.
(Babel での TypeScript サポートは単なるトランスパイルである。Jest 実行時に型チェックを行いたい場合は ts-jest を使用します。) → babel-jest より ts-jest を使用する。
- Storybook によるスナップショットテスト
@storybook/addon-storyshotsを使用する。 これが storybook 本体のバージョンを一致していることを確認する。後述する
package.json
に記述、またはjest.config.js
などにファイル化する。
今回は package.json に直書きで試した。
{
// ...
"jest": {
"setupFilesAfterEnv": ["./jest.setup.js"],
"testMatch": ["**/*.test.ts", "**/*.test.tsx"],
"verbose": true,
"moduleNameMapper": {
"^~/(.*)": "<rootDir>/src/$1"
}
}
// ...
}
ルートにjest.setup.js
を一応用意しておく
import '@testing-library/jest-dom'
import fetch from 'node-fetch'
if (!globalThis.fetch) {
globalThis.fetch = fetch
}
初期状態の.test
ファイルでは、tsconfig.json で指定した alias のパス指定で
コンポーネントを import すると test が FAIL してしまうので
jest の以下の設定を見直す。
// "@/" でsrc以下の~ という設定
"moduleNameMapper": {
"^@/(.*)": "<rootDir>/src/$1"
}
- jest と Storybook が正常に動くことを確認する
jest.config.js
とjest.storyshots.config.js
を分けて設定しておく。- npm scripts に
storyshots
を設定する - yarn storyshots でスナップショットテストが自動でできる。
- コンポーネント編集後、yarn storyshots での差分が正しい場合は
yarn storushots --updateSnapshot
を実行する
import { cleanup, fireEvent, render, screen } from '@testing-library/react'
import { Counter } from './Counter'
// Counterというテストグループ名の記載
describe('Counter', () => {
// テストケース終了毎にReactコンポーネントを画面からunmountするためのクリーンナップ用ヘルパー関数を呼ぶ
// 仮にテストが失敗した場合でもクリーンアップコードを実装するべき
afterEach(() => {
cleanup()
})
// テストケース① (実際のケース命名はよりわかりやすくする)
// スナップショットテスト
test('render', () => {
const { asFragment } = render(<Counter />)
expect(asFragment()).toMatchSnapshot()
})
// テストケース②
// 実際にユーザが触るのと同じ動作をさせるテスト
test('click:count', () => {
render(<Counter />)
const button = screen.getByText('Increment')
fireEvent.click(button)
fireEvent.click(button)
screen.getByText('Count: 2')
})
})
yarn test
でテストを実行するとXxx.test.tsx
ファイルがあるフォルダに
__snapshots__
ファイルが作成される