`test_assign_ids_with_cpk_for_two_models` の順序依存性を排除

rails/rails

Rails の自動保存関連テストで、PostgreSQL 環境下でのフレークが発生していました。TestDefaultAutosaveAssociationOnAHasManyAssociation#test_assign_ids_with_cpk_for_two_models が取得した book_ids 配列の順序に依存していたため、has_many :booksORDER BY を付与しない場合にテストが失敗していました。この PR はその比較ロジックをソートして行うことで、順序に左右されない安定したテストへと改修しています。

背景

test_assign_ids_with_cpk_for_two_models は CPK(Composite Primary Keys)を使用した OrderBook の関連付けを検証するテストです。PostgreSQL では has_many :books のクエリに明示的な order: が無いため、結果セットのレコード順序はデータベース依存で不定となります。その不定性が原因で、ビルドキュー Buildkite の 129895 ビルドでテストが flake し、期待配列 [[550090038, 342015473], [550090038, 385957113]] と実際配列 [[550090038, 385957113], [550090038, 342015473]] が順序だけで不一致と判定されました。この現象はテストロジックが order‑dependent であることに起因しています。

技術的な変更

テストコードの assert_equal 行を assert_equal book_ids.sort, order.book_ids.sort に置換し、比較対象をソートした配列同士に変更しました。この変更は activerecord/test/cases/autosave_association_test.rb の該当箇所のみで、他のロジックやデータ構造に影響を与えません。以下に変更前後の差分を示します。

@@ -1005,7 +1005,7 @@ def test_assign_ids_with_cpk_for_two_models
     order.save
     order.reload
-
-    assert_equal book_ids, order.book_ids
+    assert_equal book_ids.sort, order.book_ids.sort
     assert_equal 2, order.books.length
     assert_includes order.books, cpk_books(:cpk_great_author_first_book)
     assert_includes order.books, cpk_books(:cpk_great_author_second_book)

このソート操作に加えて、テストは既に assert_includesassert_equal 2, order.books.length で ID の集合と件数を検証しているため、ソートによるロジックの冗長化はありません。結果として、PostgreSQL の行順序が変動してもテストは安定して成功します。

設計判断

テストの比較ロジックを order‑independent に変更する方針は、データベース固有の実装詳細に依存しないテスト設計を意図しています。has_many 関連で明示的な order: が付与されていない限り、結果順序は保証できないため、テスト側で順序正規化を行うのが安全です。この判断は、既存テストが assert_includes 等で集合的検証を行っている点と整合し、追加のデータベースカラムやスコープを導入せずに問題を解消する最小侵害アプローチです。

まとめ

本 PR は test_assign_ids_with_cpk_for_two_models における order‑dependent 比較をソートに置き換えるだけで、PostgreSQL 環境でのフレークを根本的に排除しました。テストロジックの安定性が向上したことで、CI の信頼性が高まり、将来的なデータベース実装変更にも影響を受けにくい設計となります。

記事メタデータ

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

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

品質レビュー結果

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

Review Criteria:

記事構成 ✓ PASS

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

リード文 → 背景 → 技術的な変更 → 設計判断 → まとめ の流れが明確で、各要素が揃っている。

カスタムMarkdown構文 ⚠ WARNING

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

diffブロックは正しく記載されているが、PRリンクが「[PR #57759](URL)」の形式で、ガイドラインの「[#123](URL)」とは若干異なる。機能上の問題はないが形式統一が必要。

対象読者への適合性 ✓ PASS

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

エンジニア向けに技術的詳細が中心で、初心者向けの過度な説明はない。

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

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

各段落がトピックセンテンスで始まり、1段落1トピック、長さも適切。段落間は空行で区切られている。

Diff内容との照合 ✓ PASS

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

記事内のdiffブロックは提供されたDiffと完全に一致している。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

用語(order‑dependent、has_many、CPK 等)はPR内容と一致し、誤用はなし。

説明の技術的正確性 ✓ PASS

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

技術的説明はPRの変更点と整合し、根拠が明示されている。

事実の突合 ✓ PASS

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

記事の主張は全てPR情報(背景、変更内容、ビルド番号)で裏付けられている。

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

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

ビルド番号やID配列の数値はPRに記載のものと一致している。

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

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

記事タイトルはPRタイトルの意味を正確に日本語化しており、一致している。

外部知識の正確性 ✓ PASS

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

外部知識(バージョンサポート等)は含まれておらず、PR情報のみで記述されている。

時間表現の正確性 ✓ PASS

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

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