エラーをひとつも返さずに、ページは止まっていることがある
問い合わせフォームは応答し、見た目も正常で、何も送信していませんでした。インデックス済みの2つのルートは200を返し、中身は空でした。何も失敗していないので、死活監視では検知できません。欠けているのは「最後の一歩」です。
死活監視が答えるのは「サーバーは応答したか」というひとつの問いだけです。良い 問いですが、お客様が気にしているのはそこではありません。お客様が知りたいのは、 自分がやろうとしたことが本当に実行されたかどうかです。
私たちはその穴を、自分たちのサイトで見つけました。いちばん見つけたくない場所です。
200を返していた3つの障害
問い合わせフォームは何も送信していませんでした。 ナビゲーションの
「Contact」は、手を加えていないUIテンプレートで作られたページにつながっていました。
stateもname属性もない入力欄が4つと、送信ハンドラーのない「Submit」ボタン。
表示は完璧でした。何も検証せず、何も送らず、訪問者には何の問題も伝えません
——ブラウザから見れば、実際に何も問題がなかったからです。
インデックス済みの2つのルートが空でした。 ひとつは587行のコードのうち約470行が コメントアウトされ、画面4つ分の高さの空のコンテナを描画していました。サイトマップ には優先度0.9で載り、フッターから5本のリンクが張られていました。もうひとつは、 画面7つ分のdivの中に「Web Development」という文字があるだけ。どちらも200を返し、 どちらもGoogleのインデックスに入っていました。
ページを開くたびに5つのアイコンが404になっていました。 <head>とWebマニフェスト
はapple-touch-icon.png、ファビコン2つ、Android用アイコン2つを要求していましたが、
5つのファイルはどれも存在しませんでした。どのページを開いても5件のリクエストが
失敗し、それでもページは普通に表示されていました。
なぜステータスコードでは見逃すのか
ステータスコードが表すのは通信であって、取引ではありません。200 OKは、サーバーが
返すものを見つけたという意味です。それが役目を果たしているかどうかは何も語りません。
このパターンはWebページに限りません。
200を返してペイロードを捨てるWebhook。- 決済が確定する前に完了画面を出すチェックアウト。
- テンプレートが削除されたメールサービスに、正常に送信されるフォーム。
- 報告すべきエラーを握りつぶして、終了コード0で終わるバックグラウンドジョブ。
どの場合も監視は緑、ログは静か、そして仕事は行われていません。これはエラーでは なく、受領確認を結果と取り違えている状態です。
代わりに確認すべきこと
役に立つ問いは「応答したか」ではなく**「効果は起きたか」**です。そして効果は、 ほとんどの場合レスポンスとは別の場所にあります。
重要な経路ごとに、観察できる効果を言葉にして、それを確認します。
| 経路 | 弱い確認 | 本当の確認 |
|---|---|---|
| 問い合わせフォーム | ページが200を返す | 受信箱にメッセージが届く |
| ルートの存在 | ステータスコード | <title>と本文の既知の文字列を読む |
| 参照されているアセット | ファイルがリポジトリにある | HTMLが実際に出力しているURLを取得する |
| バックグラウンドジョブ | 終了コード0 | 書き込むはずの行がそこにある |
<title>の確認は少し掘り下げる価値があります。私たちのサイトには7つのプロダクトと
2つのゲームを載せ、それぞれ稼働中のものにリンクしています。自分たちのものだと
思っていた.vercel.appのサブドメイン2つは、初期状態の「Create Next App」ページを
200で返していました。ステータスコードはリンクに問題なしと言い、タイトルを読むと
問題ありと分かりました。
安く済ませる方法
穴の大部分を塞ぐのに、テストスイートは要りません。重要な経路ごとに、効果を名指しする アサーションがひとつあれば十分です。
- デプロイのたびに、本物のブラウザから本物のフォームを一度送信し、受信箱を確認する。
- サイトマップのすべてのURLを取得し、そのページにしかない文字列があるか確かめる。
- HTMLの
<head>で参照しているすべてのアセットを取得し、本文が空でないか確かめる。
どれも数分で書けます。3つそろっていれば、上に挙げたすべてを何か月も早く 見つけられていました。
ここから得たルールはこうです。緑にしかならないチェックは、チェックではない。 テストが失敗するような世界の状態を説明できないなら、そのテストは通信を測っている だけで、心配していたのは最初から通信ではなかったはずです。