テストがCIから呼ばれているかを送出バイト列で確かめる
今回やったこと
HTTP応答を扱うテストがリポジトリにあっても、CIから実行されていなければコード変更で既存の機能を壊したときに検知できない。ダッシュボード用サーバーのルートテストがこの状態だったため、workflowから呼び出す配線を追加し、キャッシュ制御とエラー応答を実際に書き出されたバイト列で確認できるようにした。
対象のテストは scripts/matome/test_dashboard_server_routes.py、実装は scripts/matome/dashboard_server.py、実行箇所は .github/workflows/autodraft-lanes.yml にある。現在のworkflowにはテストファイルを実行するステップが記述され、Pythonでそのテストを呼んでいる。今回は、実装とテストコードから確認できる範囲を扱う。
ソースの文字列ではなく、線に出た応答を見る
テストファイルの冒頭には、関数の存在ではなく「実際に線に出るバイト列」を確認する方針が説明されている。テスト用のHandlerをソケットなしで作り、出力先の wfile を io.BytesIO に置き換える。そこに書かれたHTTP応答を読み取るため、ヘッダーが設定されているかだけでなく、ステータス行を含めた送出結果を検査できる。
キャッシュ制御では、HTMLを返す処理が Cache-Control: no-store, no-cache, must-revalidate を出すことを確かめている。HTML応答では共通処理の _no_store() がこのヘッダーを設定し、JSON応答を返す _json() は Cache-Control: no-store を設定する。リアルタイムの状態を見せる画面で古い内容をブラウザーに再利用されると、利用者が現在の状態と誤認するおそれがある。レスポンスに必要なヘッダーが出ているかをテストすれば、設定漏れを回帰として捕まえられる。
エラー応答には別の落とし穴があった。標準ライブラリのHTTPサーバーでは、ステータス行の理由文をlatin-1で送る。そこに日本語やem dashなどlatin-1に含まれない文字が入ると、HTTP 500を返す前に UnicodeEncodeError が起き、接続自体が切れる可能性がある。dashboard_server.py には、送れない文字を置き換えてからエラー応答を作る処理があり、テストは日本語を含むメッセージを渡しても500ステータスが書き出されることを確認する。
h = _make_handler()
dashboard_server.Handler.send_error(h, 500, "boom — 日本語 too")
status, _ = _wire(h)
self.assertIn(" 500 ", status)
この形のテストは、内部でどの関数を呼んだかだけに依存しない。HTTPクライアントに届く境界に近い出力を確認するため、文字コード変換のように送出段階で発生する問題もテスト対象にできる。
CIへの配線を成果物の一部にする
.github/workflows/autodraft-lanes.yml には、ダッシュボードがキャッシュされないことと、500エラーで接続が切れないことを検証するステップがある。ステップは scripts/matome/test_dashboard_server_routes.py を実行する。テストファイル単体の追加ではなく、workflowに接続したことで、通常のCI実行で検査される経路ができた。
テストを書くときは、少なくとも次の三点を一緒に確認するとよい。
- 対象コードとテストがある。
- CIのworkflowがテストを実行する。
- テストが利用者に届く応答や保存結果など、境界で観測できるものを確認する。
今回のテストは外部パッケージを要求せず、標準ライブラリで動くとファイル内に記録されている。これにより、テストを実行するためだけの依存追加を避けられる。ただし、依存が不要であることと、CIで呼ばれていることは別の条件である。ワークフローの条件分岐や対象パスの設定が変われば再び実行対象から外れることもあるため、workflow自体も変更レビューに含める必要がある。
やってみてわかったこと
テストの本数は品質の保証にならない。実行経路に接続されているか、壊れたときに本当に失敗するか、利用者が受け取る出力を見ているかまで揃って初めて回帰防止として機能する。今回の例では、BytesIO をHTTP応答の出口に使うことで、キャッシュヘッダーの欠落やステータス行の文字化けを、送出された値で検査している。
CIへの配線はコード変更と同じく成果物として扱う。テストファイルを追加したPRでは、workflowからそのファイル名を検索し、実行コマンドがあることを確認する。さらに、テストを意図的に失敗させた場合にCIが赤くなることを一度確かめれば、「置いただけで呼ばれていない」状態を避けやすくなる。
更新履歴
- 2026-09-29: 起稿。実装とworkflowで確認できる内容に限定。