Lightning Web コンポーネント用の Jest テストの記述
コンポーネントテストは、ローカル JavaScript ファイルに記述します。このローカル JavaScript ファイルは、コンポーネント自体とともにバージョン管理にコミットします。Jest テストは、Salesforce には保存されません。
Jest テストは、Lightning Testing Service 用に記述される Jasmine または Mocha テストとは、記述、保存、実行の方法が異なります。Jest テストはローカルのみで、Salesforce とは関係なく保存および実行されます。
Salesforce CLI コマンド sf force lightning lwc test create
を使用して、テストディレクトリと、そのディレクトリ内の定型のテストファイルを作成します。次のコマンドでは、テストディレクトリと、myButton
Lightning Web コンポーネントをテストするためのファイルが作成されます。
Salesforce CLI create
コマンドを使用したら、force-app/main/default/lwc/myButton/__tests__
のように、__tests__
という名前のフォルダがコンポーネントのバンドルディレクトリの最上位に表示されます。それ以外の場合、フォルダを自分で作成します。このコンポーネント用のすべてのテストを __tests__
フォルダ内に保存します。__tests__
フォルダをバージョン管理にコミットして、他のチームメンバーやシステムとテストを共有します。
__tests__
フォルダとそのコンテンツが Salesforce に保存されないようにするために、この glob パターンを各プロジェクトの .forceignore
ファイルに追加します。Salesforce CLI コマンド sf force lightning lwc test setup
を実行すると、この設定が行われます。
このパターンを使用すると、コードをプッシュ、プル、または変換する Salesforce DX コマンドおよびメタデータでは、__tests__
フォルダとそのコンテンツが無視されます。
Jest が JavaScript ファイルを実行するのは、__tests__
ディレクトリです。テストファイル名の末尾は、.js
にする必要があります。.test.js
にすることをお勧めします。すべてのコンポーネントテストで 1 つのテストファイルを使用することも、複数のファイルを使用して関連するテストを編成することもできます。テストファイルは、サブフォルダに配置できます。
熟練したテスト担当者になるには、Jest の使用方法を学びます。特に、Jest で提供される Matcher の構文を覚えてください。優れた Jest ドキュメントがあるので、Jest の一般的な用法についてはここで説明しません。Lightning Web コンポーネントで Jest を使用する具体例を中心に説明します。
Lightning Web コンポーネントの Jest テストでは、外部コンポーネントまたはサービスとの連動関係を最小限に抑え、単一コンポーネントの動作を切り離してテストする必要があります。
hello.test.js
を見てみましょう。これは lwc-recipes
リポジトリにある hello
Lightning Web コンポーネント用のテストです。
順を追ってコードを確認し、テストファイルの各セクションについて説明していきます。この構造をすべてのテストで使用する必要があります。
最初に、テストは createElement
メソッドをインポートします。このメソッドはテストのみで使用できます。コードは、テストするコンポーネントもインポートする必要があります。この場合は c/hello
です。後でこれらのインポートを使用して、テストするコンポーネントを作成します。
describe
ブロックは、テストスイートを定義します。テストスイートには、機能の観点からまとめられた 1 つ以上のテストが含まれます。
最上位の describe
ブロックの記述は、コンポーネント名と一致させることをお勧めします。必要な場合にのみ、機能をグループ化する describe
ブロックを追加します。
hello.test.js
の場合、describe
は 1 つで十分です。より複雑なコンポーネントでは、エラーシナリオ、空の入力、有線データ、通常のデータなどのカテゴリにグループ化した複数の describe
ブロックを使用した方が良い場合があります。
Jest の afterEach()
メソッドは、テストの最後に DOM をリセットします。
ブラウザはテスト実行時に実行されていないため、Jest では jsdom
を使用することで、ブラウザの DOM または document
のように動作する環境が提供されます。Jest は Node.js プロジェクトである jsdom
と連動関係があるため、jsdom
は sfdx-lwc-jest
プロジェクトのインストール中に Jest 本体と同様にダウンロードされます。
各テストファイルは、1 つの jsdom
インスタンスを共有しており、ファイル内のテストの合間に変更はリセットされません。そのため、テストの出力が別のテストに影響しないように、テストの合間にクリーンアップすることがベストプラクティスです。
Jest には、設定タスクとクリーンアップタスクを実行するために使用できる他のメソッドもあります。「jestjs.io/docs/en/setup-teardown
」を参照してください。
it
は test
の別名です。期待される動作を正確に記述できるほうを使用してください。
it
ブロックは、1 つのテストを記述します。テストは、テストする 1 つの機能単位を表します。it
を使用して、その機能の期待される動作を記述します。たとえば、hello
コンポーネントには「Hello, World!」と表示されるので、it
ブロックは、hello コンポーネントに挨拶が表示されることをテストします。
テストでは、インポートした createElement
メソッドを使用して、テストするコンポーネントのインスタンス、この場合は c-hello
を作成します。
テストは次に appendChild
をコールして、テストの document
のバージョンにコンポーネントを追加します。
appendChild()
コールによって、コンポーネントが DOM に挿入され、ライフサイクルフックの connectedCallback()
と renderedCallback()
がコールされます。
次のステップでは、標準 DOM クエリメソッドを使用して要素の DOM を検索します。element.shadowRoot
をクエリの親として使用します。これは、シャドウの境界を越えてコンポーネントのシャドウツリーを検査できるテストのみの API で、this.template
と同等のテストです。
最後に、expect
ステートメントは、要素のテキストが「Hello, World!」であるという成功条件のアサーションです。
Jest は toBe
や toMatchObject
など、値が条件を満たしていることを容易に確認できる Matcher を多数サポートしています。「jestjs.io/docs/en/expect
」を参照してください。
Lightning Web コンポーネントの状態が変わると、DOM が非同期で更新されます。結果を評価する前にテストが更新の完了を待機するようにするには、解決された Promise を返します。残りのテストコードを、解決された Promise にチェーニングします。Jest はテストを終了する前に Promise チェーンの完了を待機します。Promise が拒否状態で終了すると、Jest はテストに失敗します。
appendChild()
コールによって、コンポーネントが DOM に挿入され、ライフサイクルフックの connectedCallback()
と renderedCallback()
がコールされます。この例では次に、appendChild()
コールの_後_に要素値が設定されています。これは、コンポーネントが DOM に挿入された後に別のメソッドまたはユーザ操作によってプロパティが設定される場合に似ています。このような場合は、Promise を使用して DOM の非同期更新を待機します。コンポーネントライフサイクルと表示についての詳細は、「ライフサイクルフロー」を参照してください。
プロパティが appendChild()
コールの前に設定される場合は、コンポーネントが同期で表示されます。プロパティが appendChild()
コールの前に設定される場合、非同期更新を待機、または Promise を返す必要はありません。
関連トピック
- Salesforce 開発者ブログ: Unit Test Lightning Web Components with Jest (Jest を使用した Lightning Web コンポーネントの単体テスト)
- Jest: Get Started (使用開始)
- Jest: Expect Reference (Expect リファレンス)
- GitHub リポジトリ: lwc-recipes
- Shadow DOM