テストをはじめる
学習の目的
この単元を完了すると、次のことができるようになります。
- 単体テストとエンドツーエンドテストの目的と相違点を説明する。
- Lightning Web コンポーネントの単体テストの役割を説明する。
前提条件
このモジュールでは Visual Studio Code エディターを使用して、Salesforce DX プロジェクト内で Lightning Web コンポーネントと単体テストを開発します。Lightning Web コンポーネントや Salesforce DX、Visual Studio Code を使用した Salesforce の開発に慣れていない場合は、先に進む前に「クイックスタート: Salesforce DX」、「クイックスタート: Salesforce 開発のための Visual Studio Code」、「クイックスタート: Lightning Web コンポーネント」プロジェクトを修了することをお勧めします。
テストが重要な理由
「設計フェーズでバグが検出されなかった場合、コーディングフェーズでは検出にその 10 倍の時間がかかり、デバッグフェーズではさらに 10 倍の時間がかかる。」
— Nikolai Bezroukov 博士、The Art of Debugging
デバッグとテストは関連していますが、ソフトウェア開発上の異なるプロセスです。テストはエラーを見つけて報告するものです。デバッグはそうしたエラーの原因を突き止めて修正するものです。そして、Nikolai Bezroukov 博士によると、コード内のバグを見つけて始末するには早ければ早いほどよいということです。
ソフトウェアにバグが一切ないというのが理想的ですが、現実にはミスをすることもあれば、要件が正しく理解されなかったり、アプリケーションが予期しない方法で使用されたりすることもあります。テストによってこうした問題が明らかになり、修正することができます。バグを早い段階で検出すれば、それだけ対処に要するコストが減少します。バグが開発の次のフェーズ (最悪の場合は本番フェーズ) に達すれば、その特定と修正に関与する人々やプロセスが増大します。
Salesforce アプリケーションに実施される一般的なテストには、単体テストとエンドツーエンドテストの 2 種類があります。この 2 つの違いは範囲と目的です。
単体テスト
単体テストは、アプリケーションの機能の小さな断片を対象とします。アプリケーションの構築時は単体テストを実施しやすいように、1 つの長い Apex メソッドやクラスを記述するのではなく、テスト可能な小さな単体を組み合わせます。単独でテストできる個々のメソッドにコードをモジュール化するということです。同様に、アプリケーションとして 1 つの巨大な Lightning コンポーネントを記述するのではなく、単独でテストできる小さなコンポーネントに機能をモジュール化します。単体テストは短時間で迅速に実行できることから、開発や継続的インテグレーションプロセスの中で、開発者がこうしたテストを記述して実行することが期待できます。その結果、バグが早い段階で特定され、修正されるようになります。このプロセスについての詳細は、「Test-driven development (TDD) (テスト主導型開発 (TDD))」を参照してください。
エンドツーエンドテスト
エンドツーエンドテストはアプリケーション全体やユーザージャーニー全体を対象とします。Web アプリケーションの場合は通常、このテストの一環として Sandbox やスクラッチ組織などのテスト環境のブラウザーで、ページ上のコードやコンポーネントがどのように連携するかが検証されます。
エンドツーエンドテストでは、1 つのテストでアプリケーションの多数の機能を検査するため、単体テストより時間のかかる傾向にあります。また、エンドツーエンドテストは、ネットワーク遅延、キャッシュ、サードパーティシステムへの依存、インフラストラクチャの問題など、ライブ環境の偶発的な変動のために単体テストよりも信頼性が低くなります。こうした変動により、初回のテストに合格した後で次のテストに失敗する、フラッピングテストという現象が生じることがあります。このような欠点にもかかわらず、エンドツーエンドテストからはアプリケーションやそのインテグレーションポイントについて、単体テストよりも価値ある実際的な検証結果が得られます。
単体テストとエンドツーエンドテストの比較
では、単体テストとエンドツーエンドテストが実際にどのように機能するのか見ていきましょう。ここでは例として、Salesforce プラットフォームの Lightning Web コンポーネントのサンプルコードが集められた lwc-recipes リポジトリに存在する、api-property Lightning Web コンポーネントを使用します。
<c-api-property>
コンポーネントは、(1) <lightning-card>
コンポーネント、(2) <lightning-input>
コンポーネント、(3) <c-chart-bar>
コンポーネントで構成されます。
-
<lightning-card>
コンポーネントは ApiProperty というタイトルを表示するもので、他の 2 つのコンポーネントが含まれます。 -
<lightning-input>
コンポーネントは数値のユーザー入力を処理し、値変更イベントをブロードキャストします。 -
<c-chart-bar>
コンポーネントはそのパーセント値に基づいて棒グラフを表示します。
この 3 つのコンポーネントのそれぞれに独自の公開 API、内部状態、動作が存在します。そしてこれらの各コンポーネントに、他のコンポーネントとは切り離してその機能を検証する独自の単体テストを設定できます。実際、<c-api-property>
コンポーネントの単体テストでは、<lightning-card>
、<lightning-input>
、<c-chart-bar>
の各コンポーネントが期待どおり動作するものと想定していることもあれば、各コンポーネントの動作をモックしてさまざまな状況下の多様なシナリオをシミュレートすることもあります。
この例では、エンドツーエンドテストで <c-api-property>
コンポーネントをブラウザーページに読み込み、入力項目にパーセント値を入力して、その値に応じた棒グラフが表示されることをアサートします。このエンドツーエンドテストは、3 つのすべてのコンポーネントがユーザーにリリースされたときに、この 3 つがどのように連携するかを確認するものであるため、データや動作をモックすることはありません。
概要
次の表は、単体テストとエンドツーエンドテストの長所と短所の簡単な比較を示しています。
単体テスト |
エンドツーエンドテスト |
|
---|---|---|
テストが迅速に実行される |
はい |
いいえ |
テストの信頼性が高い |
はい |
いいえ |
テストが的確で、具体的な問題を特定できる |
はい |
いいえ |
1 回のテストでアプリケーションの多数の機能を対象とする |
いいえ |
はい |
実際のユーザーをシミュレートする |
いいえ |
はい |
単体テストとエンドツーエンドテストの違いがわかったところで、次はテストが実際にどのように実行されるのかを見ていきます。これ以降は、Lightning Web コンポーネントの単体テストを中心に説明します。
リソース
- 開発者ガイド: Lightning Web コンポーネント
- Trailhead: Lightning Web コンポーネントの作成
- Trailhead: Lightning プラットフォームの単体テスト
- 外部サイト: Google Testing Blog: Just Say No to More End-to-End Tests (Google テストブログ: エンドツーエンドテスト不要論)
- 外部サイト: Kent Dodd’s Blog: Write Tests (Kent Dodd のブログ: テストの記述)
- 外部サイト: Simple Programmer: Back to Basics: Why Unit Testing is Hard (基本事項の復習: 単体テストが困難な理由)
- 外部サイト: Wikipedia: Test-Driven Development (Wikipedia: テスト主導型開発)