Skip to content

Tagifyテストのフレーキーを修正#9262

Merged
machida merged 3 commits intomainfrom
fix-tags-test
Nov 5, 2025
Merged

Tagifyテストのフレーキーを修正#9262
machida merged 3 commits intomainfrom
fix-tags-test

Conversation

@machida
Copy link
Copy Markdown
Member

@machida machida commented Oct 16, 2025

Summary by CodeRabbit

  • Tests
    • タグ入力関連のシステムテストを直接要素操作からヘルパー経由の高レベル操作へ統一しました。
    • 固定待機を廃止し、タグ数増加や非表示入力の出現などの状態を明示的に待機・検証することで安定性を向上しました。
    • 一部冗長なタグ表示アサーションを削除して検証を簡潔化しました。
    • 承認スタンプ表示の日時検証を実際のチェック日時に合わせて調整しました。
    • メール通知テストで特定メッセージの存在確認タイミングを再配置しました。

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Oct 16, 2025

Walkthrough

システムテストのTagify操作をヘルパー呼び出しへ置換し、テストヘルパーは固定sleepを廃止してタグ数やhidden入力の変化を待つ同期に変更。いくつかの冗長なタグアサーション削除、メール通知テスト内のメッセージ検証タイミング調整、承認スタンプ日付アサーションを修正。

Changes

Cohort / File(s) Summary
システムテスト:Tagify操作をヘルパー化
test/system/movie/tags_test.rb, test/system/question/tags_test.rb, test/system/article/tags_test.rb
.tagify__inputへの直接操作を削除し、fill_in_tag '追加タグ'等のヘルパー呼び出しへ置換。articleテストでは一部のタグ存在確認アサーションを削除。主要フローは維持。
テストヘルパー:同期・検証の改善
test/supports/tag_helper.rb
fill_in_tagが事前の.tagify__tag数をカウントして入力→Enter後にタグ数増加を待機し、必要ならinput[name="tag_list"]の反映を最大10秒待つ。fill_in_tag_with_alertは固定sleep除去・クリック→入力→アラート処理へ。メソッド署名は不変。
システムテスト:メール通知の検証タイミング変更
test/system/mail_notification_test.rb
不正メッセージの否定アサーション(refute_text 'ユーザーIDもしくはTOKENが違います。')のタイミングを変更し、他のセレクタ/テキストチェック後に行うよう移動。2件目のテストは実質変更なし。
コンポーネントテスト:承認スタンプ日付修正
test/components/product/product_component_test.rb
承認スタンプの期待テキストに使う日付を「本日」から直近のチェックのcreated_at.to_dateへ変更(スタンプ表示の実際のチェック日を反映)。

Sequence Diagram(s)

sequenceDiagram
    participant Test as システムテスト
    participant Helper as fill_in_tag ヘルパー
    participant UI as ブラウザ DOM (.tagify / hidden input)

    Note over Test,Helper: ヘルパー駆動の同期フロー(変更点)
    Test->>Helper: fill_in_tag("追加タグ")
    Helper->>UI: 現在の .tagify__tag 数を取得
    Helper->>UI: input をクリック・テキスト入力・Enter送信
    UI-->>Helper: DOM 更新(.tagify__tag が増加)
    alt hidden input present
        UI-->>Helper: `input[name="tag_list"]` に新タグが反映(最大10秒待機)
    end
    Helper-->>Test: assert_selector で増加と(必要なら)hidden入力の値を確認
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

注意点:

  • test/supports/tag_helper.rb のタグ数カウントと待機ロジック(タイムアウトや競合ケース)を重点確認。
  • test/system/* の各テストで fill_in_tag が非同期DOM更新(React由来のhidden inputなど)を確実に検出するかを確認。
  • test/components/product/product_component_test.rb の日付算出がテスト固定化を壊していないか確認。

Possibly related PRs

Suggested reviewers

  • komagata
  • okuramasafumi

Poem

🐇 ぽんと跳んでタグを押すよ
ヘルパー呼べばちゃんと待つよ
もう古い sleep はおしまいさ
Enter 一発でタグが増える
ぴょん✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning プルリクエストの説明が提供されていません。必須のテンプレート構成(Issue、概要、変更確認方法)がすべて欠けています。 Issue番号、概要、変更確認方法、スクリーンショットなどを含む説明を追加してください。
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed プルリクエストのタイトルは、変更内容の主要な目的(Tagifyテストのフレーキーの修正)を明確に表現しており、レビュアーが履歴をスキャンする際に変更内容を理解できます。
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-tags-test

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5b5180b and c5ea914.

📒 Files selected for processing (6)
  • test/components/product/product_component_test.rb (1 hunks)
  • test/supports/tag_helper.rb (1 hunks)
  • test/system/article/tags_test.rb (0 hunks)
  • test/system/mail_notification_test.rb (1 hunks)
  • test/system/movie/tags_test.rb (1 hunks)
  • test/system/question/tags_test.rb (1 hunks)
💤 Files with no reviewable changes (1)
  • test/system/article/tags_test.rb
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rb

⚙️ CodeRabbit configuration file

**/*.rb: # refactoring

  • まずFat Controllerを避け、次にFat Modelを避ける。
  • Serviceクラスの乱用を避ける。
  • controller concernを作ろうとしたらPORO(Plain Old Ruby Object)やActiveRecordモデルでの実装で代替できないか検討する。

Rails Patterns

  • ViewHelperにメソッドを実装する時にはまずDecoratorパターンを使うことを検討する。(active_decorator gemを導入しているのでそれを使う)
  • 複雑なActiveRecordクエリがあり、再利用できそうな場合はQueryObjectパターンを検討する。(rails-patterns gemを導入しているのでそれのQuery機能を使う)
  • Viewにpartialを作る場合はViewComponentを使うことを検討する。
  • 複数のActiveRecordモデルを操作する1つの責務がある時や外部APIとやりとりする処理がある場合にはInteractorオブジェクトパターンを検討する。(interactor gemを導入しているのでそれを使う)
  • 複数のInteractorを実行するような処理がある場合Organizerオブジェクトパターンを検討する。(interactor gemを導入しており、その中にOrganizerの機能があるので使う)

Files:

  • test/components/product/product_component_test.rb
  • test/system/movie/tags_test.rb
  • test/supports/tag_helper.rb
  • test/system/question/tags_test.rb
  • test/system/mail_notification_test.rb
test/**/*

⚙️ CodeRabbit configuration file

test/**/*: # Test

  • TestCase名は英語で書く。
  • どうしても避けられない時以外にsystem testでsleepは使わない。

Unit Test

model, helper, decorator, view_componentについてはメソッドを追加した場合は必ず対応したUnit TestのTestCaseを1つは書く。

Files:

  • test/components/product/product_component_test.rb
  • test/system/movie/tags_test.rb
  • test/supports/tag_helper.rb
  • test/system/question/tags_test.rb
  • test/system/mail_notification_test.rb
🧠 Learnings (3)
📓 Common learnings
Learnt from: Miya096jp
Repo: fjordllc/bootcamp PR: 9102
File: app/controllers/mentor/buzzes_controller.rb:0-0
Timestamp: 2025-09-04T01:39:22.261Z
Learning: fjordllc/bootcamp プロジェクトでは、更新処理の成功時の通知メッセージについて、I18n を使用せずに日本語文字列を直接記述する方針で一貫性を保っている。
📚 Learning: 2025-07-04T01:28:44.174Z
Learnt from: e-yanagita-gs
Repo: fjordllc/bootcamp PR: 8881
File: app/javascript/transform-head-sharp.js:1-8
Timestamp: 2025-07-04T01:28:44.174Z
Learning: Tagifyライブラリは空文字列のタグを自動的に追加しないという仕様があるため、変換処理で空文字列を生成することで不要なタグの追加を防ぐことができる。

Applied to files:

  • test/system/question/tags_test.rb
📚 Learning: 2025-08-31T12:08:33.904Z
Learnt from: thmz337
Repo: fjordllc/bootcamp PR: 9103
File: app/views/generations/_user.html.slim:6-14
Timestamp: 2025-08-31T12:08:33.904Z
Learning: app/views/generations/_user.html.slimの非アクティブメッセージ表示では、退会・休会・非アクティブの3つの条件が独立して評価され、複数のメッセージが同時に表示される仕様になっている。これは意図的な設計である。

Applied to files:

  • test/system/mail_notification_test.rb
🧬 Code graph analysis (2)
test/system/movie/tags_test.rb (1)
test/supports/tag_helper.rb (1)
  • fill_in_tag (4-14)
test/system/question/tags_test.rb (1)
test/supports/tag_helper.rb (1)
  • fill_in_tag (4-14)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
🔇 Additional comments (6)
test/components/product/product_component_test.rb (1)

220-220: テストの正確性を向上させる良い修正です

承認スタンプの日付アサーションを、Date.currentから実際のチェックの作成日時(checked_product.checks.last.created_at.to_date)に変更することで、テストがより正確になります。これにより、テストがタイムゾーンや実行タイミングに依存しなくなります。

test/system/mail_notification_test.rb (1)

9-13: タイミング調整により安定性が向上しています

否定的なアサーション(refute_text)を肯定的なアサーションの後に配置することで、ページが完全にロードされた後にエラーメッセージの不在を確認できるようになります。これはレースコンディションによるフレーキーを防ぐ良い改善です。

test/supports/tag_helper.rb (2)

4-14: sleepを排除した状態駆動のアプローチ、素晴らしい改善です

fill_in_tagメソッドの実装が大幅に改善されています:

  • 固定のsleepを削除し、タグの数の変化を監視する状態駆動のアプローチに変更
  • assert_selectorcountwait: 10を使用することで、Capybaraの待機機構を適切に活用
  • Reactコンポーネント向けのhidden input検証を追加し、非同期更新を確実に待機

コーディングガイドラインの「どうしても避けられない時以外にsystem testでsleepは使わない」に完全に準拠しており、テストの安定性と保守性が向上しています。


16-23: アラート処理の改善により安定性が向上

fill_in_tag_with_alertメソッドも適切に改善されています:

  • 固定のsleepを削除
  • 入力前に.clickを追加することで、要素が確実にフォーカスされる
  • アラート処理後にassert_selectorを追加し、要素の状態を検証

これらの変更により、テストの信頼性が向上しています。

test/system/movie/tags_test.rb (1)

20-20: ヘルパーメソッドへの置き換えにより保守性が向上

TagifyのDOM操作を直接行う代わりにfill_in_tagヘルパーを使用することで:

  • コードの重複を削減(test/system/question/tags_test.rbと共通化)
  • Tagifyの実装詳細を抽象化し、将来の変更に強くなる
  • test/supports/tag_helper.rbで実装された安定した状態駆動のアプローチを活用
test/system/question/tags_test.rb (1)

20-20: 一貫したヘルパー使用による改善

test/system/movie/tags_test.rbと同様に、fill_in_tagヘルパーへの置き換えが適切に行われています。このPR全体で一貫したアプローチが取られており、Tagifyテストのフレーキー問題を体系的に解決しています。

以前のレビューで指摘されていたsleepの問題は、コミット a37fe57test/supports/tag_helper.rbにおいて適切に対処されています。

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 RuboCop (1.81.7)
test/components/product/product_component_test.rb

rubocop-minitest extension supports plugin, specify plugins: rubocop-minitest instead of require: rubocop-minitest in /.rubocop.yml.
For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
rubocop-capybara extension supports plugin, specify plugins: rubocop-capybara instead of require: rubocop-capybara in /.rubocop.yml.
For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
Unable to find gem rubocop-fjord; is the gem installed? Gem::MissingSpecError
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader_resolver.rb:310:in rescue in gem_config_path' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader_resolver.rb:293:in gem_config_path'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader_resolver.rb:84:in block (2 levels) in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader_resolver.rb:82:in reverse_each'
/var/lib/gems/3.1.0/g

... [truncated 255 characters] ...

fig_loader_resolver.rb:76:in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader.rb:58:in load_file'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_store.rb:34:in options_config=' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_store.rb:29:in apply_options!'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:167:in act_on_options' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:49:in block in run'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:87:in profile_if_needed' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:45:in run'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/exe/rubocop:15:in <top (required)>' /usr/local/bin/rubocop:25:in load'
/usr/local/bin/rubocop:25:in `

'

test/supports/tag_helper.rb

rubocop-minitest extension supports plugin, specify plugins: rubocop-minitest instead of require: rubocop-minitest in /.rubocop.yml.
For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
rubocop-capybara extension supports plugin, specify plugins: rubocop-capybara instead of require: rubocop-capybara in /.rubocop.yml.
For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
Unable to find gem rubocop-fjord; is the gem installed? Gem::MissingSpecError
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader_resolver.rb:310:in rescue in gem_config_path' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader_resolver.rb:293:in gem_config_path'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader_resolver.rb:84:in block (2 levels) in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader_resolver.rb:82:in reverse_each'
/var/lib/gems/3.1.0/g

... [truncated 255 characters] ...

fig_loader_resolver.rb:76:in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader.rb:58:in load_file'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_store.rb:34:in options_config=' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_store.rb:29:in apply_options!'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:167:in act_on_options' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:49:in block in run'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:87:in profile_if_needed' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:45:in run'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/exe/rubocop:15:in <top (required)>' /usr/local/bin/rubocop:25:in load'
/usr/local/bin/rubocop:25:in `

'

test/system/mail_notification_test.rb

rubocop-minitest extension supports plugin, specify plugins: rubocop-minitest instead of require: rubocop-minitest in /.rubocop.yml.
For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
rubocop-capybara extension supports plugin, specify plugins: rubocop-capybara instead of require: rubocop-capybara in /.rubocop.yml.
For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
Unable to find gem rubocop-fjord; is the gem installed? Gem::MissingSpecError
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader_resolver.rb:310:in rescue in gem_config_path' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader_resolver.rb:293:in gem_config_path'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader_resolver.rb:84:in block (2 levels) in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader_resolver.rb:82:in reverse_each'
/var/lib/gems/3.1.0/g

... [truncated 255 characters] ...

fig_loader_resolver.rb:76:in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader.rb:58:in load_file'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_store.rb:34:in options_config=' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_store.rb:29:in apply_options!'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:167:in act_on_options' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:49:in block in run'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:87:in profile_if_needed' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:45:in run'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/exe/rubocop:15:in <top (required)>' /usr/local/bin/rubocop:25:in load'
/usr/local/bin/rubocop:25:in `

'

  • 2 others

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 883044e and ebfe84d.

📒 Files selected for processing (2)
  • test/system/movie/tags_test.rb (1 hunks)
  • test/system/question/tags_test.rb (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rb

⚙️ CodeRabbit configuration file

**/*.rb: # refactoring

  • まずFat Controllerを避け、次にFat Modelを避ける。
  • Serviceクラスの乱用を避ける。
  • controller concernを作ろうとしたらPORO(Plain Old Ruby Object)やActiveRecordモデルでの実装で代替できないか検討する。

Rails Patterns

  • ViewHelperにメソッドを実装する時にはまずDecoratorパターンを使うことを検討する。(active_decorator gemを導入しているのでそれを使う)
  • 複雑なActiveRecordクエリがあり、再利用できそうな場合はQueryObjectパターンを検討する。(rails-patterns gemを導入しているのでそれのQuery機能を使う)
  • Viewにpartialを作る場合はViewComponentを使うことを検討する。
  • 複数のActiveRecordモデルを操作する1つの責務がある時や外部APIとやりとりする処理がある場合にはInteractorオブジェクトパターンを検討する。(interactor gemを導入しているのでそれを使う)
  • 複数のInteractorを実行するような処理がある場合Organizerオブジェクトパターンを検討する。(interactor gemを導入しており、その中にOrganizerの機能があるので使う)

Files:

  • test/system/question/tags_test.rb
  • test/system/movie/tags_test.rb
test/**/*

⚙️ CodeRabbit configuration file

test/**/*: # Test

  • TestCase名は英語で書く。
  • どうしても避けられない時以外にsystem testでsleepは使わない。

Unit Test

model, helper, decorator, view_componentについてはメソッドを追加した場合は必ず対応したUnit TestのTestCaseを1つは書く。

Files:

  • test/system/question/tags_test.rb
  • test/system/movie/tags_test.rb
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
🔇 Additional comments (1)
test/system/movie/tags_test.rb (1)

20-20: LGTM! 一貫したリファクタリングでテストの品質が向上しています

fill_in_tag ヘルパーメソッドの使用により、test/system/question/tags_test.rb と同様にTagify操作が抽象化されています。複数のテストファイルで一貫したアプローチを採用することで、保守性とテストの安定性が全体的に向上します。

@machida machida removed the request for review from okuramasafumi October 16, 2025 14:55
@machida machida self-assigned this Oct 16, 2025
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
test/supports/tag_helper.rb (1)

18-18: アラート発生時の検証が最小限です。

assert_selector(selector)はセレクタの存在のみを確認していますが、アラートが表示された場合の期待動作(例:タグが追加されないこと)を明示的に検証していません。テストの意図に応じて、より具体的なアサーションの追加を検討してください。

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2006e0a and 2bf9ed9.

📒 Files selected for processing (1)
  • test/supports/tag_helper.rb (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rb

⚙️ CodeRabbit configuration file

**/*.rb: # refactoring

  • まずFat Controllerを避け、次にFat Modelを避ける。
  • Serviceクラスの乱用を避ける。
  • controller concernを作ろうとしたらPORO(Plain Old Ruby Object)やActiveRecordモデルでの実装で代替できないか検討する。

Rails Patterns

  • ViewHelperにメソッドを実装する時にはまずDecoratorパターンを使うことを検討する。(active_decorator gemを導入しているのでそれを使う)
  • 複雑なActiveRecordクエリがあり、再利用できそうな場合はQueryObjectパターンを検討する。(rails-patterns gemを導入しているのでそれのQuery機能を使う)
  • Viewにpartialを作る場合はViewComponentを使うことを検討する。
  • 複数のActiveRecordモデルを操作する1つの責務がある時や外部APIとやりとりする処理がある場合にはInteractorオブジェクトパターンを検討する。(interactor gemを導入しているのでそれを使う)
  • 複数のInteractorを実行するような処理がある場合Organizerオブジェクトパターンを検討する。(interactor gemを導入しており、その中にOrganizerの機能があるので使う)

Files:

  • test/supports/tag_helper.rb
test/**/*

⚙️ CodeRabbit configuration file

test/**/*: # Test

  • TestCase名は英語で書く。
  • どうしても避けられない時以外にsystem testでsleepは使わない。

Unit Test

model, helper, decorator, view_componentについてはメソッドを追加した場合は必ず対応したUnit TestのTestCaseを1つは書く。

Files:

  • test/supports/tag_helper.rb
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
🔇 Additional comments (2)
test/supports/tag_helper.rb (2)

4-10: sleepの削除とassert_selectorによる同期は良い改善です。

FLAKYテストの原因となるsleepを削除し、assert_selectorで明示的に待機する実装に変更したことで、テストの安定性が向上します。コーディングガイドラインの「どうしても避けられない時以外にsystem testでsleepは使わない」に準拠しています。


5-9: 複数のTagifyインスタンスに関する懸念は根拠がありません。

コードベース全体のシステムテスト(8ファイル以上)を確認した結果:

  • すべてのテストで find('.tagify__input') または first('.tagify__input') を使用して、ページごとに1つのTagifyインスタンスを前提としている
  • グローバルな .tagify__tag セレクタを使用したアサーションはテスト側でも同じパターン
  • 複数のTagifyインスタンスが存在するページは確認できない
  • 現在の実装でテストは成功している

タグカウントのスコープ限定は不要です。

ただし、fill_in_tag_with_alertメソッドのアサーション(assert_selector(selector))は、ページの安定性の観点からさらに強化することは検討の価値があります。例えば、タグが追加されなかったことを明示的に検証する方が意図的です。

Likely an incorrect or invalid review comment.

@machida machida changed the title Tagifyの初期化待ちを追加してFLAKYテストを修正 Tagifyテストのフレーキーを修正 Nov 5, 2025
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
test/supports/tag_helper.rb (1)

18-18: より具体的なアサーションを検討してください

assert_selector(selector) は要素の存在のみを確認していますが、アラート処理が成功したこと、またはTagifyが適切に初期化されていることを保証していません。アラート処理後の期待される状態(例:タグの数、特定のTagify属性の存在など)をより具体的に検証することを検討してください。

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 34b008b and 535a32e.

📒 Files selected for processing (4)
  • test/supports/tag_helper.rb (1 hunks)
  • test/system/article/tags_test.rb (0 hunks)
  • test/system/movie/tags_test.rb (1 hunks)
  • test/system/question/tags_test.rb (1 hunks)
💤 Files with no reviewable changes (1)
  • test/system/article/tags_test.rb
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/system/movie/tags_test.rb
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rb

⚙️ CodeRabbit configuration file

**/*.rb: # refactoring

  • まずFat Controllerを避け、次にFat Modelを避ける。
  • Serviceクラスの乱用を避ける。
  • controller concernを作ろうとしたらPORO(Plain Old Ruby Object)やActiveRecordモデルでの実装で代替できないか検討する。

Rails Patterns

  • ViewHelperにメソッドを実装する時にはまずDecoratorパターンを使うことを検討する。(active_decorator gemを導入しているのでそれを使う)
  • 複雑なActiveRecordクエリがあり、再利用できそうな場合はQueryObjectパターンを検討する。(rails-patterns gemを導入しているのでそれのQuery機能を使う)
  • Viewにpartialを作る場合はViewComponentを使うことを検討する。
  • 複数のActiveRecordモデルを操作する1つの責務がある時や外部APIとやりとりする処理がある場合にはInteractorオブジェクトパターンを検討する。(interactor gemを導入しているのでそれを使う)
  • 複数のInteractorを実行するような処理がある場合Organizerオブジェクトパターンを検討する。(interactor gemを導入しており、その中にOrganizerの機能があるので使う)

Files:

  • test/supports/tag_helper.rb
  • test/system/question/tags_test.rb
test/**/*

⚙️ CodeRabbit configuration file

test/**/*: # Test

  • TestCase名は英語で書く。
  • どうしても避けられない時以外にsystem testでsleepは使わない。

Unit Test

model, helper, decorator, view_componentについてはメソッドを追加した場合は必ず対応したUnit TestのTestCaseを1つは書く。

Files:

  • test/supports/tag_helper.rb
  • test/system/question/tags_test.rb
🧠 Learnings (2)
📓 Common learnings
Learnt from: e-yanagita-gs
Repo: fjordllc/bootcamp PR: 8881
File: app/javascript/transform-head-sharp.js:1-8
Timestamp: 2025-07-04T01:28:44.174Z
Learning: Tagifyライブラリは空文字列のタグを自動的に追加しないという仕様があるため、変換処理で空文字列を生成することで不要なタグの追加を防ぐことができる。
Learnt from: masyuko0222
Repo: fjordllc/bootcamp PR: 8277
File: test/models/searcher_test.rb:0-0
Timestamp: 2025-07-07T12:46:01.650Z
Learning: テストにおいて、`result.all? { |condition| }` でコレクションの全要素が条件を満たすことを確認できれば、その条件を満たさない要素が含まれていないことも論理的に保証されるため、追加のアサーションは冗長となる。
📚 Learning: 2025-07-04T01:28:44.174Z
Learnt from: e-yanagita-gs
Repo: fjordllc/bootcamp PR: 8881
File: app/javascript/transform-head-sharp.js:1-8
Timestamp: 2025-07-04T01:28:44.174Z
Learning: Tagifyライブラリは空文字列のタグを自動的に追加しないという仕様があるため、変換処理で空文字列を生成することで不要なタグの追加を防ぐことができる。

Applied to files:

  • test/system/question/tags_test.rb
🧬 Code graph analysis (1)
test/system/question/tags_test.rb (1)
test/supports/tag_helper.rb (1)
  • fill_in_tag (4-10)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
🔇 Additional comments (2)
test/system/question/tags_test.rb (1)

20-20: LGTM! ヘルパーメソッドの使用でテストの安定性が向上しています

fill_in_tag ヘルパーの使用により、Tagifyの初期化待ちが適切に処理され、直接的なDOM操作が抽象化されています。これによりテストの保守性と安定性が向上し、FLAKYテストの問題が解決されます。

test/supports/tag_helper.rb (1)

5-9: このレビューコメントは却下してください

検証の結果、このレビューコメントで指摘されている「複数のTagifyインスタンスがページに存在する場合の問題」は、実装コードベースに存在しません。

実装上の根拠:

  • article/tags_test.rbでは既に2つのタグを連続追加するテストが実装されており、正常に動作しています
  • fill_in_tag呼び出しでタグ数を前後比較してアサートしており、連続追加時も正確に検証できています
  • 実際のコードベース内でページ上に複数の独立したTagifyインスタンスが存在する場面は見つかりません
  • 報告されているテストの不安定性や失敗もありません

現在の実装は、実際の使用パターンに対して正確に機能しており、問題はありません。

Likely an incorrect or invalid review comment.

@machida machida force-pushed the fix-tags-test branch 2 times, most recently from 8b9fa8b to 5b5180b Compare November 5, 2025 14:52
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
test/supports/tag_helper.rb (1)

11-13: React コンポーネント向けの hidden input 検証について

hidden input の値検証に部分一致 [value*='#{name}'] を使用していますが、理論的にはタグ名が他のタグの部分文字列である場合に誤マッチの可能性があります。

ただし、acts-as-taggable-on がカンマ区切りで保存する仕様上、実用上は問題ありません。より厳密にしたい場合は、カンマや前後の空白を考慮したパターンマッチも検討できます。

より厳密なマッチングの例:

# カンマ区切りを考慮した検証(オプション)
tag_pattern = "(^|, )#{Regexp.escape(name)}(, |$)"
assert_selector("input[type='hidden'][name*='tag_list']", visible: :all, wait: 10) do |input|
  input.value.match?(/#{tag_pattern}/)
end
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 68d6b03 and 5b5180b.

📒 Files selected for processing (4)
  • test/supports/tag_helper.rb (1 hunks)
  • test/system/article/tags_test.rb (0 hunks)
  • test/system/movie/tags_test.rb (1 hunks)
  • test/system/question/tags_test.rb (1 hunks)
💤 Files with no reviewable changes (1)
  • test/system/article/tags_test.rb
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/system/question/tags_test.rb
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rb

⚙️ CodeRabbit configuration file

**/*.rb: # refactoring

  • まずFat Controllerを避け、次にFat Modelを避ける。
  • Serviceクラスの乱用を避ける。
  • controller concernを作ろうとしたらPORO(Plain Old Ruby Object)やActiveRecordモデルでの実装で代替できないか検討する。

Rails Patterns

  • ViewHelperにメソッドを実装する時にはまずDecoratorパターンを使うことを検討する。(active_decorator gemを導入しているのでそれを使う)
  • 複雑なActiveRecordクエリがあり、再利用できそうな場合はQueryObjectパターンを検討する。(rails-patterns gemを導入しているのでそれのQuery機能を使う)
  • Viewにpartialを作る場合はViewComponentを使うことを検討する。
  • 複数のActiveRecordモデルを操作する1つの責務がある時や外部APIとやりとりする処理がある場合にはInteractorオブジェクトパターンを検討する。(interactor gemを導入しているのでそれを使う)
  • 複数のInteractorを実行するような処理がある場合Organizerオブジェクトパターンを検討する。(interactor gemを導入しており、その中にOrganizerの機能があるので使う)

Files:

  • test/supports/tag_helper.rb
  • test/system/movie/tags_test.rb
test/**/*

⚙️ CodeRabbit configuration file

test/**/*: # Test

  • TestCase名は英語で書く。
  • どうしても避けられない時以外にsystem testでsleepは使わない。

Unit Test

model, helper, decorator, view_componentについてはメソッドを追加した場合は必ず対応したUnit TestのTestCaseを1つは書く。

Files:

  • test/supports/tag_helper.rb
  • test/system/movie/tags_test.rb
🧠 Learnings (1)
📓 Common learnings
Learnt from: Miya096jp
Repo: fjordllc/bootcamp PR: 9102
File: app/controllers/mentor/buzzes_controller.rb:0-0
Timestamp: 2025-09-04T01:39:22.261Z
Learning: fjordllc/bootcamp プロジェクトでは、更新処理の成功時の通知メッセージについて、I18n を使用せずに日本語文字列を直接記述する方針で一貫性を保っている。
Learnt from: e-yanagita-gs
Repo: fjordllc/bootcamp PR: 8881
File: app/javascript/transform-head-sharp.js:1-8
Timestamp: 2025-07-04T01:28:44.174Z
Learning: Tagifyライブラリは空文字列のタグを自動的に追加しないという仕様があるため、変換処理で空文字列を生成することで不要なタグの追加を防ぐことができる。
🧬 Code graph analysis (1)
test/system/movie/tags_test.rb (1)
test/supports/tag_helper.rb (1)
  • fill_in_tag (4-14)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
🔇 Additional comments (3)
test/supports/tag_helper.rb (2)

5-9: タグ追加の同期処理が適切に実装されています

固定sleepを廃止し、タグ数の変化を待つ明示的な同期に変更されています。visible: :allを使用することで、非表示のタグ要素も正しくカウントされます。10秒の待機時間も十分です。

コーディングガイドラインに従い、system testでのsleep使用を避ける方針に沿っています。


16-23: アラート処理を伴うタグ追加が改善されています

Line 18 で input をクリックしてから入力することで、フォーカス状態が確実になります。Line 22 のアラート後のアサーションも、要素が期待通りの状態にあることを確認する適切な防御的コーディングです。

test/system/movie/tags_test.rb (1)

17-23: ヘルパーを使用したテストの可読性向上

直接的な Tagify 入力操作を fill_in_tag ヘルパー呼び出しに置き換えることで、テストの意図が明確になり、保守性が向上しています。同期処理の詳細はヘルパー内にカプセル化され、テストコードがシンプルになりました。

fill_in_tagヘルパーでタグが正しく追加されないフレーキーを修正。
タグ要素の確認機能を追加し、sleepを削除してCapybaraの待機機能
を使用するように改善。clickを追加してフォーカスを確実にし、set
からnative.send_keysに変更してReactの入力イベントを正しく処理
するようにした。React版ではhidden input更新を待機し、フォーム
送信時の値を確実に反映。冗長なアサーションを削除し、movie/
questionテストでヘルパーを統一的に使用。また、RuboCopの指摘に
従いガード節に変更。
@machida machida merged commit 0203b65 into main Nov 5, 2025
3 checks passed
@machida machida deleted the fix-tags-test branch November 5, 2025 16:32
@github-actions github-actions bot mentioned this pull request Nov 5, 2025
16 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant