Cypress APIテストが本当に得意なこと

  • セットアップとティアダウン。 UIテストに必要な状態を、5つの画面をクリックして回る代わりにAPI経由で作成します。そのほうが速く、安定しており、この機能の正しい使い方です。

  • レイヤーをまたぐアサーション。 画面上で操作を行い、その内容がバックエンドに正しく記録されたことを確認します。これは実在するカテゴリであり、Cypressはこれをきれいに扱えます。

  • 少数のエンドポイント検証。 APIの対象範囲が小さいうちは、同じスイートにまとめておくことは、シンプルさと引き換えに妥当な判断です。

規模の拡大とともに現れる4つの問題

セッションの有効期間

  • トークンがスイートの実行途中で失効し、その失敗はプロダクトの不具合のように見えます。

  • 結局、リフレッシュ処理をサポートファイルに自前で書くことになります。

呼び出し間の値

  • 作成リクエストで得た識別子を削除リクエストまで届ける必要がありますが、Cypressのコマンドチェーンでは、テストをまたいでこれを行うのが扱いにくくなります。

  • そこでハードコードしてしまい、スイートは一度だけ動きます。

実行順序

  • 実際のAPIカバレッジはグラフであり、テストファイルはリストです。そのグラフを手作業で表現する部分に、保守コストが吸い込まれていきます。

4つめはクリーンアップです。レコードが蓄積し、一意性制約が引っかかり始め、データが増えるにつれてページネーションのアサーションがずれていきます。

これらが本当はCypressの問題ではない理由

Cypressは、ブラウザ主導のテストライフサイクルを前提に設計されています。ここまで挙げたものはいずれも、単一のテストの外側、そして単一の実行の外側に存在する状態の話です。すべてサポートファイルで解決できますが、その解決策は、誰かが保守しなければならない小さなフレームワークになります。これが、誰も見込んでいないコストです。

専用のAPIレイヤーが代わりに引き受けること

どのツールを使うにせよ、APIスイートが最初の1年を生き延びられるかどうかは4つの要素で決まります。失効するセッション、実行時にしか存在しない値、互いに依存し合う呼び出し、そして誰も片付けないレコードです。TestSpriteはこれらをAuto-Authentication、Dynamic Variables、Dependency Chains、Auto-Cleanupと呼んでおり、その仕組みは APIテストのドキュメント で解説しています。

サポートファイルがフレームワークに変わる地点

Cypressの中のAPIスイートが、数本のリクエストであることをやめてインフラになる地点には、はっきりとわかる境目があります。流されるのではなく意識的に判断できるよう、それを言語化しておく価値があります。

始まりは、サポートファイルに置いたログインコマンドです。次にトークンのキャッシュ。テストごとにログインするのは遅いからです。次にリフレッシュ処理。実行の途中でキャッシュが古くなるからです。次に、後続のテストから参照できるよう、作成した識別子を保持するヘルパー。次にファイル名に埋め込んだ順序の規約。そして、スイートの後に走り、それらすべてを把握しているクリーンアップタスクが加わります。

どのステップも間違ってはおらず、それぞれがその時点で当然の次の一手です。結果として、サポートディレクトリに数百行のフレームワークが住み着きます。理解しているのは一人だけで、しかも土台にしたランナーの外側にあります。この道筋を早い段階で認識できること、それがこうして書き出すことの価値のすべてです。

採用する価値のある分担

引き続き cy.request は、セットアップ、ティアダウン、そして1つのテストの中で両方の層を本当に必要とする、レイヤーをまたぐアサーションに使ってください。単独のエンドポイントカバレッジと統合カバレッジは、この4つの問題を利用者の宿題ではなく自らの仕事として扱うレイヤーへ移しましょう。

2つのスイートは互いを知っている必要はなく、どちらも同じパイプラインから実行できます。

仕組みそのものよりも、何をきっかけに実行するかが重要です。デプロイのイベントに紐づけておけば、誰かが判断しなくてもすべての変更がチェックされます。 GitHub App はダッシュボードからそれを行い、 GitHub Actions のステップはワークフローの内側からそれを行います。詳細は CLIリポジトリ。

保守しなくてよくなるもの

TestSpriteが置き換えるのは、ここまで述べたサポートファイル製のフレームワークです。Auto-Authenticationがセッションの有効期間を扱います。Dynamic Variablesが、作成リクエストの識別子を削除リクエストまで運びます。Dependency Chainsが、各ケースの必要とするものと生成するものから安全な順序を導きます。Auto-Cleanupは、その実行が作成したものだけを正確に削除します。これが並列実行を安全にしている要素です。

カバレッジが、誰に時間があるかに左右されることもなくなります。テスト計画は、仕様、または稼働中のサービスに対する探索から生成され、手作業ではまず書かれないエラーパスや境界値も含まれます。そして平易な言葉で調整できます。

Cypressは得意なことをそのまま担い続けます。セットアップ、ティアダウン、そして1つのテストの中でブラウザとAPIの両方が本当に必要になる、レイヤーをまたぐ検証です。両者は互いを知らないまま、同じパイプラインから実行されます。

cy.requestはバッドプラクティスですか?

まったくそんなことはありません。セットアップやレイヤーをまたぐ検証には適したツールです。限界があるのは規模の面であって、正しさの面ではありません。

すべてをCypressに置いたままにできますか?

できます。そのうえで、セッション管理、値の受け渡し、実行順序、クリーンアップを自分たちで保守することになります。対象範囲が小さければ見合いますが、それを超えると高くつきます。

Cypressのコンポーネントテストはどうなりますか?

ここまでの話の影響は受けません。コンポーネントテストは別の問いに答えるものであり、今ある場所に置いたままにするのが最善です。

カバレッジの重複はどう避ければよいですか?

問いで分けてください。Cypressは、ユーザーに見えるフローが動くかどうかに答えます。APIレイヤーは、エンドポイントが期待どおりに振る舞うかどうかに答えます。どちらの場所でも通るテストは、コストの安いほうに置きます。

APIレイヤーにソースコードは必要ですか?

不要です。稼働中のサービスに対して動作し、仕様または探索によって何が存在するかを把握します。

要点

cy.requestはセットアップのために使い、APIスイート全体を担わせないでください。

Cypress APIテストは、フィクスチャの用意とレイヤーをまたぐアサーションには非常に優れています。単独のAPIカバレッジが増えてくると、セッション、取得した値、実行順序、クリーンアップが、手作業で保守するフレームワークに変わります。そこが、そのレイヤーを専用に作られた場所へ移すタイミングです。