2024年11月11日
執筆
有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)に所属するテクニカルライター。出版社を経てフリーランスとして独立。ライター、エディター、デベロッパー、講師業に従事。屋号は「たまデジ。」。著書に『Bootstrap 5 フロントエンド開発の教科書』、『作って学べるHTML+JavaScriptの基本』など。
監修
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。
主な著書に「独習」シリーズ、「これからはじめるReact実践入門」、「改訂3版 JavaScript本格入門」他、著書多数。
「新発見!フロントエンド技術の今」の連載。第13回のテーマは高品質なアプリの開発に欠かせないテストです。
テストを一言で表現すれば、ソフトウェアの品質を高めるための作業です。ソフトウェアには仕様があり、あるべき姿が定められています。あるべき姿と実際の姿を比較して差異があれば、それを検出するのがテストの目的です。
ソフトウェアの品質には、大きく2種類あります。プログラム(コード)の品質と、アプリケーションの品質です。前者は、プログラムが正しく動作するか、後者はプログラムがユーザの要求を満たしているか、に力点が置かれます。このため、テストも要求されるものに応じた手法があります。
よほど単純なロジックでない限り、書いたばかりのコードがバグのない完全体になることはありません。テストを繰り返し、問題を潰していきながら、コードの品質を高めていきます。
テストといえばバックエンド、ビジネスロジックのためのものと考えている方もいるかも知れません。かつては、フロントエンドの位置付けはサーバサイドアプリケーションの補助的なものであることが多く、テストの重要性はさほど高いものではありませんでした。
しかしながら、現在ではアプリケーションの大部分をフロントエンド技術でまかなうことも当たり前になってきており、こうなるとテストなしではアプリケーションの品質を担保することは困難です。フロントエンド開発でも、テストは当たり前になっているのです。
テストには、手動テストと自動テストがあります。手動テストは、文字通り手作業でテストを実行します。テスト用のソフトウェアを別途用意する必要もなく、手軽にできるイメージがありますが、人手に頼るものなので確実性に欠けます。そのため、現在では何らかのソフトウェアを用いた自動テストが主流です。
自動テストは、文字通り自動的に実行されるテストです。人手によらない自動テストは、高速に実行できることもメリットですが、コード修正時のチェック漏れを防止できるのもメリットです。コードを修正した場合、成功していたケースが逆に失敗に転ずる場合もあります(回帰バグ)。このようなことを防止するためにもテストを自動化し、手作業から切り離すのです。また、高速化することでプログラマがテストを忌避することも抑制できます。
テストには、幾つかの種類があります。フロントエンドでは、単体テスト、結合テスト、E2Eテストといった分類になることが多いようです。まずは、その分類で各テストの特徴を紹介します。
単体テストはユニットテスト、コンポーネントテストともいい、関数(メソッド)、クラス、モジュールといったコンポーネント単位の動作を検証する、最も基本的なテストです。例えば関数の場合、入力値(引数)の組み合わせをテストケースとして用意し、それらに対して正しい出力値(戻り値)が得られるかということをテストします。アプリケーションの基本部分の品質を、早期に確保するのが目的です。フロントエンド開発においては、データリソースとのやり取りなどの関数、UIコンポーネント単体での動作を検証することになります。
単体テストのツールには、Mocha、Jest、Jasmine、AVAなどがあります。また、UIコンポーネントのテストには、ドキュメンテーションの機能も備えたワークショップであるStorybookが利用できます。
結合テストはインテグレーションテストともいい、複数コンポーネント(関数、UIコンポーネントなど)の組み合わせを検証するテストです。単体テストが、コンポーネント単独での動作を検証する基本的なテストであったのに対し、結合テストはコンポーネントの組み合わせが正しく動作するかどうかを検証します。単体テストでは、テスト対象が外部データや通信を必要とする場合にモックという模擬的な機能を用意しますが、結合テストではこれらの機能も含めたテストとなります。フロントエンドでは、データソースとのやり取りなどの関数とそれを使うUIコンポーネント、あるいはUIコンポーネント同士を組み合わせての動作を検証することになります。
結合テストのツールには、Mocha、Jest、Jasmine、Vitest、Cypress、AVAなどがあります。
E2Eテストは、エンドツーエンド(End-to-end)テストの略で、ユーザの実際の利用環境に基づき、システムが正しく動作するか、データフローが適切に機能するかどうかを、システム全体を通して検証するテストです。V字開発モデルにおけるシステムテストを発展させたもので、ユーザインタフェースを含めた全体のテストを行うことから、これを指してUIテストと呼ぶこともあります。開発プロジェクトの最終段階で実行され、アプリケーションの最終的な品質を確保するのが目的です。フロントエンド開発においては、ブラウザ上での動作を検証することになります。E2Eテストは、テスト仕様書に基づき手動で行うことも多いのですが、本記事で紹介するようなツールを用いることで自動化することが可能です。
E2Eテストのツールには、Cypress、Playwright、Selenium、Puppeteerなどがあります。
ここからは、JavaScriptについてのサーベイである「State of JS」の、2023年の調査結果において人気のある、注目されているテストフレームワークをメインに、いくつかピックアップして紹介します。
それぞれのテストフレームワークは、MITライセンス下において無償で利用できます。基本的にNode.js環境で動作しますが、ブラウザ上でテストを実行できるフレームワークもあるので、以下の表に摘要をまとめておきます。
テストフレームワークは一般的に、特定の役割を持ったライブラリで構成されます。テストフレームワークが組み込みで備えることもあるほか、テストフレームワークによっては、ライブラリを部分的に差し替えて使うこともできるようになっています。
テストランナー | テストをNode.jsおよびブラウザで実行するためのライブラリ。Karmaなど |
テスティングライブラリ | DOM操作のためのライブラリ。Testing Library、Enzymeなど |
モックライブラリ | 模擬データや通信のためのライブラリ。mock-fs、nockなど |
アサーションライブラリ | テストの実行結果を検証するためのライブラリ。Chaiなど |
Mochaは、2011年リリースと歴史が長く、利用者も多いことから情報の入手も容易なテストフレームワークです(「モチャ」ではなく「モカ」と発音します)。Mochaは非常に多機能ですが、多くのライブラリと組み合わせて使う前提であるので非常に柔軟性が高い反面、依存するライブラリが多くなってしまうのが現在では弱点と言えます。
テストカバレッジや非同期関数のテストなど豊富な機能を備えており、should.js、express.js、chai、better-assert、unexpectedなどのアサーションライブラリを選択可能です。
WebアプリフレームワークSvelte、Nuxt.js 3における標準のテストフレームワークとなっています。
Jestは、Meta社(旧Facebook)が2019年にリリースした比較的新しいテストフレームワークです。登場以来、Mochaをしのぐ勢いで利用者を獲得、認知度も向上しています。「テストを楽しく」をコンセプトに、ゼロコンフィグなどシンプルさを重視した設計となっています。テストも高速に実行でき、コードカバレッジ、スナップショット、並列テスト、豊富なモックなど機能面でも充実しています。
JestはもともとReact向けに開発されましたが、プラグインによりBabel、TypeScript、Node、Angular、Vueアプリもテストできます。Reactアプリ、Next.jsアプリの開発であれば、Jestを使うのが最も自然です。
後述するJasmine、Vitestとはテスト関数の記述において共通部分が多く、ノウハウを共有できます。
Jasmineは、2014年にPivotal Labs(現VMware Tanzu Labs)によりリリースされた、2009年に登場したMochaと並んで歴史のあるテストフレームワークです。高速に動作し、他のライブラリやフレームワークに依存しない独立性の高さが特徴です。
JasmineはAngular、Vueに標準装備されています。このため、Angularアプリ、VueアプリであればJasmineを使うのが最も自然です。
Storybookは、2016年にリリースされたUIコンポーネントのテストを手軽に行えるテストフレームワークです。テストフレームワークというよりはUI構築、ドキュメント作成のためのUIワークショップであり、UIコンポーネントの挙動を確認したり、ドキュメントの生成を自動化したり、デモデータを用いたテストが可能など、多数の機能を備えています。
React以外にもVue、Angular、Web Component、Ember、Svelte、Preactなどがサポートされています。
Vitestは、Vue.jsの開発者であるEvan You氏により2021年にリリースされた、新しいテストフレームワークです。上記サーベイでも、利用実績や知名度は他のフレームワークに及びませんが、登場していきなり関心度トップとなっています。
Vitestは、同じくEvan You氏によるJavaScriptバンドラーVite(第12回を参照)と連携して動作します。Viteの設定やプラグインなどをテスト環境にも利用できるので、テストの導入のために新たに手順を踏む必要がなくなっています。また、Jestと高い互換性があり、テストスクリプトなどをほぼそのまま利用できます。ただし、スナップショットやテストカバレッジの機能は備えません。
簡易的なウォッチ機能を備え、コードの変更によりテスト起動の機能を備えます。Vite同様に高速なJavaScriptバンドラーesbuildを利用し、TypeScriptやJSXのテストにも対応します。
Cypressは、2019年にCypress社によってリリースされた、E2Eテストに対応したテストフレームワークです。E2Eテストのほか、単体テスト、UIテストにも対応しています。直感的で使いやすく、軽量に動作し、安定性に優れているのが特徴です。E2Eテストに対応しているテストフレームワークの中では知名度が高く、導入実績も豊富で情報の収集も容易です。
スナップショットを自動的に作成するタイムトラベル、awaitやsleepが不要の自動待機、ネットワークトラフィックの制御、スクリーンショットや動画の記録、クロスブラウザテストなど、豊富な機能を備えています。CypressはOSにインストールされるので、OSの機能に依存しないと利用できない機能を備えるのが特徴です。
Playwrightは、E2Eテストのためのテストフレームワークです。Microsoft社によってリリース、メンテナンスされています。フレームワークの到達目標として、Chromium、Webkit、Firefoxといったブラウザエンジンにおいてアプリが正しく動作することを掲げています。これらのブラウザエンジンのためのテストの他、Android OS上のGoogle ChromeやiOS上のSafariのテストもサポートされています。
Microsoft社のプロダクトらしく、VS Codeの拡張機能も提供されており、同環境からのテストが可能となっています。また、CI(継続的インテグレーション)ツールであるGitHub ActionsやGoogle Cloud Buildなどをサポートするので、CI/CDのフローにE2Eテストテストを組み込むことも容易になっています
今回は、フロントエンドアプリの品質向上に欠かせない「テスト」を紹介しました。本記事をきっかけにテストの意義を再認識し、気になるテストフレームワークがあればぜひ深掘りしていただきたいと思います。
関連記事
人気記事