Upgrade to Pro — share decks privately, control downloads, hide ads and more …

既存プロダクトのRSpec カバレッジを 40% から100% にした話

Avatar for OPTiM OPTiM
July 17, 2026

既存プロダクトのRSpec カバレッジを 40% から100% にした話

2026/07/16 開催「RailsTokyo#5」でのオプティム skytomoの発表資料です。

https://railstokyo.connpass.com/event/393733/

Avatar for OPTiM

OPTiM

July 17, 2026

More Decks by OPTiM

Other Decks in Technology

Transcript

  1. © 2019-2026 OPTiM Corp. All rights reserved. 既存プロダクトの RSpec カバレッジを

    40% から 100% にした話 2026-07-16 skytomo(@skytomo221) 最終更新日:2026-07-16
  2. © 2019-2026 OPTiM Corp. All rights reserved. 3 skytomo (@skytomo221)

    会社:株式会社オプティム Railsエンジニアです。 2022年に入社してから社内の複数製品のEoL対応 (サポートが切れたバージョンからサポートされているバージョンに上げる対応) を行っていました。 最近はiOSやAndroidにも手を出し始めています。 自己紹介
  3. C O N F I D E N T I

    A L © 2019-2026 OPTiM Corp. All rights reserved. 4 今回対応した製品について Optimal Remote
  4. © 2019-2026 OPTiM Corp. All rights reserved. 5 Optimal Remoteは、

    顧客や社員のPC/スマホのトラブル解決 をサポートするツール Optimal Remoteについて
  5. © 2019-2026 OPTiM Corp. All rights reserved. 6 よくある課題 ◼高齢者がスマホの使い方、アプリの使い方が分からない

    ◼株取引のサイトの使い方…… ◼プリンターの使い方…… よくあるサポートの課題 ◼お困りの場所が分からない ◼操作方法を説明し解決することが難しい ◼サポートのために現地へ訪問しなければならない Optimal Remoteについて
  6. © 2019-2026 OPTiM Corp. All rights reserved. 8  よくある課題

    ◼高齢者がスマホの使い方、アプリの使い方が分からない ◼株取引のサイトの使い方…… ◼プリンターの使い方……  よくあるサポートの課題 ◼お困りの場所が分からない → 遠隔で画面を確認できることで解決! ◼操作方法を説明し解決することが難しい → 赤ペン・矢印操作で解決! ◼サポートのために現地へ訪問しなければならない → 遠隔操作で解決! ◼サポートのためにアプリインストールが必要 → アプリのインストールが不要(エージェントレス)! Optimal Remoteについて
  7. © 2019-2026 OPTiM Corp. All rights reserved. 9  よくある課題

    ◼高齢者がスマホの使い方、アプリの使い方が分からない ◼株取引のサイトの使い方…… ◼プリンターの使い方……  よくあるサポートの課題 ◼お困りの場所が分からない → 遠隔で画面を確認できることで解決! ◼操作方法を説明し解決することが難しい → 赤ペン・矢印操作で解決! ◼サポートのために現地へ訪問しなければならない → 遠隔操作で解決! ◼サポートのためにアプリインストールが必要 → アプリのインストールが不要(エージェントレス)!  製品の実績 ◼大手金融機関・通信キャリア各社での採用 ◼サポート時間を約40%短縮 ◼PC・Webアプリ対応 ◼機密情報は非表示(マスキング)で画面共有など Optimal Remoteについて
  8. © 2019-2026 OPTiM Corp. All rights reserved. 10 Optimal Remoteの管理サーバ・ログサーバ

    ◼Railsアプリ ◼10年以上稼働 管理サーバは、クライアントツールと オペレーターツールとの通信を管理する ログサーバは、サポートのログの 収集・保存・検索を管理する Optimal Remoteについて
  9. © 2019-2026 OPTiM Corp. All rights reserved. 11 テストコードのカバレッジが足りない 管理サーバが45%、ログサーバが37%

    ◼セキュリティ的に重要なものなど最小限必要なテストコードのみ ◼残りの55%と63%は検証チームが人手でカバー カバレッジ率が低いと起こる困ったこと ◼最近EoL対応時にRailsの大幅なバージョンアップ ⚫検証チームの人手によるブラックボックステストは負担が大きい 負担・品質のためテストのカバレッジを上げたい ◼しかし他の業務も多く人手が足りない → AI を活用し、両アプリのカバレッジ向上に着手 カバレッジ向上着手前
  10. C O N F I D E N T I

    A L © 2019-2026 OPTiM Corp. All rights reserved. 12 使用したプロンプトについて
  11. © 2019-2026 OPTiM Corp. All rights reserved. 13 foo.rbのカバレッジを100%にしてほしいです。 coverage

    フォルダで確認できるので、足りないテストを増やしてカバレッジを上げてほしいです。 【注意事項】 - アプリのコードが正です。カバレッジやテストを通すために本番コードを変えず、テスト側を修正・追加してください。 - ただし、網羅の仕方がおかしい場合は、そのテストコードを書き直すこともできます。 - テストが失敗した場合は、本番の仕様に合わせて期待値やセットアップを修正してください。本番コードのリファクタや 仕様変更は依頼がない限りしないでください。 - テストファイルがない場合は対応するファイルを生成してください。 - bundle exec rspecでテストが実行できます。 【テスト名について】 - 日本人が見てもわかるようにシンプルな英語であること。難しい場合はテストコードの責務がよく整理されていない、と 考えるとよい。 【テストコードのスタイルについて】 - 基本的にrubocopに従うこと - https://qian-dao-zhen-yi.gitbook.io/rspec-style-guide/ (AI向け:https://raw.githubusercontent.com/willnet/rspec- style-guide/refs/heads/master/README.md)に従うこと - RSpec の各 `it` ブロックは原則として一つの振る舞いだけを検証し、その結果として一つの `expect` に収めることを推 奨する。そうすることで、どの期待が満たされなかったかが失敗メッセージからすぐに分かり、テストの意図も「この example はこの一点だけを保証する」と明確になる。また、複数の expect を並べると最初の失敗で example が終了し、後 続の expect は実行されないため、デバッグ時に見落としが生じやすくなる。 - ただし、同一の振る舞いや同一の戻り値について、形・内容・副作用などを複数の観点からまとめて検証する場合は、一 つの `it` に複数の `expect` を書いてよい。例えば、あるメソッドが「script タグで囲んだ HTML 安全な文字列を返す」と いう一つの仕様を、同じ結果オブジェクトに対して「特定の文字列を含む」「script タグを含む」「html_safe である」と 複数の expect で確認するような場合は、それらを一つの `it` にまとめるのが自然である。逆に、複数の異なる状態や異な る振る舞いを検証している場合は、それぞれ別の `it` に分ける。例えば「リクエスト前のロケール」と「リクエスト後のロ ケール」のように、検証対象の状態やタイミングが違う場合は、example を分割した方がよい。 - 判断の目安として、その `it` の説明を日本語で書いたときに、「〜であり、かつ〜であり、かつ〜である」と複数の事実 を並べるのであれば分割を検討し、「〜という形式の値を返す(その中身として A かつ B かつ C を満たす)」のように一 つの戻り値や一つのシナリオの多面的な検証であれば、一つの `it` に複数の expect を書いてよい、と考えるとよい。 【変更したテストの報告】 テストの追加・変更をした場合は、以下のフォーマットでまとめて出力してください。 ## 変更ファイル - ファイルパス ## 変更種別 - 追加 / 修正 / 削除 のいずれか ## 変更内容の概要 - 何を検証するテストか、どの分岐・rescue をカバーしたかなど、1〜2行で記載 ## 追加・修正した example(describe / context / it の名前) - example 名 1 - example 名 2 (変更が複数ある場合は箇条書きで列挙) のカバレッジを100%にしてほしいです。 coverage フォルダで確認できるので、足りないテストを増やしてカバレッジを上げてほしいです。 【注意事項】 - アプリのコードが正です。カバレッジやテストを通すために本番コードを変えず、テスト側を修正・追加してください。 - ただし、網羅の仕方がおかしい場合は、そのテストコードを書き直すこともできます。 - テストが失敗した場合は、本番の仕様に合わせて期待値やセットアップを修正してください。本番コードのリファクタや 仕様変更は依頼がない限りしないでください。 - テストファイルがない場合は対応するファイルを生成してください。 【テスト名について】 - 日本人が見てもわかるようにシンプルな英語であること。難しい場合はテストコードの責務がよく整理されていない、と 考えるとよい。 【テストコードのスタイルについて】 - 基本的にrubocopに従うこと - https://qian-dao-zhen-yi.gitbook.io/rspec-style-guide/ (AI向け:https://raw.githubusercontent.com/willnet/rspec- style-guide/refs/heads/master/README.md)に従うこと - RSpec の各 `it` ブロックは原則として一つの振る舞いだけを検証し、その結果として一つの `expect` に収めることを推 奨する。そうすることで、どの期待が満たされなかったかが失敗メッセージからすぐに分かり、テストの意図も「この example はこの一点だけを保証する」と明確になる。また、複数の expect を並べると最初の失敗で example が終了し、後 続の expect は実行されないため、デバッグ時に見落としが生じやすくなる。 - ただし、同一の振る舞いや同一の戻り値について、形・内容・副作用などを複数の観点からまとめて検証する場合は、一 つの `it` に複数の `expect` を書いてよい。例えば、あるメソッドが「script タグで囲んだ HTML 安全な文字列を返す」と いう一つの仕様を、同じ結果オブジェクトに対して「特定の文字列を含む」「script タグを含む」「html_safe である」と 複数の expect で確認するような場合は、それらを一つの `it` にまとめるのが自然である。逆に、複数の異なる状態や異な る振る舞いを検証している場合は、それぞれ別の `it` に分ける。例えば「リクエスト前のロケール」と「リクエスト後のロ ケール」のように、検証対象の状態やタイミングが違う場合は、example を分割した方がよい。 - 判断の目安として、その `it` の説明を日本語で書いたときに、「〜であり、かつ〜であり、かつ〜である」と複数の事実 を並べるのであれば分割を検討し、「〜という形式の値を返す(その中身として A かつ B かつ C を満たす)」のように一 つの戻り値や一つのシナリオの多面的な検証であれば、一つの `it` に複数の expect を書いてよい、と考えるとよい。 【変更したテストの報告】 テストの追加・変更をした場合は、以下のフォーマットでまとめて出力してください。 ## 変更ファイル - ファイルパス ## 変更種別 - 追加 / 修正 / 削除 のいずれか ## 変更内容の概要 - 何を検証するテストか、どの分岐・rescue をカバーしたかなど、1〜2行で記載 ## 追加・修正した example(describe / context / it の名前) - example 名 1 - example 名 2 (変更が複数ある場合は箇条書きで列挙) 使用したプロンプト(例)
  12. © 2019-2026 OPTiM Corp. All rights reserved. 14 ファイル単位でプロンプトを実行する プロンプトは2種類

    を使い分け: ◼既存のテストがある → 不足分を埋めるプロンプト ◼テストがない → 新規作成用プロンプト プロンプトについて
  13. © 2019-2026 OPTiM Corp. All rights reserved. 15 foo.rbのカバレッジを100%にしてほしいです。 coverage

    フォルダで確認できるので、足りないテストを増やしてカバレッジ を上げてほしいです。 プロンプトの中身(概要) `foo.rb` に対して、カバレッジを100%にするプロンプト • Rubyには simplecov というカバレッジを計測するライブラリがある • これを使ってカバレッジを計測することができる • coverage フォルダには、カバレッジを計測した結果が保存されている • AIにこれを確認してもらい、以下の情報をもとにテストを追加していく • あるファイルは何%カバーされているか • どの行がカバーできているか・できていないか
  14. © 2019-2026 OPTiM Corp. All rights reserved. 16 【注意事項】 -

    アプリのコードが正です。カバレッジやテストを通すために本番コードを変えず、 テスト側を修正・追加してください。 - ただし、網羅の仕方がおかしい場合は、そのテストコードを書き直すこともできま す。 - テストが失敗した場合は、本番の仕様に合わせて期待値やセットアップを修正して ください。本番コードのリファクタや仕様変更は依頼がない限りしないでください。 - テストファイルがない場合は対応するファイルを生成してください。 - bundle exec rspecでテストが実行できます。 プロンプトの中身(注意事項) AIが暴走しないように注意事項を書く • 今回の対応は既存のアプリに対して足りないテストを追加する • 本来であれば、テストコードを元にアプリが正しく動作しているか検証する • 今回は、すでに提供しているアプリなので、実際に動作しているアプリ側を「正」とし て、テストコードを追加していく • 今後の更新時に差分が発生しないかを確かめるためのテストコード
  15. © 2019-2026 OPTiM Corp. All rights reserved. 17 【テスト名について】 -

    日本人が見てもわかるようにシンプルな英語であること。難しい場合はテ ストコードの責務がよく整理されていない、と考えるとよい。 【テストコードのスタイルについて】 - 基本的にrubocopに従うこと - https://qian-dao-zhen-yi.gitbook.io/rspec-style-guide/ (AI向け: https://raw.githubusercontent.com/willnet/rspec-style- guide/refs/heads/master/README.md)に従うこと プロンプトの中身(注意事項) テスト名をシンプルにすることによって、AIがテストコードの責務を理解しやすくする
  16. © 2019-2026 OPTiM Corp. All rights reserved. 18 - RSpec

    の各 `it` ブロックは原則として一つの振る舞いだけを検証し、その 結果として一つの `expect` に収めることを推奨する。そうすることで、ど の期待が満たされなかったかが失敗メッセージからすぐに分かり、テストの 意図も「この example はこの一点だけを保証する」と明確になる。また、 複数の expect を並べると最初の失敗で example が終了し、後続の expect は実行されないため、デバッグ時に見落としが生じやすくなる。……(以下 略) プロンプトの中身(注意事項) • RuboCop に準拠 • RSpec スタイル: https://qian-dao-zhen-yi.gitbook.io/rspec-style-guide/ • AI 向け raw: https://raw.githubusercontent.com/willnet/rspec-style- guide/refs/heads/master/README.md • 既存の古い書き方のテストコードに引っ張られないようにスタイルを指定する
  17. © 2019-2026 OPTiM Corp. All rights reserved. 19 【変更したテストの報告】 テストの追加・変更をした場合は、以下

    のフォーマットでまとめて出力してくだ さい。 ## 変更ファイル - ファイルパス ## 変更種別 - 追加 / 修正 / 削除 のいずれか ## 変更内容の概要 - 何を検証するテストか、どの分岐・ rescue をカバーしたかなど、1〜2行で記 載 ## 追加・修正した example(describe / context / it の名前) - example 名 1 - example 名 2 (変更が複数ある場合は箇条書きで列 挙) プロンプトの中身(変更したテストの報告) 最後に対応した内容をこのフォーマットに合わせて出力するようにする。 これをチケットに記載することで後から対応内容を確認しやすくすることができる。
  18. C O N F I D E N T I

    A L © 2019-2026 OPTiM Corp. All rights reserved. 20 実績と課題
  19. © 2019-2026 OPTiM Corp. All rights reserved. 21 結果(カバレッジ) 対応前

    対応後 管理サーバ 45.22% 100.00% ログサーバ 37.02% 100.00% 計測はsimplecovを使用。テストで通ったコード行数をすべてのコード行数で割った割合
  20. © 2019-2026 OPTiM Corp. All rights reserved. 22 対象: テストの数と行数

    見積もり: 約9人月 人手のみで同規模の改修 (約3,000テスト・4,000 LOC) をやろうとすると…… 楽観 約9人月、悲観 約30人月近く(レガシー・複雑・結合が多い前提。) 実績: 両サーバあわせて 20人日以下 でテスト追加。 テスト追加の工数をおおむね 90% 以上削減 できた。 見積もりと工数の実績
  21. © 2019-2026 OPTiM Corp. All rights reserved. 23 使ったもの ◼モデル:Cursor

    Auto (一部 gpt-5) ◼トークン量 ⚫総量約5億 (キャッシュの読み込みが大半) ⚫出力約500万 ◼コスト $166 (従量課金の場合) ⚫実際には定額なので40ドル程度 使用したモデル・トークン量・コスト
  22. © 2019-2026 OPTiM Corp. All rights reserved. 24  良かったところ

    ◼ 未カバー行を埋めることにより、検証チームへの負担が減る ◼ ついでにデッドコード・無意味なコードを発見できた ◼ ファイル単位 × SimpleCov はAIにとってわかりやすい  課題 ◼ Cursor ⚫ 履歴が大きすぎて不具合で読み込めなくなった ⚫ ファイル1つごとにプロンプトを回すと同時に5ファイルまでが限界になる ◼ Rspec ⚫ ファイル単体OKでも全体でテストを実行させるとコケる → AIが全体に影響を与えるテストを生成することがある ◼ 品質 ⚫ 大半は人並みの品質だが、稀にモック大盛りの部分がある ◼ 人間 ⚫ レビューがボトルネック 良かったところと課題
  23. © 2019-2026 OPTiM Corp. All rights reserved. 25  良かったところ

    ◼ 未カバー行を埋めることにより、検証チームへの負担が減る ◼ ついでにデッドコード・無意味なコードを発見できた ◼ ファイル単位 × SimpleCov はAIにとってわかりやすい  課題 ◼ Cursor ⚫ 履歴が大きすぎて不具合で読み込めなくなった ⚫ ファイル1つごとにプロンプトを回すと同時に5ファイルまでが限界になる ◼ Rspec ⚫ ファイル単体OKでも全体でテストを実行させるとコケる → AIが全体に影響を与えるテストを生成することがある ◼ 品質 ⚫ 大半は人並みの品質だが、稀にモック大盛りの部分がある ◼ 人間 ⚫ レビューがボトルネック 良かったところと課題 原因の典型(今回実際に対処) • クラスメソッド • シングルトン • stub_const の復元漏れ • I18n.locale や Time.zone の汚染 • fixture 共有・一意制約 改善策 • プロンプトに「変更後は関連 spec だけでな く bundle exec rspec で確認」を明記。 • 隔離ルールを最初から入れる。 • around で定数復元 • stub_const 推奨 • allow_any_instance_of 禁止