Playwright APIテストの優れている点
第一級のリクエストコンテキスト。 API呼び出しにブラウザのページは不要なため、検証はリクエストと同じ速度で実行されます。
再利用できる認証済みの状態。 一度サインインして状態を保存し、それを複数のテストで再利用します。旧来のフレームワークと比べて、実用上最も大きな進歩がこれです。
両方のレイヤーで同じランナー。 レポーターは1つ、CIジョブも1つ、実行方法も1つです。自分が保守する立場になると、この価値は過小評価されがちです。
すでにPlaywrightを日常的に使っていて、APIのカバレッジもほどほどで足りるチームにとって、これは本当に良い選択肢です。
Playwrightだけでは足りなくなるところ
保存した状態は古くなる
保存された認証情報はスナップショットです。トークンは失効し、その更新ロジックを書いて保守するのは自分の仕事になります。
データの依存関係
どのテストが別のテストに必要なレコードを作るのか、そして最初のテストが失敗したらどうなるのか。
フィクスチャ、実行順序、スキップという形で、手作業で書き表すことになります。
並列実行下でのクリーンアップ
Playwrightは設計上テストを並列実行するため、パターンに基づくクリーンアップは安全ではありません。
クリーンアップは、各実行が作成したものに紐づける必要があります。
これらはいずれもフレームワークの欠陥ではありません。どのランナーも代わりに解決してはくれないAPIテストの領域であり、長期的なコストの大半を占める部分でもあります。
思いついたものだけで形づくられるカバレッジ
より見過ごされがちな問題は、手書きのテストスイートが誰かの記憶に残っていたエンドポイントしかカバーしないことです。エラーコード、境界値、めったに使われないパラメータこそが壊れるケースであり、夜11時に誰も書こうとしないケースでもあります。
仕様書から、あるいは稼働中のサービスを探索してカバレッジを生成すると、カバーする範囲の形そのものが変わります。これは個々のアサーションの書き心地よりも大きな意味を持ちます。
専用レイヤーが引き受けること
どのツールを使うにせよ、APIテストスイートが最初の1年を生き延びられるかどうかは4つの要素で決まります。失効するセッション、実行時にしか存在しない値、互いに依存する呼び出し、そして誰も片付けないレコードです。TestSpriteはこれらをAuto-Authentication、Dynamic Variables、Dependency Chains、Auto-Cleanupと名付けており、その仕組みは APIテストのドキュメント で解説しています。
ストレージ状態では持ちこたえられないこと
認証済みのストレージ状態を再利用できることは、PlaywrightがAPIテストにもたらす使い勝手の面で最大の利点ですが、それを土台にする前に知っておくべき落とし穴が3つあります。
保存された状態はスナップショットなので、トークンの有効期間が短いものは実行の途中で失効し、認可のバグとまったく同じように見える失敗を引き起こします。また、保存された状態は1人のユーザーに属するため、権限チェックのために2つ目のアカウントが必要なテストは、別途用意しなければなりません。さらに、保存された状態はそれが作られた環境も一緒に取り込むため、ローカルで作った状態ファイルのままテストスイートをステージングに向けると、原因のわかりにくい種類の失敗が生じます。
いずれも、ストレージ状態の利用を避ける理由にはなりません。ただしこうした事情があるからこそ、プロジェクトにはやがて、ユーザーごと・環境ごとに状態ファイルを管理する小さなモジュールが育っていきます。そしてその時点で、作らずに済ませようとしていたものを自分で作り始めていることになります。
両者を併用する
ブラウザのフローと、1つのテストで本当に両方の層が必要になるクロスレイヤーの検証には、Playwrightを使い続けてください。API全体の網羅は、生成されたカバレッジに任せます。両者は互いを意識することなく、同じパイプラインから実行できます。
GitHub App は、TestSpriteのダッシュボードで設定するWebhookです。パイプラインがすでに発行しているデプロイイベントを検知するため、リポジトリ側には何の変更も必要ありません。
GitHub Actions は、ターミナルから設定して、自分のワークフローの中にステップを組み込みます。最新のコマンドは CLIリポジトリにあります。
TestSpriteが引き継ぐ範囲
Playwrightはブラウザのフローとクロスレイヤーのテストを担当します。TestSpriteが引き受けるのは網羅性と状態管理であり、リクエストコンテキストがどれだけ優れていても自分の手元に残り続ける部分です。
具体的には、ユーザーごと・環境ごとに保守するストレージ状態のモジュールの代わりにAuto-Authenticationを、フィクスチャや実行順序の取り決めの代わりにDependency Chainsを、並列実行下でも安全でなければならないプレフィックスベースの削除の代わりに各実行に紐づいたAuto-Cleanupを使うということです。カバレッジは、誰かが書くのを覚えていた範囲からではなく、仕様書と稼働中のサービスから生成されます。
その結果、半日で書いたヘルパーコードが誰かの継続的な責任になることはなくなります。書くこと自体ではなく、この継続的な責任こそが常に本当のコストでした。
PlaywrightだけでAPIテストは十分でしょうか。
対象となる範囲がほどほどで、それを保守するチームがあるなら十分です。問題は、セッションの更新、依存関係の順序制御、並列実行でも安全なクリーンアップを自分たちで抱える気があるかどうかです。これらは必ずついて回ります。
ストレージ状態は認証の問題を解決しますか。
解決するのは繰り返しの手間であって、失効ではありません。保存された状態はスナップショットであり、それを更新する何かが依然として必要です。
2つのテストスイートで認証情報を共有できますか。
共有すべきは認証情報の取得元であって、セッションではありません。各レイヤーが自前でセッションを取得すれば、一方の失敗がもう一方に波及しません。
コントラクトテストはどうでしょうか。
用途の異なる道具です。コントラクトテストは2つのサービスがスキーマについて一致していることを確認するものであり、ここで扱っているのは稼働中のサービスが正しく振る舞うかどうかの確認です。
生成されたカバレッジは既存のテストと重複しませんか。
多少の重複は問題なく、コストもかかりません。生成されるレイヤーは網羅性に向け、意図して仕様化したフローには手書きのテストを残してください。