【React】フロントエンドにテストは必要か
本ブログでも何度かフロントエンドにおけるテストの実装について触れてきましたが。
現時点での自分の意見をだらだらーっと書いていこうと思います。
まず誤解を恐れずに結論から書いてしまうと。
基本的にはフロントエンドにおけるテストの実装については、そこまで積極的に行う必要はないんじゃないか?というのが個人的な意見です。
「なにがなんでもテストは書かないとダメ!!」でもないし「まったく必要ない!!」という感じでもなく。
ケースバイケースで取捨選択を行えば良いと思いつつ、どちらかといえばネガティブな立ち位置だったりします。
そもそもフロントエンドにおけるテストって、調べても情報がめちゃくちゃ荒れててさっぱりまとまっていない現状があったりします。
そこで、まずは自分が信頼しているソースをもとに、自信が把握している範囲でテストに関する方法を書いていこうと思います。
フロントエンド開発において信頼できるソースの 1 つに Frontend Developer Roadmap が挙げられると思います。
これによると、以下を網羅していればフロントのテストは OK だよ!と書かれていますね。
- Jest
- react-testing-library
- Cypress
- Enzyme
これに対し、React の公式サイトではいくつかのセクションにわかれてテストに関する記述があります。
自分が把握しているセクションは以下のとおりです。
これらのドキュメントを読むと、ざっくり以下のようなことが書かれていることがわかります。
- テストランナーは Jest をオススメするよ
- コンポーネントのテストには react-testing-library をオススメするよ(ボイラープレートの記述を減らせるため)
- Enzyme は使わなくていいよ
- スナップショットテストには react-test-renderer をオススメするよ
- End-to-end テスト(以下 e2e テスト)には Cypress とか Playwright を使えば良いよ
ということで、この 2 つのソースをもとに話をまとめると。
- テストランナーには Jest を使おう
- コンポーネントのテストには react-testing-library を使おう
- スナップショットテストには react-test-renderer を使おう
- e2e テストには Cypress を使おう
といったチョイスがベストなのかなーと思います。
ちなみにテスト周りのドキュメントとしては Jest の公式ドキュメント がぶっちぎりで読みやすいので、一読されることをオススメします。
で、個人的にはここに Storybook の選択肢も出てくるのかなーと思っています。
Storybook 自体は直接的にテストに関わってくるわけではないですが。
スナップショットテストを行いたい場合、Storybook を通してスナップショットを取得するケースもメジャーかなと。
とはいえ上記に加え Storybook まで考慮すると、もうもうもうわっけがわからん状態になりますよね。
自分も正直ついていけていない部分も少なくありません。
一応各モジュールについて説明をば。
Jest
JavaScript のフレームワークであり、テストランナーです。
テストを実行してくれるモジュールというイメージで良いと思います、採点みたいな感じですね。
react-testing-library
レンダリングされたコンポーネントに対してテストを行うことができるモジュールです。
npm パッケージ名は react-testing-library
ではなく @testing-library/react
なのが死ぬほどややこしく、もっとも混乱を招いている一員だと思います。
やれることとしては、たとえば onClick
イベントの発火前後の DOM の状態が想定通りかなど、操作系を得意としています。
react-test-renderer
コンポーネントのスナップショットを取得したりできるモジュールです。
react-testing-library とは異なり、DOM に対して操作などは行うことはできません。
ほぼスナップショットテスト専用なイメージなんですが、どーなんでしょうか。
Cypress
実際にブラウザを立ち上げて挙動を確認してくれるモジュールです。
人間が実際にブラウザに対して行う行動を Cypress で実現するイメージとなります。
Storybook
コンポーネントをコンポーネント単位で画面に描画してくれるモジュールです。
テスト用のモジュールではないですが、Storybook を通してスナップショットを取得することも可能です。
おそらくやってることとしては react-test-renderer
をラップして Storybook 用に最適化されて提供されているだけだとは思いますが。
フロントエンドにテストを導入すると一口に言っても、テストにはいくつか種類があります。
- コンポーネントのテスト
- スナップショットテスト
- e2e テスト
これらはどれもテストの目的が異なるため、いずれかを導入したところで他のテストを導入しなくても良いということにはなりえません。
導入コストを比較すると「e2e テスト > コンポーネントのテスト > スナップショットテスト」という感じなので、スナップショットテストだけ導入してお茶を濁しているプロジェクトも多いです。
テストごとに目的が異なるということは、逆に言えば作っている Web サイトや Web サービスの規模感やクオリティから最適なテストを選択すれば良いと、個人的には強く思っています。
例を挙げると。
- フォームの入力時や送信時、フロント側のバリデーションが正しく働いているか確認したい → コンポーネントのテスト
- ボタンコンポーネントの見た目を変更したので、影響範囲を確認したい → スナップショットテスト
- 画面遷移が正しく行われているか確認したい → e2e テスト
で、個人的になぜフロントエンドにおけるテストの導入について、どちらかといえばネガティブな立ち位置でいるかというと。
かけるコストの割に、得られるメリットが少ないよなーというのが本音です。
スナップショットテストくらいであれば導入コストはさほどかからないかもですが、コンポーネントのテストや e2e テストともなってくると話が変わってきます。
バックエンド側であれば、セキュリティ面に始まり、DB へのアクセスや Api 周りのバリデーション、サーバー負荷やレスポンス速度など、気にかけないといけないことが山程ある一方。
フロント側って、まぁ、さほどですよね。
もちろん銀行系や株・FX 系であれば、まったく話は別です。
1 円単位の表記ズレすら許されないでしょうし、レスポンス速度やセキュリティ周りも厳しいでしょうし、すべてのテストをガチガチに書く必要があると思います。
が、それ以外のさほどなジャンルやさほどな部分については、正直さほどで良いと思っています。
気づいたら直すくらいで十分、かけられるコスト感とバランスを見て、まったくテストを書かない選択肢も普通にあって良いと思います。
ということで、テストってさほどで良いよね、という話でした。
繰り返しになりますが、ケースバイケースとしか言いようがないです、少なくとも毎プロジェクト同じテストを書かなければいけないということはありえません。
たまにテストの知識に強いプログラマーが「テストを書かないとかありえないですよ!」みたいなことを書いていますが、ぜーんぜんそんなことないです。
しょせんフロントです、知識として持っておくことはとても大切ですが、テストより開発を優先しちゃってなんの問題もないと思います。
もし仮にテストのことをよく理解していないプロダクトオーナーから「フロントのテストはどうなってんの?」とか言われたら、スナップショットくらい書いておけば良いんじゃないでしょうか。