初めてReactのテストフレームワークを触るので簡単なテストを行った内容をまとめます。
これまでの学習内容については以下の記事にまとめています。
テストについて
フロントエンドのテストは、アプリケーションの異なる観点で品質を確保するために以下のように分類することができます。
分類 | 確認する観点 | 例 |
単体テスト (Unit Test) | 個々のコンポーネントや関数が正しく動作すること | ・クリックイベントを正しく処理するか ・値の入力時に、期待通りにステートが更新されるか |
結合テスト (Integration Test) | 複数のコンポーネントや機能が連携して正しく動作すること | ・メモの作成、編集、削除機能が正しく連携して動作するか ・フォームの入力値が正しくステートに反映され、サーバーに送信されるか |
エンドツーエンドテスト (E2E Test) | アプリケーション全体のフローがユーザーの視点で正しく動作すること | ・ユーザーがフォームに入力し、送信ボタンをクリックした後、メモ一覧が更新されるか |
今回は、単体テストをJestとReact Testing Libraryを使って行いたいと思います。
JestとReact Testing Library
Jestはテストを行うインフラです。
料理に例えるとコンロやシンクに該当し、これがなければ調理を行うことができないように、Jestはテストを実行するための環境を提供します。
React Testing Library(以降、RTL)はReactコンポーネントをユーザーの視点からテストするためのツールです。
料理に例えるとたこ焼き器やミキサーなど特定の料理を作るためのツールに該当します。
たこ焼き器やミキサーだけでは調理することができず、コンロやシンクを必要とするように、RTL単体ではテストを実行できないためJestの実行環境を使用することでReactのテストを行うことができます。
JestとRTLの導入
TypeScriptを使用したReactプロジェクトにおいてJestとRTLを使用した単体テストを導入するためのステップをまとめます。
なお、以下のテストを理解するためには使用しているプロジェクトのコンポーネントを理解する必要があります。
今回の対象プロジェクトを題材にコンポーネント指向についてまとめたのでぜひ参考にしてください。
JestとRTLのインストール確認
create-react-appを使用している場合、JestとReact Testing Libraryは標準でインストールされています。
$ npx jest --version
27.5.1
$ npm ls @testing-library/react
simple-memo-front@0.1.0 /Users/xxxxxxxxxx/Development/simple-memo-frontend
└── @testing-library/react@13.4.0
テストファイルの作成
コンポーネントの振る舞いに関するテスト項目として今回は以下の4つをテストします。
- MemoContainerコンポーネントがレンダリングされているか
- NewMemoRowコンポーネントがレンダリングされているか
- NewMemoRowを押下したら対象のテキストエリアがfocusされるか
- テキストエリアに入力したらstateに反映されるか
import { render, screen, fireEvent } from "@testing-library/react";
import MemoContainer from "../components/MemoContainer/MemoContainer";
describe("MemoContainer", () => {
beforeEach(() => {
// 各テスト実行前にレンダリングを実行(記述量が削減できる)
render(<MemoContainer />);
});
// MemoContainerコンポーネントがレンダリングされているかを確認
test("renders MemoContainer", () => {
const memoContainer = screen.getByTestId("memo-container");
expect(memoContainer).toBeInTheDocument();
});
// NewMemoRowコンポーネントがレンダリングされているかを確認
test("renders NewMemoRow", () => {
const newMemoRow = screen.getByTestId("new-memo-row");
expect(newMemoRow).toBeInTheDocument();
});
// NewMemoRowを押下したら対象のテキストエリアがfocusされるかを確認
test("click NewMemoRow", () => {
const newMemoRow = screen.getByTestId("new-memo-row");
newMemoRow.click();
const textarea = screen.getByTestId("new-memo-textarea");
expect(textarea).toHaveFocus();
});
// テキストエリアに入力したらstateに反映されるかを確認
test("input NewMemoRow", () => {
const newMemoRow = screen.getByTestId("new-memo-row");
newMemoRow.click();
const textarea = screen.getByTestId("new-memo-textarea");
fireEvent.change(textarea, { target: { value: "New memo content" } });
expect(textarea.value).toBe("New memo content");
});
});
テストを実行
以下のコマンドでテストを実行します。
npm run test
全てのテストで成功していることが分かります。
PASS src/__tests__/MemoContainer.test.tsx
MemoContainer
✓ renders MemoContainer (13 ms)
✓ renders NewMemoRow (2 ms)
✓ click NewMemoRow (4 ms)
✓ input NewMemoRow (4 ms)
Test Suites: 1 passed, 1 total
Tests: 4 passed, 4 total
Snapshots: 0 total
Time: 0.478 s, estimated 1 s
Ran all test suites related to changed files.
なお、テストを実行中にファイルを変更した場合は自動的に再テストしてくれます。
まとめ
以上がコンポーネントの振る舞いについてJestとReact Testing Libraryを用いてテストを行う方法でした。
クリックや入力などのユーザーのアクションを記述できることで効率的にテストが行えるということを学びました。
ぜひ簡単なテストをやってみてください。
コメント