Cypress
Cypressは素晴らしいE2Eテストツールです。これを考慮する大きな理由は次のとおりです。
分離インストールが可能です
TypeScriptの定義がそのままの状態で使えます
優れたインタラクティブなGoogle Chromeのデバッグ環境を提供します。これは、UI開発者が手動で作業する方法と非常によく似ています
より強力なデバッグとテストの安定性を実現するコマンド実行セパレーションを持っています(詳細は後述)
より脆いテストでより意味のあるデバッグエクスペリエンスを提供するための暗黙のアサーションがあります(詳細は以下のヒントを参照してください)。
アプリケーションコードを変更することなく、バックエンドのXHRを簡単に模倣して観察する機能を提供します(以下のヒントで詳しく説明しています)。
インストール
このインストールプロセスで提供される手順は、あなたの組織のボイラープレートとして使用できる素敵なe2eフォルダを提供します。
同じ手順を私の youtubeチャンネルで動画で紹介しています。
e2eディレクトリを作成し、cypress、TypeScriptをインストールし、typescriptとcypressの設定ファイルを追加します。
cypressのために別の
e2e
フォルダを作成するのには、いくつかの理由があります:
別のディレクトリや
e2e
を作成すると、package.json
の依存関係を他のプロジェクトと簡単に分離することができます。これにより依存性の競合が少なくなります。テストフレームワークには、グローバルな名前空間を
describe
it
expect
などのもので汚染する慣習があります。グローバルな型定義の競合を避けるために、e2eのtsconfig.json
とnode_modules
をこの特別なe2e
フォルダに保存することをおすすめします。
e2e/package.json
ファイルにいくつかのスクリプトを追加します:
最初のテストをcypress/integration/basic.ts
に書きます:
キーとなるファイルの詳細
e2e
フォルダの下に、次のファイルがあります:
/cypress.json
:Cypressを設定します。デフォルトは空で、必要なのはそれだけです。/cypress
サブフォルダ:/integration
:あなたのすべてのテストより良い構成を作るためにサブフォルダの下にテストを作成することは自由です。例:
/someFeatureFolder/something.spec.ts
最初のテスト
次の内容の
/cypress/integration/first.ts
ファイルを作成します:
開発中に実行する
次のコマンドを使用してcypress IDEを開きます。
実行するテストを選択します。
ビルドサーバーで実行する
ciモードでCypressテストを実行するには、次のコマンドを使用します。
ヒント: UIとテストの間でコードを共有する
Cypressテストはコンパイル/パックされ、ブラウザで実行されます。プロジェクトコードを自由にテストにインポートしてください。
たとえば、UIセレクタとテストの間でID値を共有して、CSSセレクタが壊れないようにすることができます。
ヒント: ページオブジェクトの作成
さまざまなテストがページで行う必要があるすべてのインタラクションに対して便利なハンドルを提供するオブジェクトを作成することは、一般的なテストの慣例です。getterとメソッドでTypeScriptクラスを使用してページオブジェクトを作成できます。
ヒント: 明示的なアサーション
Cypressには、ウェブ用のほんのいくつかのアサーションヘルプが付属しています。例えば、chai-jquery https://docs.cypress.io/guides/references/assertions.html#Chai-jQuery です。 それらを使うには、.should
コマンドを使用して、chainerに文字列として渡します:
You get intellisense for
should
chainers as cypress ships with correct TypeScript definitions 👍🏻
The complete list of chainers is available here : https://docs.cypress.io/guides/references/assertions.html
If you want something complex you can even use should(callback)
and e.g.
ヒント: cypressにはcallbackの呼び出しにも自動リトライ機能があるため、普通の文字列のチェーンと同じように壊れにくいコードを書くことができます。
ヒント: コマンドとチェーン
cypressチェーン内のすべての関数呼び出しはcommand
です。should
コマンドはアサーションです。チェーンとアクションの別々の_カテゴリ_を別々に開始することは慣習になっています:
他の何かのライブラリは、同時にこのコードを評価し、実行します。それらのライブラリは、単一のチェーンが必要になります。それはセレクタやアサーションが混在してデバッグを行うのが難しくなります。
Cypressのコマンドは、本質的に、コマンドを後で実行するためのCypressランタイムへの_宣言_です。端的な言葉:Cypressはより簡単にします
ヒント: より容易なクエリのためにcontains
を使う
contains
を使う下記に例を示します:
ヒント: スマートディレイとリトライ
Cypressはたくさんの非同期のものに対して、自動的に待ち(そしてリトライし)ます。
これにより、テストコードフローに常に任意のタイムアウトのロジックを追加する必要がなくなります。
ヒント: 暗黙のアサーション
Cypressには暗黙のアサーションという概念があります。1つ前のコマンドが原因でそれ移行のコマンドでエラーが発生したときに実行されます。These kick in if a future command is erroring because of a previous command. E.g. the following will error at contains
(after automatic retries of course) as nothing found can get click
ed:
伝統的なフレームワークでは、null
にはclick
がないというような恐ろしいエラーを目にすることでしょう。Cypressの場合、#foo
にはSubmit
が含まれていないという親切なエラーが表示されます。このようなエラーは暗黙のアサーションの一種です。
ヒント: HTTPリクエストを待つ
アプリケーションが作るXHRに必要なすべてのタイムアウトが原因となり、多くのテストが脆くなりました。cy.server
は次のことを簡単にします。
バックエンド呼び出しのエイリアスを作成する
それらが発生するのを待つ
例:
ヒント: HTTPリクエストのレスポンスをモックする
route
を使ってリクエストのレスポンスを簡単にモックすることもできます:
ヒント: HTTPリクエストのレスポンスをアサートする
リクエストのアサートは、モックを作らなくてもroute
やonRequest
/onResponse
を使うことで実現できます。
ヒント: 時間をモックする
wait
を使ってある時間テストを一時停止することができます。自動的に"あなたはログアウトされます"という通知画面をテストする例:
しかし、cy.clock
と時間をモックし、cy.tcl
を使用して時間を前倒しすることが推奨されます:
ヒント: アプリケーションコードのユニットテスト
あなたはCypressを使ってアプリケーションコードを分離してユニットテストを行うことも可能です。
ヒント: ユニットテストにおけるモック
もしあなたがアプリケーショのモジュールをユニットテストしていたら、あなたはcy.stub
を使ってモックを提供することが可能です。例えば、あなたはnavigate
が関数foo
で呼ばれることを確認できます:
foo.ts
下記を
some.spec.ts
で行います
ヒント: コマンド - 実行の分離
たとえば、cy.get('#something')
のようなCypressのコマンド(またはアサーション)を呼び出したとき、関数は実際には何もアクションを行わずに即座に返ります。実際に関数が行うのは、Cypressのテストランナーに対して、あるアクション(この場合はget
)をある時点で実行する必要があると伝えることです。
あなたが行うことは、基本的には、ランナーが将来実行することになるコマンドリストを書くことになります。このようにコマンドと実行が分離されていることは、次のようなシンプルなテストを書くことで確かめることができます。このテストを実行すると、ランナーがコマンドを_実行_する前に、start / between / end
のconsole.log
文がすぐに実行されることがわかります。
このようなコマンドの実行の分離を行うことには、2つの利点があります。
ランナーがコマンドを実行するときに、_脆さに耐えられる_やり方で自動リトライや暗黙のアサーションを実行できる。
非同期に書くコードを同期的に書くことができるため、コードのメンテナンスが難しくなってしまう常に_チェーンする_ような書き方をする必要がなくなる。
ヒント: ブレークポイント
Cypressテストによって生成された自動スナップショット+コマンドログは、デバッグに最適です。とはいえ、それは、あなたが望むならテストの実行を一時停止できます。
まずChrome Developer Tools(愛情を込めてdev toolsと呼ばれています)をテストランナー(macではCMD + ALT + i
/windowsではF12
)で開いていることを確認してください。一度dev toolsを開けば、あなたはテストをリランすることができ、dev toolsは開いたままになります。もしdev toolsを開いていれば、あなたは2つの方法でテストを実行できます:
アプリケーションコードのブレークポイント:
debugger
文をアプリケーションのコードを使うと、テストランナーは通常のweb開発のように、ちょうどそこで停止します。テストコードのブレークポイント: あなたは
.debug()
コマンドを使い、cypressのテスト実行をそこで停止できます。例えば、.then(() => { debugger })
です。あなたはいくつかのエレメントを得ること(cy.get('#foo').then(($ /* a reference to the dom element */) => { debugger; })
)や、ネットワーク呼び出し(cy.request('https://someurl').then((res /* network response */) => { debugger });
)すら可能です。しかし、慣用的な方法は、cy.get('#foo').debug()
です。そして、テストランナーがdebug
で止まったときに、get
をコマンドログでクリックすると自動的にconsole.log
にあなたが知りたい.get('#foo')
に関する情報が出力されます(そして、デバッグに必要な他のコマンドでも似たようなものです)
ヒント: サーバーを開始してテストを実行する
もしテストの前にローカルサーバーを起動したい場合はstart-server-and-test
https://github.com/bahmutov/start-server-and-test を依存関係に追加できます。それは次の引数を受け取ります。
サーバーを実行するためのnpmスクリプト
サーバーが起動しているかをチェックするためのエンドポイント
テストを初期化するためのnpmスクリプト
package.jsonの例:
リソース
ウェブサイト:https://www.cypress.io/
あなたの最初のCypressテストを書く(Cypress IDEの素晴らしいツアー):https://docs.cypress.io/guides/getting-started/writing-your-first-test.html
CI環境を設定する(例えば、そのまま
cypress run
で動く提供されたdockerイメージ):https://docs.cypress.io/guides/guides/continuous-integration.htmlレシピ(説明付きのレシピの一覧です。レシピのソースコードに移動するには見出しをクリックしてください): https://docs.cypress.io/examples/examples/recipes.html
Visual Testing: https://docs.cypress.io/guides/tooling/visual-testing.html
Optionally set a
baseUrl
in cypress.json to prevent an initial reload that happens after firstvisit
.Code coverage with cypress: Webcast
最終更新