PDFプレビューのスワップ完了を検証するテストに変更し、CI フレークを解消

basecamp/lexxy

PDF などプレビュー可能な添付ファイルがアップロードされた際、プレビュー画像が表示されるまでの一時的なファイルアイコン表示を確認していたテストが、タイミング依存で CI で不安定になる問題を解消しました。テストは プレースホルダーの存在 から 最終プレビュー画像が表示されること へとアサーションを移行し、Capybara の待機機構で確定的に合格できるようになっています。

背景

テスト upload previewable attachment shows file icon while preview loads は、PDF などのプレビュー可能ファイルがサーバ側でサムネイル生成中に一時的に表示されるファイルアイコン(プレースホルダー)を検証していました。CI 環境ではサーバ側の生成が速く、プレースホルダーが消えてプレビュー画像がすぐにスワップされるため、Capybara がプレースホルダーを捕捉できずに フレーク が発生していました。

この問題は同様の理由で #1128 の Firefox 専用テストでも顕在化していたことが報告されており、テストの安定化はプロジェクト全体の CI 信頼性向上に直結します。

技術的な変更

テストファイル test/system/attachments_test.rb の該当テストを プレースホルダーの検証 から プレビュー画像のスワップ完了 を検証するコードへ置き換えました。具体的な差分は以下の通りです。

@@ -13,17 +13,14 @@ class AttachmentsTest < ApplicationSystemTestCase
     assert_image_figure_attachment content_type: "image/png", caption: "example.png"
   end

-  test "upload previewable attachment shows file icon while preview loads" do
+  test "upload previewable attachment swaps in the preview" do
     attach_file file_fixture("dummy.pdf") do
       click_on "Upload files"
     end
-
-    # Previewable non-image uploads (PDFs) show as file icon initially while
-    # the server generates the thumbnail. The preview swaps in once ready.
-    assert_figure_attachment content_type: "application/pdf" do
-      assert_selector ".attachment__icon"
-      assert_selector ".attachment__name", text: "dummy.pdf"
-    end
+    # A previewable non-image (PDF) shows a file icon while the server generates
+    # the thumbnail, then swaps in the preview image once it loads.
+    assert_selector "figure.attachment--preview[data-content-type='application/pdf'] .attachment__container img", wait: 10
   end

   test "upload image via image button" do

変更点は次の通りです。

  • テスト名を "upload previewable attachment swaps in the preview" に変更し、期待結果を明示的に記述。
  • 旧コードでは assert_figure_attachment ブロックでプレースホルダーとファイル名を確認していたが、これを削除。
  • 新コードでは assert_selector を用いて PDF 用プレビュー画像img 要素が figure.attachment--preview 内に出現することを最大 10 秒待機して検証。

この修正により、Capybara が 最終状態 を待つため、サーバ側の処理速度に左右されず deterministic にテストが通過します。

設計判断

テストは エンドツーエンドのプレビュー生成フロー をそのままカバーし続ける方針が保たれました。プレースホルダーの一時状態を明示的にチェックする代わりに、「スワップが完了した」ことを確認することで、状態遷移の短時間の揺らぎをテストから除外しました。

この判断は、以下の設計トレードオフを踏まえています。

  • 安定性 vs. 詳細網羅:一時的な UI 表示は実装上は重要ですが、CI の信頼性を損なうリスクがあるため、堅牢な最終結果に重点を置く。
  • テスト範囲の重複回避:プレースホルダーの検証は Playwright の preview_status_url.test.js が既に deterministic にカバーしているため、システムテストで二重に検証する必要がなくなります。
  • 後方互換性:テストロジックだけを変更し、アプリケーションコードは一切改変していないため、プロダクションへの影響はありません。

このように、テストの目的を 結果の確実な検証 に絞り込む設計判断が、CI のフレーク解消に直結しています。

まとめ

test/system/attachments_test.rb の変更は、一時的なプレースホルダー検証を削除し、プレビュー画像が確実に表示されることを待機して確認する形にシフトしました。これにより CI 環境でのタイミング依存フレークが解消され、テストの安定性と信頼性が向上します。変更はテストコードのみであり、実装ロジックやユーザー体験への影響はありません。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
72e56a69

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文、背景、技術的変更、設計判断(任意)、まとめの5要素が揃っており、総論→各論→結論の流れが明確です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

diffコードブロックは正しい形式で記載され、PRリンクは #1129 が含まれる形で適切にリンク化されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

対象はエンジニアであり、専門用語中心の説明で過度な初心者向け解説はありません。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションは総論・各論・結論の段落構成で、トピックセンテンスが冒頭にあり、段落は1トピック・6文未満で空行で区切られています。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内 diff は提供された PR Diff と完全に一致し、ファイル名や変更箇所も正確です。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

使用されている技術用語は PR 内容と一致し、誤用は見られません。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

技術的説明は PR の根拠に基づき正確で、因果関係も論理的です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事の主張はすべて PR Title、Description、Diff で裏付けられており、捏造や憶測はありません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR 番号 #1129 のみが記載されており、正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事タイトルは PR の内容(スワップ検証と CI フレーク解消)を適切に表現しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

外部知識(バージョンサポート等)の記載はなく、PR に基づいた情報のみです。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

時間表現のずれはなく、PR の記述と一致しています。