PuppeteerによるUIテストが本当に得意なこと

  • ブラウザの直接制御。 スクリーンショット、PDF出力、ネットワークの傍受、パフォーマンストレース。ブラウザに特定の動作をさせたいとき、これが最短の手段です。

  • スクレイピングと自動化。 Puppeteerの用途のかなりの部分はテストですらなく、そうした用途で非常に優れた力を発揮します。

  • 小さく、習得しやすいAPI。 API全体を頭に入れておけます。これは本来もっとあってよいはずの、珍しい長所です。

ブラウザテストスイートにかかる3つのコスト

  • セレクタは壊れます。 機能的には何も変わっていないリデザインでも、スイートは失敗に転じます。保守の時間は、実際にはその大半がここに費やされます。

  • 待機は繊細です。 固定の待ち時間は遅いうえに、不安定さも解消しません。正しい待機には、何を待つべきかを把握している必要があります。テストが不安定になる原因の多くは、ここに行き着きます。

  • カバレッジは人が書くものです。 カバーできるのは誰かが書いた範囲、つまり壊れるフローではなく、書き手が関心を持ったフローです。

何を自動化するかを決める

最も重要な機能から着手したくなるものです。しかし、より有効な判断基準は、その機能がどれだけ静かに壊れるかです。決済フローの不具合は騒がしく、1時間以内に報告が上がってきます。エクスポート、招待、設定画面の不具合は静かです。そして、静かな不具合こそ真っ先に自動化する価値があります。

2つ目の基準は、どれだけ頻繁に変更されるかです。スプリントごとに変わるフローは、得られる効果より保守コストのほうが大きくなります。対象にするのは、仕様が落ち着いてからで構いません。

最も時間を節約できる3つの習慣

  • 安定した属性を使う。 CSSのパスではなく、テスト専用の属性を指定します。この一点を変えるだけで、リデザインによる破損のほとんどがなくなります。

  • 時間ではなく、状態を待つ。 待つ対象は要素やレスポンスであり、何ミリ秒といった時間ではありません。

  • リロードしても確認できることを検証する。 成功のトースト表示は、データが保存された証拠にはなりません。

意図ベースの検証が活きる場面

セレクタの破損と、人手で書くカバレッジという問題は、規律を高めれば解決するものではなく、構造的なものです。意図として表現されたステップは、セレクタが耐えられないリデザインを乗り越えます。また、誰かの記憶ではなくプロダクトそのものから生成されたカバレッジには、誰も書こうとは思わなかったフローが含まれます。

これはPuppeteerを否定する議論ではありません。ブラウザの直接制御には、依然としてPuppeteerが適したツールです。ここで主張しているのは、広いカバレッジを手書きすべきではないということです。

ターミナル

npm install -g @testsprite/testsprite-cli
testsprite setup

何もインストールしたくない場合は、ダッシュボードから同じことを実行できます。コマンドラインでできるそのほかの操作はすべて、こちらで確認できます: CLIリポジトリ

Puppeteerのスクリプトを脆くする3つの要因

急いで書いたスクリプトが壊れる理由は、決まって同じ3つです。いずれも、その場で対処すればコストはかかりませんが、後回しにすると大きな代償を払うことになります。

1つ目は、CSSのパスを連ねた指定です。4階層をたどるようなセレクタは、要素そのものではなく画面構造を書き写しているだけなので、誰かがラッパー要素を1つ追加しただけで壊れます。基準にすべきは、その要素がどこにあるかではなく、何であるかを表すものです。

2つ目は、固定の待ち時間です。遅い日でも確実に動くだけの待ち時間は、速い日にも毎回支払わされるコストであり、それでいて最も遅い日には結局失敗します。待つべきは要素、レスポンス、あるいは状態の変化です。

3つ目は、たった今行った操作そのものを検証してしまうことです。保存ボタンを押したあとに、その保存ボタンが存在することを確認しても、何の証明にもなりません。検証すべきは、処理が実際に完了した場合にのみ成立する事実であり、多くの場合それは対象のデータを取得し直すことを意味します。

変更のたびに実行する

パイプラインが他チームの管理下にある場合は、 GitHub App が最も抵抗の少ない方法です。webhookとして動作し、リポジトリには一切変更を加えず、ビルドが新しいバージョンの公開を通知した時点で起動します。代わりにリポジトリ上でチェック結果を見えるようにしたい場合は、 GitHub Actions のステップで同じことができます。

Puppeteerと併用する場合のTestSpriteの位置づけ

Puppeteerは、ブラウザの直接制御、つまりスクリーンショット、PDF出力、ネットワークの傍受、スクレイピングのために残します。TestSpriteが引き受けるのは、人が書く時間を増やしてもスケールしない部分、すなわち何をカバーするかを決め、それを動き続ける状態に保つ作業です。

ステップはセレクタではなく意図として保存されるため、リデザインによる破損のほとんどがなくなります。待機も自動的に処理され、テストごとに調整する必要がありません。カバレッジはプロダクトから生成されるので、誰のリストにも挙がらないような静かなフローも対象に含まれます。

実務上何が変わるかというと、失敗したビルドのうち本物のバグである割合が十分に高く保たれ、メンバーが結果を読み続けるようになります。ブラウザテストスイートが2年目を生き延びられるかどうかを実際に決めるのは、まさにこの点です。

Puppeteerの書籍の無料epubはありますか。

それは出版社次第であり、時期によっても変わります。本ページは書籍の複製ではなく、現時点で実務に使える知見をまとめたものです。

PuppeteerとPlaywrightのどちらを選ぶべきですか。

Playwrightは対応ブラウザが広く、組み込みの待機機構も優れています。Puppeteerはよりシンプルで、Chrome固有の作業やスクレイピングに適しています。

テストの不安定さを減らすにはどうすればよいですか。

安定した属性と状態ベースの待機で、そのほとんどは解消できます。残るのはたいてい、環境そのものが本当に不安定なケースであり、これはどのフレームワークでも解決できません。

UIテストはどれくらいの数を用意すべきですか。

思っているより少なくて構いません。選ぶ基準は、それがどれだけ静かに壊れるかです。無視される大きなスイートより、信頼される小さなスイートのほうが役に立ちます。

Puppeteerとエージェントによる検証は併用できますか。

はい、むしろそれが一般的な構成です。ブラウザの直接制御はPuppeteerに任せ、広いカバレッジは生成されたテストに担わせます。

要点

APIは簡単です。難しいのは、何を選び、どう維持するかです。

PuppeteerによるUIテストの要点は、どのフローを自動化し、それをどう動き続けさせるかにほぼ尽きます。安定した属性を使い、状態を待ち、リロードしても確認できることを検証し、広いカバレッジを手書きしないことです。