はじめに
Reactでのテストをする際はReact Testing Libraryを使いますが、提供されるクエリには公式からあらかじめ定められた優先度があるのはご存知でしょうか?
雰囲気で以下のような感じでテストを書いていませんか?
// <a href='https://hoge.com' data-testid='hoge-testid'>リンク</a>を取得したい時
render(<Component />)
screen.getByTestId('hoge-testid')
公式ではgetByTestIdを使用する方法はあまり推奨されていません。
以下のように修正できます。
render(<Component />)
screen.getByRole('link', {name: 'リンク'})
なるべくgetByRoleやgetByLabelTextなどのユーザー目線でのテストを記述することが良いとされています。
今回はReact Testing Libraryにおけるクエリの優先度を学びつつ、ユーザ目線を意識したユニットテストの書き方について学んでいきます。
クエリの優先度
testing-libraryにおけるテストはユーザーが操作する方法にできる限り似ているように設計するべきとされており、以下のような3つの優先順位で決められています。
1. Queries Accessible to Everyone
視覚やマウスを使用するユーザーや、支援技術を使用するユーザーの体験を反映するクエリ
getByRole
WAI-ARIAで決められている、各属性の役割で要素を取得することができます。
冒頭の例だと、a要素はlinkという役割が暗黙的に指定されています。
また、nameオプションを使うことでアクセシブルな名前でフィルタすることができます。
例えば以下のようになります。
// <a href='https://hoge.com' data-testid='hoge-testid'>リンク</a>を取得したい時
screen.getByRole('link', {name: 'リンク'})
getByLabelText
主に、フォームなどのinput要素のラベルに使用されます。
ユーザーはラベルに基づいてinput要素を見つけ出しますが、その操作に似せたクエリとなっています。
getByPlaceholderText
input要素などのプレースホルダーテキストを使用して要素を取得するクエリです。
例えば、検索ボックスのテキストを取得する場合などに使用されます。
getByText
要素のテキスト内容に基づいて要素を取得します。
このクエリは画面上に表示されるテキストを元に要素を見つけるため、ユーザーが実際に見るコンテンツを反映します。
getByDisplayValue
フォーム要素の現在の値に基づいて要素を取得します。
ユーザーがフォームに入力した値を反映したクエリです。
2. Semantic Queries
HTML5やARIAを準拠したクエリ。
getByAltText
画像要素の代替テキスト(alt属性)に基づいて要素を取得します。
画像の内容に関連するクエリで、視覚障害のあるユーザーのために重要です。
getByTitle
このクエリは、要素のタイトル情報を利用して要素を取得します。
3. Test IDs
テスト専用のIDを使用したクエリ。(ユーザーはテストIDを見たり聞いたりすることができないため、特定のロールを持たない、またはテキストで一致できない場合のみ推奨されます)
この方法は、テストがUIの変更に影響を受けずに安定して動作することを目指す場合に便利です。
getByTestId
テストのための特別な属性(data-testid)を使って要素を取得します。
アクセシビリティの観点からは、このクエリは避けるべきですが、テストのしやすさから一部の場合に使用されることもあります。
まとめ
ユーザー目線でテストを行うためには、ユーザーが実際にどのようにアプリケーションを操作操作して利用するかを考えることが重要となっています。
上記のクエリの優先度に従い、ユーザーがどのようにアプリケーションを操作するかを考慮してテストを記述しましょう。
テストを行う際は、テストケースが現実のユーザー操作に沿ったものであることを確認し、アクセシビリティを重視することで、アプリケーションの品質を高めることができます。
参考文献
About Queries | Testing Library
Common mistakes with React Testing Library
testing-library でユーザの気持ちになって書くフロントエンドのテスト