【React】フロントエンドのテストコードを書いてみよう【Vitest】

こんにちは。

ギークフィードでエンジニアをやっているNkawaKです。

 

バックエンドのテストコードは書いたことはあっても、

フロントエンドのテストコードは経験がない方も少なくないのではないでしょうか。

 

本記事ではVitestというモダンなテストフレームワークを使って、

フロントエンドのテスト環境の構築やテストコードの書き方を解説していきますので、

これからフロントエンドのテストに入門する方の参考にしていただければと思います。

 

テスト環境の構築

まずはViteを使ってReactのプロジェクトを作成していきましょう。

 

 

これでReactのプロジェクトが作成できました。

これからの作業はこのディレクトリで行っていきます。

 

今回は↓のような、よくあるログインフォームをサンプルにテストしてみましょう。

 

 

 

 

 

 

 

 

このフォームは以下のコンポーネントからできています。

メールアドレスとパスワードをuseStateで管理し、そのデータをログインボタンのイベントでAPIに送信します。

API側ではメールアドレスとパスワードでユーザーを検索して、ユーザーが見つかったらレスポンスとして返します。

以上の処理が正常に完了したら、取得したデータのユーザー名をフォーム上に表示します。

次はこのコンポーネントをテストするための環境を構築していきましょう。

 

以下のコマンドを実行してテストに必要なライブラリをインストールします。

ライブラリのインストールが完了したら、Vitestの設定をしていきましょう。

 

vite.config.tsを以下のように編集します。

次にpackage.jsonにテスト用のスクリプトを追加します。

次にテストの設定ファイルを配置するディレクトリを作成し、そこにsetup.tsを配置します。

この時点ではsetup.tsに、importを一行追加するだけで大丈夫です。

 

最後にtsconfig.jsonでVitestでよく使うAPIの型を、あらかじめimportしておきます。

以上でVitestのテスト環境を構築することができました。
では実際にテストコードを書いていきましょう。

 

フロントエンドのテストコードを書く

src/testにApp.test.tsxを新規作成します。

まずはログインフォームが正常に表示されているかのテストをしていきましょう。

 

ファイルのトップレベルでdescribeというAPIを実行します。
describeは文字列か関数を第一引数に指定し、第二引数のコールバック関数の中にテストケースを書いていきます。
第一引数の文字列か関数名が、describeの中に記述する複数のテストをまとめるグループ名となります。

 

次にtestというAPIを実行して、テストを定義します。

テストケースを書いていく前に、renderでテストをするコンポーネントをレンダリングする必要があります。

 

getByTextで引数に指定された文字列が含まれる要素を取得し、

toBeInTheDocumentでその要素がドキュメントの中に存在しているかを確認しています。

 

getByRoleでは引数で指定したロールを持つ、要素を取得することができます。

このロールはAccessible Rich Internet Applications (ARIA)を参照しています。

https://momdo.github.io/html-aria/#allowed-descendants-of-aria-roles

 

getByLabelTextは引数の文字列を含むラベルに紐づいた要素を取得します。

type=”password”のinputはgetByRoleでは取得できないので、このメソッドを使用しています。

 

これら以外にも、getByTestIdというメソッドが頻出です。

このメソッドではid属性ではなく、data-testidという属性から要素を取得することに注意が必要です。

 

getByRoleとgetByLabelTextで取得した要素が存在しているかをtoBeTruthyで確認しています。

要素が取得できなかった場合は結果はfalsyとなるので、期待する要素が存在するかを確認できます。

 

ではこのテストコードをyarn testで実行してみましょう。

テストが成功したことを確認できました。

 

次は入力フォームが動作しているかのテストをしていきましょう。

 

以下のテストを追加します。

テストコード上でフォームの入力やクリックなどのイベントを発生させる場合は、userEventを使用します。

イベントを起こす前にsetupで準備する必要があります。

 

先ほど紹介したgetByLabelTextでフォームの要素を取得します。

取得した要素に文字を入力する場合はtypeを実行します。

typeの第一引数には入力を行う要素を、第二引数には入力する文字列を指定します。

またtypeは非同期で実行されるのでawaitで処理の完了を待機しています。

 

フォームに入力された値をtoHaveValueで確認します。

新しく追加したテストも成功しました。

以上のテスト結果から、期待したテキストが画面に含まれていることと

フォームが正常に動作していることが分かりました。

 

次にAPIと連携している部分をテストします。

 

APIをモック化する

最後にログイン処理をテストしましょう。

この処理はAPIとやりとりを行いますが、テスト環境では外部のAPIと連携することができません。

ではどうやってテストするかというと、APIの部分をモック化することで解決します。

 

APIのモック化はmswというライブラリを使います。

ライブラリをインストールしたらsrc/test/にmocksというディレクトリを作成します。

このディレクトリでhandlers.tsというファイルを作成します。

handlersの配列の中でモックAPIの動作を定義します。

テスト環境では”https://XXXXXXX/signin”に”test@example.com”と”userTest1234″がPOSTされた場合に、
ステータスコード200とユーザーデータのオブジェクトを返し、それ以外では404エラーを返すようにしました。

 

次はsrc/test/にserver.tsというファイルを作成します。

setupServerに先ほど作成したhandlersの配列を渡すことで、サーバーとして機能してくれます。

 

最後にsrc/test/setup.tsを以下のように編集します。

setupServerで作成したサーバーをテストする際に、どのように動作させるかを定義しています。

 

beforeAllはdescribe内の最初のテストが始まる前に実行するコールバック関数を登録し、

テスト前にサーバーを待機状態にしています。

 

afterAllはdescribe内の最後のテストが終了した際に実行する関数を登録し、

テスト後にサーバーを終了させています。

 

afterEachはdescribe内の各テストが終わる毎に実行する関数を登録し、

テスト毎にリクエストハンドラをリセットしています。

 

モックAPIの準備ができたので、App.test.tsxに以下のテストコードを追加します。

setupでイベントの準備を行い、getByで要素を取得します。
typeからフォームにメールアドレスとパスワードを入力して、
clickでログインボタンをクリックしてAPIにフォームの情報を送信します。

 

これらの処理が正常に実行できていれば、画面上に”Welcome testUser !”と表示されるはずです。
テストを実行して確認してみましょう。

 

最後に追加したテストも成功しました。モック化したAPIも正常に動作しています。

すべてのテストが成功したことで、このコンポーネントは期待通りに動作していることが分かりました。

 

Vitest UIとカバレッジレポート

テスト環境を構築する際にpackage.jsonに以下のスクリプトも追加していました。

これらのVitestのオプションも見ておきましょう。

yarn test:uiを実行するとテスト結果をUIで確認することができます。

テストの結果をダッシュボードとして出力したり、左のファイル名をクリックすると、

各テストのより詳しい情報を確認することができます。

実際のアプリではもっと多くのテストコードが書かれるので、便利なUIがあるのはありがたいですね。

 

yarn coverageを実行するとテストのカバレッジ(網羅率)が表示されます。

このレポートを見れば、どのコンポーネントがテストできていないのか一目でわかりますね。

またカバレッジテストの後、/coverageにレポートのHTMLページが作成されます。

 

このディレクトリの中にあるindex.htmlを開くと、ブラウザ上でより詳しくレポートの確認ができます。

File列のリンクから、各コンポーネントのテスト状況を個別に確認することもできます。

 

以上のように、Vitestには便利なオプションがあるので、テストの際に活用してみるのも良いでしょう。

 

まとめ

  • Vitestのテスト環境を構築する際はvite.config.tsにテストの設定を追加する
  • テストコードのトップレベルでdescribeを実行し、その中でテストを定義する
  • getByから始まるメソッドで要素を取得し、expectのメソッドで取得した要素の確認を行うことができる
  • 入力やクリックなどのイベントはuserEventで発生させることができる
  • mswというライブラリを使って、APIをモック化することができる
  • Vitestにはテスト結果をUIやカバレッジレポートとしても出力させることができる

 

Vitestによるフロントエンドのテスト解説は以上になります。

皆さまがテストコードを書くときの参考になれば幸いです。

この記事が気に入ったら
いいね ! しよう

Twitter で

【採用情報】一緒に働く仲間を募集しています

採用情報
ページトップへ