2023年3月2日

Prismaを使ったテストの究極ガイド:エンドツーエンドテスト

エンドツーエンドテストは、アプリケーションのテストの中でもより「俯瞰的」な形式の1つであり、ユーザーの視点からアプリケーションとのインタラクションをテストできます。この記事では、エンドツーエンドテストの設定と記述に関する実践的な例をいくつか見ていきます。

The Ultimate Guide to Testing with Prisma: End-To-End Testing

目次

はじめに

このシリーズのここまでの時点で、スタンドアロンのExpress APIの機能と動作が意図したとおりに動作することを保証するために、広範なテストを記述しました。これらのテストは、統合テストユニットテストの形式で行われました。

このシリーズのこのセクションでは、このアプリケーションに別の複雑さのレイヤーを追加します。この記事では、以前の記事と同じExpress APIとテスト、およびそのAPIを使用するReactアプリケーションを含むモノレポを探求します。このチュートリアルの目標は、ユーザーがアプリケーションで行うインタラクションが正しく機能していることを確認するエンドツーエンドテストを記述することです。

エンドツーエンドテストとは?

エンドツーエンドテストは、アプリケーション内でのユーザーインタラクションをエミュレートして、それらが正しく動作することを保証することに焦点を当てた広範なテスト方法論です。

このシリーズの前のパートでのテストは、アプリケーションの個々の構成要素が適切に動作することを検証することに焦点を当てていましたが、エンドツーエンドテストは、アプリケーションのユーザーエクスペリエンスが期待どおりであることを保証します。

例として、エンドツーエンドテストでは、次のようなことをチェックする場合があります。

  • ユーザーがサインインしていない状態でホームページに移動した場合、ログインページにリダイレクトされるか?
  • ユーザーがUI経由でレコードを削除した場合、そのHTML要素は消えるか?
  • ユーザーはメールフィールドを空欄のままログインフォームを送信できるか?

エンドツーエンドテストが非常に役立つのは、テクノロジースタックの特定の部分の動作を検証するだけでなく、すべてのピースが期待どおりに連携して動作することを保証するからです。フロントエンドクライアントまたはバックエンドAPIに対して具体的にテストを記述するのではなく、これらのテストは両方を利用し、テストランナーがユーザーであるかのように動作します。

エンドツーエンドテストとは何かについての一般的なアイデアを理解したところで、テスト環境のセットアップを開始する準備ができました。

使用する技術

前提条件

前提知識

以下の知識があると、以下の手順を進める上で役立ちます。

  • JavaScriptまたはTypeScriptの基本的な知識
  • Prisma Clientとその機能の基本的な知識
  • Dockerの基本的な理解
  • テストフレームワークの経験

開発環境

提供されている例に沿って進めるには、以下が必要です。

  • Node.js がインストールされている
  • お好みのコードエディタ VSCode を推奨)
  • Git がインストールされている
  • pnpm がインストールされている
  • Docker がインストールされている

このシリーズでは、この GitHubリポジトリ を多用します。リポジトリをクローンしてください。

リポジトリのクローン

ターミナルで、プロジェクトを保存するディレクトリに移動します。そのディレクトリで、次のコマンドを実行します。

上記のコマンドは、プロジェクトを testing_mono_repo という名前のフォルダにクローンします。そのリポジトリのデフォルトブランチは main です。

リポジトリをクローンしたら、プロジェクトをセットアップするためにいくつかの手順が必要です。

まず、プロジェクトに移動し、node_modules をインストールします。

次に、プロジェクトのルートに .env ファイルを作成します。

新しいファイルに次の変数を追加します。

.env ファイルに、次の変数が追加されました。

  • API_SECRET:認証サービスがパスワードを暗号化するために使用する秘密鍵を提供します。実際のアプリケーションでは、この値を英数字で構成される長いランダムな文字列に置き換える必要があります。
  • DATABASE_URL:データベースへのURLが含まれています。
  • VITE_API_URL:Express APIのURLロケーション。

リポジトリの概要

上記で述べたように、このシリーズの以前のパートとは異なり、この記事で作業するリポジトリは、2つの独立したアプリケーションを含むpnpmモノレポです。

以下は、プロジェクトのフォルダ構造です。

backend フォルダには、Express APIと、その統合テストおよびユニットテストが含まれています。このプロジェクトは、このシリーズの前のセクションで作業したのと同じAPIです。

frontend フォルダには、新しいフロントエンドReactアプリケーションが含まれています。アプリケーションは完成しており、このシリーズでは変更されません。

prisma および scripts フォルダには、このシリーズの以前の記事と同じファイルが含まれています。prisma/ には schema.prisma ファイルが含まれており、scripts/ には、テスト環境の実行とセットアップに役立つ .sh スクリプトが含まれています。

残りのファイルは、パッケージ構成、Dockerコンテナ、およびpnpmワークスペースが定義されている場所です。

package.json を見ると、scripts セクションに以下が表示されます。

これらは、pnpmモノレポで実行できるコマンドです。ここでのコマンドは主にpnpmを使用して、backend/package.json および frontend/package.json で定義されているコマンドを実行します。

プロジェクトのルートから次のコマンドを実行して、アプリケーションを起動します。

次に、http//localhost:5173 に移動すると、アプリケーションのログインページが表示されるはずです。

Login page

次に、エンドツーエンドテストとそのテスト環境のセットアップに進みます。

エンドツーエンドテストのプロジェクトのセットアップ

エンドツーエンドテストのセットアップを開始するには、モノレポ内に新しいプロジェクトをセットアップします。これには、すべてのエンドツーエンドテストコードが含まれます。

注意:エンドツーエンドテストとそれに関連するコードは、モノレポの別のプロジェクトにあります。これは、これらのテストがフロントエンドまたはバックエンドプロジェクトに属していないためです。それらは独自のエンティティであり、両方のプロジェクトと対話します。

このプロセスの最初のステップは、プロジェクトの新しいフォルダを作成することです。

モノレポのルートに e2e という名前の新しいフォルダを追加します。

その新しいディレクトリ内で、次のコマンドを使用してpnpmを初期化する必要があります。

このコマンドは、name フィールドの値が 'e2e' を含む初期構成の package.json ファイルを作成します。この名前は、pnpmがプロジェクトのワークスペースを定義するために使用するものです。

モノレポのルート内で、pnpm-workspace.yaml ファイルを開き、次を追加します。

エンドツーエンドテストを記述するプロジェクトがpnpmモノレポに登録され、テストライブラリのセットアップを開始する準備ができました。

Playwrightのインストールと初期化

この記事では、Playwright を使用してエンドツーエンドテストを実行します。

注意:Cypressや他のより成熟したツールではなく、なぜPlaywrightなのでしょうか?この記事の後半で強調表示されるPlaywrightの非常にクールな機能がいくつかあり、特定のユースケースにおいてPlaywrightを他と区別しています。

まず、e2e ディレクトリ内に playwright をインストールします。

上記のコマンドを実行すると、プロジェクトに関する一連の質問が表示されます。これらのオプションごとにデフォルトを使用するには、Return キーを押します。

Playwright config options output

「typescript」、「tests」、および「true」と「true」が選択されたオプションであることに注意してください。

注意:Playwrightはテストが実行される複数のブラウザのバイナリをインストールするため、このプロセスのインストール手順には時間がかかる可能性があります。

この構成はプロジェクトの一般的な構造をセットアップしましたが、不要なファイルも含まれています。

次のコマンドを実行して、不要なファイルを削除します。

注意:削除したファイルは、テストを配置する場所と記述方法を示すために使用された単なるサンプルファイルでした。

次に、このプロジェクトはTypeScriptを使用して記述されるため、このフォルダでTypeScriptを初期化します。

この時点で、このプロジェクトでTypeScriptを記述し始め、Playwrightによって提供されるツールにアクセスできるようになりました。次のステップは、Playwrightを構成し、データベース、フロントエンド、およびバックエンドをテスト用に起動するスタートアップスクリプトを記述することです。

テスト環境のセットアップ

エンドツーエンドテストを実行するために必要な主なものは2つあります。

  1. テストの実行時にフロントエンドおよびバックエンドサーバーを自動的に起動するようにPlaywrightを構成する
  2. エンドツーエンドテストを実行する前にテストデータベースを起動するシェルスクリプトを追加する

これらの手順の目標は、単一のコマンドを実行して、データベースを起動し、データベースがオンラインになるのを待機し、フロントエンドおよびバックエンドプロジェクトの開発サーバーを起動し、最後にエンドツーエンドテストを実行する方法を提供することです。

Playwrightの構成

Playwrightを初期化したときに、e2e フォルダに playwright.config.ts という名前の新しいファイルが生成されました。そのファイルの最下部に、webServer という名前の構成オプションがコメントアウトされているのがわかります。

この構成オプションを使用すると、テストを実行する前にWebサーバーを起動するコマンドを含むオブジェクト(またはオブジェクトの配列)を提供できます。また、各オブジェクトにポート番号を提供することもできます。Playwrightは、テストを開始する前に、そのポートでサーバーがアクセス可能になるのを待機するために使用します。

このオプションを使用して、バックエンドおよびフロントエンドプロジェクトを起動するようにPlaywrightを構成します。

playwright.config.ts で、そのセクションのコメントを解除し、次を追加します。

上記の構成の各コマンドでは、pnpmを使用して、--filter フラグを使用してフロントエンドおよびバックエンドプロジェクトで適切な dev スクリプトを実行します。これらのスクリプトは、各プロジェクトの package.json ファイルで定義されています。

注意:pnpmでコマンドを実行する方法の詳細については、ドキュメント を参照してください。

各オブジェクトには、reuseExistingServer キーが true に設定されています。これにより、Playwrightは、テストを実行する前にサーバーが起動されていた場合、実行中のサーバーを再利用する必要があることを認識します。

スタートアップスクリプトの記述

Playwright自体が開発サーバーを起動するように構成されたので、テストデータベースとPlaywrightのテストランナーを単一のコマンドで起動する方法が必要になります。

これを行う方法は、統合テストを実行する前にデータベースを起動するために使用された、このシリーズの以前の記事で記述されたスクリプトと非常によく似ています。

モノレポのルートにある scripts/ フォルダに移動し、run-e2e.sh という名前の新しいファイルを作成します。

このファイルは、スタートアップスクリプトを記述する場所です。

注意:以前の記事で記述されたスタートアップスクリプトを確認するには、scripts/run-integration.sh を参照してください。

このファイルに必要な最初のことは、実行可能にすることです。これにより、ターミナルからファイルを実行できるようになります。

run-e2e.sh の一番上に次を追加します。

注意:この行は shebang 行と呼ばれ、コマンドを実行するためのデフォルトシェルとしてbashを設定するために使用されます。

次に、モノレポのルートから次のコマンドを実行して、ファイルをファイルシステムで実行可能としてマークします。

ファイルが実行可能になったので、実際のスタートアップスクリプトの記述を開始します。

このシリーズの以前の記事で記述されたデータベーススタートアップスクリプトを実行するために、次の行を追加します。

このスクリプトは、プロジェクトのルートにある docker-compose.yml ファイルに基づいてDockerコンテナを起動します。次に、データベースが利用可能になるのを待機し、prisma migrate dev を実行してから、スクリプトを続行できるようにします。

データベースが起動されたら、スクリプトに必要な最後のものは、エンドツーエンドテストを実行することです。

run-e2e.sh の最後に追加します。

上記で追加された行は npx playwright test を実行します。これにより、テストランナーが呼び出されます。このスクリプトを呼び出すコマンドに引数が提供された場合、スクリプトはテストがheadedモードで実行される必要があると想定します。--headed 引数で示されます。これにより、エンドツーエンドテストが実際のブラウザで実行されているのが表示されます。

最後に、スクリプトの最後に、npx playwright show-report が実行されます。これは、テストの結果を表示するWebページを備えたローカル開発サーバーを提供します。

スクリプトが完了したので、最後のステップは、それを実行する方法を構成することです。

e2e フォルダ内の package.json で、scripts セクションに次を追加します。

prisma はこのディレクトリにないため、この package.json ファイルでPrismaスキーマの場所も指定する必要があります。

これにより、ターミナルが e2e フォルダに移動した場合に、エンドツーエンドテストを実行できます。

これをさらに簡単にするために、モノレポのルートにある package.json ファイルに移動し、scripts セクションに次を追加します。

これで、プロジェクトのルートからエンドツーエンドテストを実行できます。

ターミナルが現在 e2e フォルダにあると仮定すると、次はプロジェクトのルートに移動し、テストスクリプトを実行します。

Empty test suite results

テストレポートは空のはずです。テストはありません!

エンドツーエンドテストの記述

Playwrightが構成され、テスト環境の準備が整いました!これで、アプリケーションのエンドツーエンドテストの記述を開始します。

何をテストするか

この記事では、アプリケーションの認証ワークフローに関連するすべてのエンドツーエンドテストを記述します。

注意:GitHubリポジトリの e2e-tests ブランチには、アプリケーション全体の完全なエンドツーエンドテストスイートが含まれています。

エンドツーエンドテストは、ユーザーが実行する可能性のあるアプリケーションのワークフローをテストすることに焦点を当てていることを覚えておいてください。テストを記述するログインページを見てください。

Login page

すぐには明らかにならないかもしれませんが、ユーザーが認証に関して遭遇する可能性のあるシナリオはたくさんあります。

たとえば、ユーザーは

  • ... サインインしていない状態でホームページにアクセスしようとした場合、ログインページにリダイレクトされる必要があります。
  • ... アカウントが正常に作成されたときにホームページにリダイレクトされる必要があります。
  • ... ログインが成功した後、ホームページにリダイレクトされる必要があります。
  • ... ログイン試行が成功しなかった場合、警告される必要があります。
  • ... 既存のユーザー名でサインアップしようとした場合、警告される必要があります。
  • ... 空のフォームを送信した場合、警告される必要があります。
  • ... サインアウトすると、ログインページに戻される必要があります。

この記事では、物事を管理しやすい長さに保つために、これらのシナリオのほんの一部のみのテストを記述します。具体的には、この記事では以下のシナリオについて説明します。

ユーザーは

  • ... サインインしていない状態でホームページにアクセスしようとした場合、ログインページにリダイレクトされる必要があります。
  • ... アカウントが正常に作成されたときにホームページにリダイレクトされる必要があります。
  • ... ログインが成功した後、ホームページにリダイレクトされる必要があります。
  • ... ログイン試行が成功しなかった場合、警告される必要があります。
  • ... 空のフォームを送信した場合、警告される必要があります。

注意:これらのシナリオは、この記事で伝えたい主な概念のすべてをカバーします。他のシナリオのテストを自分で記述してみることをお勧めします!

具体的な目標を設定したので、これからテストの記述を開始します。

テスト例

Playwrightは、アプリケーションを非常に直感的にテストできる豊富なヘルパーとツールのライブラリを提供します。

掲示板にメッセージを投稿できる仮想アプリケーションのサンプルテストを見てください。

上記のテストは、メッセージを投稿すると、Webページに自動的に表示されることを検証します。

これを実現するには、テストはユーザーが目的の結果を達成するために行うフローに従う必要があります。より具体的には、テストは次のことを行う必要があります。

  1. テストアカウントでログインする
  2. 投稿を送信する
  3. 投稿がWebページに表示されたことを確認する

すでにお気づきかもしれませんが、サインインなどのこれらのステップの多くは、何度も繰り返される可能性があります。特に、サインインしたユーザーを必要とする数十(またはそれ以上)のテストスイートでは。

各テストで一連の指示を重複して記述することを避けるために、これらの指示を再利用可能なチャンクにグループ化できる2つの概念を利用します。これらは、ページフィクスチャです。

ページ

まず、ログインページのページをセットアップします。これは基本的に、Webページとのさまざまなインタラクションのセットを、最終的にフィクスチャとテスト自体で使用されるクラスの個々のメンバー関数にグループ化するヘルパークラスにすぎません。

e2e/tests フォルダ内に、pages という名前の新しいフォルダを作成します。

そのフォルダ内に、login.page.ts という名前の新しいファイルを作成します。

ここに、ログインページを記述するクラスを定義します。

ファイルの先頭に、Playwrightによって提供される Page 型をインポートします。

このヘルパー型は、Playwright内で登録されたすべてのテストで使用できる page という名前のフィクスチャを記述します。page オブジェクトは、ブラウザ内の単一のタブを表します。記述するクラスは、ブラウザページと対話できるように、コンストラクタにこの page オブジェクトが必要です。

login.page.ts で、Page 型の page 引数をコンストラクタが取る LoginPage という名前のクラスを追加してエクスポートします。

ブラウザページへのアクセス権があれば、このページに固有の再利用可能なインタラクションを定義できます。

まず、アプリケーションの /login ページに移動する goto という名前のメンバー関数を追加します。

注意page オブジェクトで使用可能な関数の詳細については、Playwrightのドキュメントを参照してください。

次に、ログインフォームに入力する2番目の関数を追加します。

このチュートリアルでは、これらはログインページに必要な唯一の再利用可能な一連の指示です。

次に、フィクスチャを使用して、この LoginPage クラスのインスタンスを各テストに公開します。

フィクスチャ

上記のテスト例を思い出してください。

ここでは、page オブジェクトが test 関数のコールバック関数のパラメータからデストラクチャリングされています。これは、前のセクションで参照されたPlaywrightによって提供される同じフィクスチャです。

Playwrightには、既存の test 関数を拡張してカスタムフィクスチャを提供できるAPIが付属しています。このセクションでは、LoginPage クラスを各テストに提供できるフィクスチャを記述します。

ログインページフィクスチャ

モノレポのルートから始めて、e2e/testsfixtures という名前の新しいフォルダを作成します。

次に、その新しいフォルダに auth.fixture.ts という名前のファイルを作成します。

そのファイルの先頭に、base という名前を使用して、Playwrightから test 関数をインポートします。

ここでインポートされた変数は、カスタムフィクスチャで拡張するデフォルトの test 関数です。ただし、この関数を拡張する前に、追加するフィクスチャを記述する type を定義する必要があります。

次のものを追加して、LoginPage クラスのインスタンスをテストに提供する loginPage という名前のフィクスチャを記述します。

これで、その型を使用して test 関数の型を拡張できます。

base.extend 関数のオブジェクトパラメータ内で、loginPage プロパティを記述するIntelliSenseがあることがわかります。

Login page intellisense

このプロパティは、新しいカスタムフィクスチャを定義する場所です。値は、2つのパラメータを持つ非同期関数になります。

  1. test 関数で使用可能なすべてのフィクスチャを含むオブジェクト。
  2. LoginPage のインスタンスのみをパラメータとして期待する use 関数。この関数は、LoginPage クラスのインスタンスをすべてのテストに提供します。

この関数の本文は、page フィクスチャを使用して LoginPage クラスをインスタンス化する必要があります。次に、インスタンス化されたクラスの goto 関数を呼び出す必要があります。これにより、loginPage フィクスチャがテスト内で使用されるときに、ブラウザの開始点がログインページになります。最後に、use 関数は、loginPage 変数を入力として呼び出す必要があります。これにより、インスタンスを新しいフィクスチャを使用するテストに提供します。

以下の更新は、上記で説明した変更を実装します。

ここで行う最後のことは、Playwrightによって提供される関数である expect という名前の関数もエクスポートすることです。これにより、テストの期待値を設定できます。これにより、testexpect を同じ場所から簡単にインポートできます。

ファイルの最後に expect エクスポートを追加します。

最初のカスタムフィクスチャが完成し、テストで使用する準備ができました!ただし、それを行う前に、テストスイートでは、認証機能が動作していることを検証するために、テストデータベースにユーザーが存在する必要があります。これを行うには、次のものを処理するフィクスチャをさらにいくつか追加する必要があります。

  • 各テストに固有のログイン資格情報を生成する
  • 各テストのテストアカウントを作成する
  • テストコンテキストのローカルストレージデータへのアクセスを提供する
  • 各テスト間でテストデータをクリーンアップする

ユーザー資格情報フィクスチャ

まず、各テストに固有のログイン資格情報を生成するフィクスチャを作成します。

e2e/fixtures/auth.fixture.ts で、インポートステートメントの下に username プロパティと password プロパティを持つ UserDetails という名前の type を追加します。

AuthFixtures 型内でこの型を使用して、新しい user_credentials プロパティを記述します。

これで、test オブジェクトは user_credentials フィクスチャを処理できるようになりました。このフィクスチャは、次の3つのことを行います。

  1. ランダムなユーザー名とパスワードを生成する
  2. 各テストのユーザー名とパスワードを含むオブジェクトを提供する
  3. Prismaを使用して、生成されたユーザー名を持つデータベースからすべてのユーザーを削除する

フィクスチャは Faker を使用してランダムデータを生成するため、最初に e2e フォルダ内にFakerライブラリをインストールする必要があります。

このフィクスチャで生成された資格情報は、多くの場合、UIを介して新しいアカウントを作成するために使用されます。テストデータベースに古いデータを残さないようにするには、テスト間でこれらのアカウントをクリーンアップする方法が必要です。

Playwrightのクールな点の1つは、Nodeランタイムで実行されることです。つまり、Prisma Clientを使用して、テストとフィクスチャ内でデータベースと対話できます。これを利用して、テストアカウントをクリーンアップします。

e2e/tests 内に helpers という名前の新しいフォルダーを作成し、prisma.ts という名前のファイルを追加します。モノレポのルートに戻り、次のコマンドを実行します。

新しいファイル内で、PrismaClient をインポートし、インスタンス化されたクライアントをエクスポートします。

auth.fixture.ts ファイルの先頭に、prismafaker をインポートします。

これで、user_credentials フィクスチャーを作成するために必要なツールがすべて揃いました。

test オブジェクトのフィクスチャーのセットに以下を追加して、テストクレデンシャルを生成、提供、およびクリーンアップするフィクスチャーを定義します。

: Prisma は、生成されたユーザーがデータを生成するために使用された場合に備えて、ここで削除するために使用されます。これはすべてのテストの最後に実行されます。

これで、このフィクスチャーをテストで使用して、一意のクレデンシャルセットにアクセスできます。これらのクレデンシャルは、データベース内のユーザーとはまだ一切関連付けられていません。

アカウントフィクスチャー

テストから実際のユーザーにアクセスできるようにするには、生成されたクレデンシャルで新しいアカウントを作成し、それらの詳細をテストに提供する account という名前の別のフィクスチャーを作成します。

このフィクスチャーは、カスタム user_credentials フィクスチャーを必要とします。クレデンシャルを使用してサインアップフォームに入力し、一意のクレデンシャルでフォームを送信します。

このフィクスチャーがテストに提供するデータは、新しいユーザーのユーザー名とパスワードを含むオブジェクトです。

AuthFixtures 型に UserDetails 型の account という名前の新しい行を追加します。

次に、次のフィクスチャーを test オブジェクトに追加します。

テストでこのフィクスチャーを使用すると、データベースに存在するユーザーのクレデンシャルが得られます。テストの最後に、ユーザーは削除されます。これは、このフィクスチャーが user_credentials フィクスチャーを必要とし、クリーンアップ Prisma クエリをトリガーするためです。

ローカルストレージフィクスチャー

アプリケーションの認証に関するテストを実行するために必要な最後のフィクスチャーは、テストブラウザのローカルストレージデータへのアクセスを提供する必要があります。

ユーザーがアプリケーションにサインインすると、その情報と認証トークンがローカルストレージに保存されます。テストでは、そのデータを読み取って、データが正常にそこに到達したことを確認する必要があります。

: このデータは、(かなり面倒ですが)テストから直接アクセスできます。このデータを提供するフィクスチャーを作成すると、データがはるかにアクセスしやすくなります。

e2e/tests/helpers フォルダー内に、LocalStorage.ts という名前の新しいファイルを作成します。

そのファイルで、Playwright によって提供される BrowserContext 型をインポートします。

ローカルストレージアクセスを提供するために、context という名前の別のフィクスチャーをクラスでラップします。このプロセスは、以前に page フィクスチャーをラップしたクラスと似ています。

次のスニペットを LocalStorage.ts ファイルに追加します。

このクラス内で、getter 関数を 1 つ追加します。この関数は、context フィクスチャーの storageState 関数を使用して、http://localhost:5173 で実行されているサイトのブラウザコンテキストのローカルストレージデータにアクセスします。

: 上記のコードをより深く理解するために、Playwright の context オブジェクトに関するドキュメントを確認してください。

このクラスはローカルストレージに簡単にアクセスする方法を提供しますが、データは依然としてフィクスチャーを介してテストに提供される必要があります。

auth.fixtures.ts に戻り、LocalStorage クラスをインポートします。

次に、AuthFixtures 型に storage という名前の別のプロパティを追加します。その型は LocalStorage です。

最後に、LocalStorage クラスを page フィクスチャーの context でインスタンス化し、use 関数を使用してテストに提供する新しいフィクスチャーを追加します。

このフィクスチャーが完成したので、次のセクションでテストするすべてのシナリオに対処する準備ができました。

: e2e-tests GitHub リポジトリのブランチでは、フィクスチャーのセットアップが少し異なることに気付くでしょう。フィクスチャーとページの役割を明確にするために、この記事では以下が異なります。

  • TypeScript エイリアスは、インポート URL を短縮するために使用されていません。
  • base.fixture.ts ファイルは、auth.fixture.ts ファイルのベースフィクスチャーとして、ファイル間でプロパティを共有するために使用されていません。この記事で使用されているフィクスチャーファイルは 1 つだけであるためです。

テスト

最初に作成するテストは、ログインしていないユーザーがホームページにアクセスしようとすると、ログイン画面にリダイレクトされることを検証します。

認証されていないユーザーがログイン画面にリダイレクトされることを確認する

まず、e2e/testsauth.spec.ts という名前の新しいファイルを作成します。

このファイルの先頭に、auth.fixture.ts ファイルから test 変数と expect 変数をインポートします。

カスタム test オブジェクトにアクセスできるようになったので、その describe 関数を使用してテストスイートを記述します。

この最初のテストでは、カスタム loginPage フィクスチャーを使用する必要はありません。ログインページから開始しないためです。代わりに、デフォルトの page フィクスチャーを使用して、ホームページへのアクセスを試み、ページがログイン画面にリダイレクトされることを検証します。

これを実現するために、次のテストを追加します。

これでテストスイートを実行すると、1 つの成功したテストが表示されるはずです。

Successful test

テストはデフォルトで 3 つの異なるブラウザで実行されるため、3 行が表示されます。

: 次のテキストを含むエラーが表示された場合: 'browserType.launch: Executable does not exist at ...'e2e フォルダー内で npx playwright install を実行してみてください。次に、テストを再度実行します。このエラーは、ターゲットブラウザがダウンロードされなかった場合に発生します。

ユーザーが誤ったクレデンシャルでサインインした場合に警告されることを確認する

アプリケーションのログインページで、ユーザーが誤ったクレデンシャルでサインインしようとすると、問題があったことを知らせるメッセージが画面にポップアップ表示されるはずです。このテストでは、その機能が動作していることを検証します。

Invalid login attempt

右下のポップアップに注目してください。

このテストを開始するには、page フィクスチャーと loginPage フィクスチャーを取り込むテストをテストスイートに追加します。

: loginPage フィクスチャーがこのテストに含まれているため、テストのページはアプリケーションのログインページから開始されます。

次に、LoginPage クラスの populateForm 関数を使用して、無効なログインクレデンシャルのセットでログインフォームに入力します。

最後に、page オブジェクトの click 関数を使用してログインボタンをクリックし、リクエストが完了するのを待って、ポップアップが表示されることを確認します。

エンドツーエンドテストを実行すると、別の成功したテストのセットが表示されるはずです。

Two successful tests

ユーザーが空のフォームを送信しようとした場合に警告されることを確認する

このテストは、ログインページから開始してログインフォームを送信するという点で、前のテストと非常によく似ています。唯一の違いは、フォームが空である必要があり、エラーメッセージに次のテキストが含まれている必要があることです: 'Please enter a username and password'

次のテストを追加して、期待されるエラーメッセージが表示されることを確認します。

: このテストでは、click 関数は loginPage.page プロパティを介してアクセスされます。これは、変数が未使用になったときに発生する ESLint 警告を取り除くためだけに実行されます。

エンドツーエンドテストを実行すると、3 番目の成功したテストのセットが表示されるはずです。

Three sets of successful tests

ユーザーが新しいアカウントを作成した後、ホームページにリダイレクトされることを確認する

これまで、作成したテストは、ユーザーがサインインしていないか、サインインできなかったことを前提としていました。

このテストでは、ユーザーがサインアップフォームから新しいアカウントを正常に作成したときに、ホームページにリダイレクトされることを検証します。

user_credentialsloginPagestorage、および page フィクスチャーを取り込む新しいテストをスイートに追加します。

このテストで最初に行う必要があるのは、一意のユーザークレデンシャルでサインアップフォームに入力することです。user_credentials フィクスチャーには、このテストに固有のデータがあるため、これらの値を使用します。

次のスニペットを追加して、サインアップフォームに入力して送信します。

この時点で、テストはサインアップフォームに入力し、サインアップボタンをクリックします。それが起こると、ブラウザはホームページにリダイレクトされ、ユーザーの詳細が 'quoots-user' という名前のキーでローカルストレージで使用可能になるはずです。

リダイレクトが発生し、ユーザーデータがローカルストレージで使用可能であることを確認するために、次を追加します。

すべてがうまくいけば、実行すると 4 番目の成功したテストのセットが表示されるはずです。

Four sets of successful tests

: このテスト中に作成されたテストアカウントは、テスト完了後にクリーンアップされることを覚えておいてください。これを検証するには、クエリロギングe2e/tests/helpers/prisma.ts でオンにして、テストを再度実行し、クリーンアップクエリを確認してみてください。

ユーザーがサインインした後、ホームページにリダイレクトされることを確認する

この最後のテストは前のテストと似ていますが、ユーザーアカウントがすでにデータベースで使用可能であることを前提としています。新しいアカウントを作成する代わりにログインし、ユーザーがホームページに到達することを検証します。

新しいアカウントを生成する必要があり、一意のクレデンシャルのセットだけではないため、このテストには user_credentials フィクスチャーではなく、account フィクスチャーを含める必要があります。

このテストの手順セットは、user_credentials 値を使用するのではなく、account オブジェクトの値を使用してログインフォームに入力する点を除いて、前のテストとほぼ同じです。

これでテストスイートを実行すると、5 番目の成功したテストのセットが表示されるはずです。

Set of five successful tests

Playwright を選ぶ理由

エンドツーエンドテストの作成と実行を支援するツールはたくさんあります。これらのツールの多くは非常に成熟しており、意図されたことを実行するのに優れています。

では... なぜこの記事では、より成熟したツールではなく、比較的新しいエンドツーエンドテストツールである Playwright を使用するのでしょうか?

この記事で Playwright がツールとして選ばれた理由はいくつかあります。

  • 使いやすさ
  • 拡張可能な API
  • 柔軟なフィクスチャーシステム

この記事では、作成したテストの重要な側面は、テスト固有のデータをセットアップし、後でそのデータをクリーンアップできるようにするフィクスチャーの実装でした。

Playwright の直感的で拡張可能なフィクスチャーシステムのおかげで、これらのフィクスチャーで Prisma Client を直接インポートして使用し、データベースでデータを作成および削除することができました。

拡張性と開発者エクスペリエンスは、Prisma が非常に重要視しているものです。Playwright とそのフィクスチャーを拡張する簡単で直感的なエクスペリエンスは、ツールを決定する上で大きな役割を果たしました。

: これは、他のツールが「悪い」と言っているわけではありません。上記の意見は、この記事で提示された特定のユースケースに Playwright が特によく適合したことを単に表明しています。

まとめと今後の展望

エンドツーエンドテストにより、手動で行う必要があった種類のテストを自動化できます。一連の手順を通じて、アプリケーションをナビゲートし、目的の動作が正しく機能することを確認できます。

この記事を通して、あなたは

  • エンドツーエンドテストとは何かを学びました
  • エンドツーエンドテストを保持するためのプロジェクトを pnpm でセットアップしました
  • テスト環境を構成およびスクリプト化しました
  • テストでのコードの重複を避けるために、フィクスチャーページを作成しました
  • アプリケーションの認証ワークフローを検証するための一連のテストを作成しました

このチュートリアルでは、多くのことをカバーしました!GitHub リポジトリを見て、アプリケーション全体をカバーするエンドツーエンドテストの完全なスイートを確認することをお勧めします。

このシリーズの次の最終セクションでは、GitHub リポジトリに変更をプッシュするときにユニットテスト、統合テスト、およびエンドツーエンドテストを実行する CI/CD パイプラインをセットアップします。

次回の投稿をお見逃しなく!

Prisma ニュースレターにサインアップ