TypeScriptサイプレステストのすべてのもの#frontend @ twiliosendgrid
公開: 2020-11-14Twilio SendGridでは、ほとんどのフロントエンドWebアプリケーション、特に新しいページと機能をTypeScriptとReactで記述して、コードベースの型チェック、保守性、およびドキュメント化を改善しています。 2年以上前に初めてサイプレステストを書き始めたとき、ページオブジェクト、ヘルパー、スペックファイルのほとんどはまだJavaScriptで実装されており、ほとんどがサイプレスバージョン3.xxでした。最近のテストはすでにTypeScriptで書かれていますが、まだTypeScriptに変換して移行するファイルがたくさんありました。
コンポーネント、単体テスト、およびCypressE2Eテストを完全に入力することのメリットを享受したかったのです。 プロセスを簡単にしたのは、Cypress 4.4.0以降のTypeScriptのサポートを利用するために、新しいバージョンのCypressに移行することでした。
一歩下がって、E2Eテストの作成についてより一般的に考える方法を学びたい場合は、このブログ投稿をチェックしてください。 さまざまな環境でサイプレステストを作成する前に使用または実行した最も一般的なことの1000フィートの概要も確認したい場合は、サイプレステストにTypeScriptを追加する前に、このブログ投稿を参照してください。 このブログ投稿は、サイプレスのテストに精通しており、以前にAPIを使用したことがあることを前提としています。
入力方法を確認する準備ができたら、最初に、古いバージョンを使用している場合にCypressにTypeScriptサポートを追加するなどの初期変更を見てみましょう。
Cypress3.xから>=4.4.0への移行
Cypressバージョン3.xxから4.4.3でTypeScriptを使用するようにCypressインフラストラクチャを既に構成している場合は、 plugins/index.js
で適切なWebpackプリプロセッサ構成を設定する際に試行錯誤を経験した可能性があります。 Twilio SendGridチームの場合、 plugins
とsupport
フォルダー内のJavaScriptファイルである必要がある特定のファイルに関するいくつかの落とし穴があり、デバッグが難しいサイプレスエラーが表面化しました。 何かが機能するようになると、次のようになります。
以前のバージョンの3.xxからアップグレードした後、Webpackプリプロセッサー構成を削除し、 plugins/index.js
ファイルをindex.ts
ファイルに置き換え、Cypressフォルダーのtsconfig.json
を少しいじくり回すことができました。 Cypressフォルダー内のTSファイル( some_page.spec.ts
、 index.d.ts
、 page_object.ts
など)を使用する– Webpackプリプロセッサー構成は不要で、機能しました。 以下に示すように、独自のWebpackプリプロセッサ構成を管理せず、ファイル全体でTypeScriptのカバレッジを向上させることが、どれほどクリーンで優れているかを嬉しく思います。
TypeScriptのサポートについて説明した後、より適切に入力する方法について学ぶために、サイプレスチームの実世界のアプリケーションの例であるcypress-real-world-appリポジトリを調べました。 cy.task(“pluginName”, { … })
とCypress.env(“someEnvVar”)
関数呼び出しを入力する方法を発見し、ファイルを更新する際のチェーンと入力インテリセンスのサポートを改善しました。 また、付属のTypeScriptドキュメントも調べました。 これにより、 cy.login()
カスタムコマンドなどの入力方法や、 tsconfig.json
構成ファイルの設定方法がわかりました。 サンプルアプリケーションには、参照用のtsconfig.json
もあります。これにより、好みに合わせてカスタマイズするための優れた基本TypeScript構成を提供できます。 サイプレスの最新バージョンを最新の状態に保ち、サイプレスの公式リソースに飛び込んで、タイプ定義ファイルを試してみることをお勧めします。
カスタムコマンドの入力
APIを介したログインを処理するcy.login()
などのグローバルカスタムコマンドを作成して、すべてのスペックファイルで再利用できるようにしました。 これは、ユーザー資格情報を指定して独自のログインカスタムコマンドを入力し、認証トークンを返す方法の例です。
環境変数の入力
開発やステージングなどの複数のテスト環境を処理するために、ステージングなどの現在テストしている環境を保持する「testEnv」、バックエンドAPIホストを保持する「apiHost」などの環境変数の構成を利用しました。変数。 Cypress.env()
呼び出しを入力して、このような環境変数値の使用に依存する関数やその他のオブジェクトをより適切に入力できます。
プラグインの入力
API呼び出し、サービスのポーリング、テストメールの受信トレイで一致するメールのチェックなどを処理するために、多くのcy.task()
プラグイン関数を作成しました。 以前は、 cy.task().then((data) => {})
のようにこれらの関数呼び出しのいずれかをチェーンする場合、チェーンされたデータサブジェクトはany
またはunknown
として入力されていましたが、これはTypeScriptファイルには適していませんでした。 サイプレスの例を通じて、プラグイン名と関数呼び出しで渡された引数に基づいてプラグインをより適切に入力する方法を発見しました。 これにより、TypeScriptファイルは連鎖データ型を検出できました。
私たちが経験した微妙な問題の1つは、プラグインの名前と引数が入力方法と正確に一致する必要があることでした。エディターでチェーンされた.then()
タイプとcy.task()
引数オブジェクトにカーソルを合わせて2倍にすることが重要であることがわかりました。タイプが正しく一致していることを確認してください。 cy.getCookie(“auth_token”).its(“value”).then((token) => { })
やcy.wrap(data).then((data) => {})
、 cy.task(..., { token, data })
関数引数として渡す前に、これらの連鎖データ引数も入力する必要があります。そうしないと、 cy.task(...).then((data) => { })
が表示されます。 cy.task(...).then((data) => { })
データ部分がany
またはunknown
として入力されました。 .its(“value”).then((token: string) => {})
やcy.wrap(data).then((data: DataType) => {})
cy.task()
引数オブジェクトの一部としてそれらを渡す前に、型が再び機能していることを確認します。
plugins/index.ts
で使用する関数をエクスポートする個別のプラグインTypescriptファイルを作成しました。 プラグインの数が増えるにつれて、これらのプラグイン関数の実装をページまたは機能ごとに整理して、 plugins/index.ts
ファイルを小さく保つことをお勧めします。 plugins/index.ts
ファイルですべてのcy.task(...)
関数を定義すると、一目で読みやすくなるはずです。 最後に、次の方法でこれらのタスク関数をindex.d.ts
に入力できます。
すべてを型宣言ファイルにまとめる
カスタムコマンド、環境変数、およびプラグインのすべてのタイプを、 support
フォルダーのindex.d.ts
ファイルに配置しました。 すべてのサイプレスタイプもメインのTypeScript定義ファイルに配置して、整理しておくことをお勧めします。 Cypressテストコードで使用される外部依存関係で欠落しているタイプをバイパスするために、ライブラリのTypeScript警告を回避するために、declaremodule'some declare module 'some-lib'
を含む「some-lib.d.ts」のようなモジュールファイルを定義することもできます。 TypeScriptのタイプのインポート機能を使用して、他のプラグイン/ utilsファイル内に定義されたタイプ/インターフェースを取り込み、複数のファイルでタイプ定義が重複しないようにすることもできます。 これらのタイプをサイプレス名前空間内に追加し、次の方法で整理できます。
テストフィクスチャオブジェクト、ページオブジェクト、およびスペックファイルを入力する
テスト環境のさまざまなユーザーとメタデータをロードする場合、「testing」や「staging」などの環境変数を「testing」や「staging」の値と組み合わせて「testing」や「テストフィクスチャオブジェクト全体からの「ステージング」オブジェクト。 これらのテストフィクスチャ環境オブジェクトをジェネリックで入力して、すべての仕様を共有するための一貫した構造にすることができます。 テスト環境ごとに、テストのジェネリック型を使用して同じユーザー資格情報とメタフィールドを設定し、必要な数のプロパティを追加できます。 以下の例を参照してください。
ページオブジェクトの入力と対応するスペックファイルの入力は、使用しているサイプレスコマンド、プラグイン、およびその他のユーティリティによって異なります。 ほとんどの場合、ページオブジェクトまたはスペックファイルを入力するのに、対応するJavaScriptファイルから多くの変更を加える必要はありません(プラグインと環境変数の呼び出しをすでに入力していると仮定します)。 場合によっては、定義したページオブジェクトヘルパー関数でいくつかの引数を入力する必要がある場合や、 cy.request()
呼び出しから返されるresponse.body as SomeType
as
で入力する必要がある場合があります。 全体として、VSCodeなどのエディターは、TypeScriptの警告を補正するためにスペックファイルにタイプを追加しなくても、 cy.task()
またはcy.customCommand()
呼び出しの連鎖タイプを自動検出できます。
これは、いくつかのヘルパー関数と、ページオブジェクト、ログインカスタムコマンド、およびプラグインタスクを使用するスペックファイルを含むページオブジェクトの一部の例です。
結論
サイプレステストにTypeScriptを追加することで、バグを回避し、サイプレステストを作成する際の開発者エクスペリエンスを向上させることができました。 cy.task()
、 Cypress.env()
、およびcy.customCommand()
関数呼び出しを使用すると、関数の引数と出力の型チェックが向上し、VSCodeなどのIDEのコード補完を利用できます。
重要なのは、 index.d.ts
ファイルなどの独自の型宣言ファイルを作成することです。このファイルでは、カスタムコマンド、環境変数、およびタスクプラグイン関数に基づいて、「Cypress」および「Chainable」インターフェイスをオーバーライドまたは拡張できます。を使用します。 ページオブジェクトとスペックTypeScriptファイルで、これらのサイプレス関数を利用して、予想される入力タイプと出力タイプの定義にカーソルを合わせるか、それに従うことができます。
さらに、最新バージョンではTypeScriptがすぐにサポートされているため、CypressでTypeScriptを使用してみてください。 関数をより明確に文書化し、誤ったAPIの使用を回避するのに役立つかどうかをテストします。 TypeScriptテストはJavaScriptCypressテストと同じように見える可能性が高いため、一度にいくつかのテストを着実に変換して、アプローチを比較対照することができます。
サイプレスのテストから学んだことに関連するその他の投稿に興味がある場合は、次の記事を確認してください。
- E2Eテストを書くときに考慮すべきこと
- サイプレステストの作成の1,000フィートの概要
- サイプレステストでの電子メールフローの処理
- サイプレステストを構成、整理、統合するためのアイデア
- サイプレステストとDocker、Buildkite、およびCICDの統合