⚙️

フロントエンド開発のためのテスト入門 - サンプルの紹介 -

2023/04/06に公開3

昨年から執筆を続けていた書籍が 4/24 に刊行します。「フロントエンド開発のためのテスト入門」という本です。

https://twitter.com/takepepe/status/1629426402905964544

書籍ならではのテストコード解説を目指して

次の投票結果は、書籍企画時に持ち込んだ筆者のツイートです。フロントエンドテストに関していえば、8 割近くの方が何かしら不安や不足を感じている、という結果になりました。

https://twitter.com/takepepe/status/1539945216542511104

不安や不足の原因は様々なものがあるかと思います。そのうち、筆者が着目したのは「テスト手法の豊富さ」です。「単体テスト・結合テスト・E2E テスト、何をどれほど書けばよいのか?」という疑問は、フロントエンドに限らず、はじめて自動テストに取り組まれる方が通る関門ではないでしょうか。

自動テストを書くには「テスト対象」を明確にしたうえで、テスト対象に適したテストコードを書く必要があります。本書は、現場で書かれるものに近い「テスト対象 = アプリケーションコード」をサンプルとして用意し、テストコードを書きました。一本のアプリケーションを通して様々なテスト手法が解説できるのは、一冊の書籍ならではの利点だと思います。

刊行前ですが、本日そのサンプルコードを公開しましたので、ここに紹介します。

https://github.com/frontend-testing-book

各章の概要

書籍は前半・後半に分けて、2 つのサンプルリポジトリを軸に解説しています。第 3 章〜第 6 章はフロントエンドのテスト入門リポジトリを使用します。Jest を使用したテスト入門となっており、テストコード初学者でも読み進められるよう工夫しました。第 7 章〜第 10 章は Next.js サンプルリポジトリを使用します。

  • 第 1 章 テストの目的と障壁
  • 第 2 章 テスト手法とテスト戦略
  • 第 3 章 はじめの単体テスト
  • 第 4 章 モック
  • 第 5 章  UI コンポーネントテスト
  • 第 6 章 カバレッジレポートの読み方
  • 第 7 章  Web アプリケーション結合テスト
  • 第 8 章  UI コンポーネントエクスプローラー
  • 第 9 章 ビジュアルリグレッションテスト
  • 第 10 章  E2E テスト

章の構成は、筆者おすすめの取り組み順となっています。Jest で実行する単体テストからはじまり、最終的には DB(Prisma)を含めた E2E テストまでをカバーします。書籍では様々なフレームワーク・ライブラリが登場します。

  • フロントエンドライブラリ・フレームワーク:React, Zod, React Hook Form, Next.js, Prisma
  • テスティングツール・フレームワーク:Jest, Testing Library, Storybook, reg-suit, Playwright

これらの使用方法については適宜解説を挟んでいるので、ライブラリに不慣れな方でも読み進めるに支障のないよう留意しました。(ただやはり紙面に限りがあるため、公式ドキュメントも並行して読んでいただければと思います)

Next.js サンプルアプリケーションの紹介

Next.js サンプルアプリケーション

テスト対象となる Next.js サンプルアプリケーションは「架空の技術ブログ投稿サービス」を想定して実装しています(上図)ざっくりとした機能要件は以下の通りです。

  • ログインユーザーは記事を執筆することができる
  • 記事は「公開・下書き」ステータスを更新できる
  • 一般公開された記事は、誰でも閲覧することができる
  • ユーザー同士は記事に「Like」をつけることができる
  • Like 数の多い順に記事一覧をソートできる
  • レスポンシブレイアウトで構築されている

あくまで「テストコードの書籍」ということで、このアプリケーションコードそのものの詳細設計については解説していません。これらの解説については、zenn や GitHub リポジトリを活用して、より充実した書籍になるよう随時補足していきいたいと考えています。

発売までまだ少しお待ちいただきますが、ぜひ手に取っていただけると嬉しいです。

Discussion

Shota TamuraShota Tamura

書籍拝読いたしました。あいまいな知識が線で繋がり、今後に大いに役立ちそうです。ありがとうございます🚀

もし差し支えなければ、一点ご質問させていただいてもよろしいでしょうか🙏


現在、Unit Test と E2E Test の中間にある、Integration Test を充実させるのが一番効果的だよ、という世の流れだと理解してます。

このIntegration Testを書く手法として、本書籍では Jest + React Testing Library を活用されていたと思います。一方で、もしかしてPlaywrightでも、わりと似たようなことができるのではないか?という個人的な感触がありました。

たとえば、アサーションなどはどちらでも同じようなAPIが用意されていそうでした。

  • 特定のテキストを持つ
  • 特定のCSSが適用される
  • URLに特定のQuery Stringをもつ

また、アクションもほぼ同等のものがあるかと思います。

  • クリックする
  • 文字を入力する
  • inputで画像ファイルを選択する

今後、当方は画面単位でのざっくりした統合テストを書いていこうかと思っており、JestでやるかPlaywrightでやるか迷っています。

VRTが簡単にできたり、画面上で視覚的なデバッグができることを考えると、Playwrightを選択したい一方で、例えばフォームで送信されるデータの精緻な検証などには向かないのかなと思ったりもしており、迷っています。

このあたりどう感じておられるか、ご意見伺えますとありがたいです🙇‍♂️

TakepepeTakepepe

読んでいただきありがとうございます!

「Integration Test(結合テスト)が何をさすのか?」というのは、文脈によって人それぞれです。拙書では、インタラクションを伴うものは、テストツールを問わず結合テストと称しています。重要なのは「何をテスト対象とするのか?」ということです。

おっしゃるとおり Playwright でも、結合テスト(機能テスト)ができます。このとき判断基準になるのが「Jest + Testing Library でも同じテストを書くことができないか?」という点に着目することです。

Jest + Testing Library の場合、jsdom という仮想ブラウザ上でテストを実行します。jsdom は実行速度が早い反面、完全にブラウザを再現しきれた環境ではありません。そのため「このテスト対象は jsdom では再現不能だから、Playwright で書こう」という判断になります。

書籍第7章で取り上げているテストは概ね、jsdom で実行できる結合テストになります。画面間を跨ぐ機能、例えば「A画面->B画面->C画面、というような流れでしか再現しない機能」をテストする場合は、Playwright で書くことになります。(ただし、こういった機能はまれで、localStorage を使った機能などです)

また、Playwright はブラウザを起動するため、実行速度が遅いです。そのため、はじめのうちはあまり気にならないかもしれませんが、テストが充実してくると「CI待ちでマージするのに数十分待たなければいけない」という状況になりがちです。

テスト対象がより速く実行できるなら、それに越したことはないため、テスト対象によってツールを選ぶと良い、というのが私の考えです。

Shota TamuraShota Tamura

お返事いただきありがとうございます!

CI待ちでマージするのに数十分待たなければいけない

この視点は抜けていました。これが理由で後々テストを書き直すことになるのは避けたいですね。

一旦、両方を併用しつつ、特に必要がなければJestで書いていく方向でやってみたいと思います🙏