改善・モダナイゼーション

テストがないシステムを安全に改修する進め方

July 12, 2026
リファクタリング 技術的負債 既存改善 テスト

「このシステム、テストが1本もないんです」——既存プロダクトの改修相談で最も多く聞く言葉のひとつです。機能追加のたびに手動で全画面を確認し、リリース後に別の場所が壊れていないか祈る運用を何年も続けているチームは珍しくありません。

テストがないこと自体は致命的ではありません。危険なのは「怖くて触れない」状態が続き、負債が雪だるま式に膨らむことです。この記事では、自動テストがほぼ無い既存システムを、全面書き直しに逃げずに安全に改修する現実的な手順を解説します。

「まず全部テストを書く」が失敗する理由

テストがないと分かると、多くのチームは「本格改修の前に、まずテストカバレッジを上げよう」と考えます。しかしこの発想はほとんどの現場でうまくいきません。

  • 数万〜数十万行に網羅的なテストを書くには数ヶ月〜年単位の工数がかかる
  • その間、事業側が求める機能追加は止められない
  • テストのないコードは「何が正しい仕様か」の基準がなく、テストを書く作業自体が仕様調査になり長期化する

結果として「テスト全書き直しプロジェクト」は途中で頓挫し、中途半端にテストが増えただけで元の問題は解決しない、というパターンをよく見ます。目指すべきは100%のカバレッジではなく、「今から触る箇所だけを安全にする」という現実的なゴールです。

ステップ1: リスクマップを作る(どこが一番怖いかを可視化する)

最初にやるべきは、コードを書くことではなく「どこが危険か」の棚卸しです。

  • 変更頻度が高い箇所: git logで直近半年〜1年のコミットが集中しているファイルを洗い出す
  • 障害・バグの発生源になった箇所: 過去のインシデントや「本番で不具合」の履歴から繰り返し問題を起こしている箇所を特定する
  • お金・個人情報が絡む箇所: 決済、権限管理など壊れたときの被害が大きい箇所

この3つが重なる箇所が最優先で安全網が必要な場所です。逆に「1年触っていない・事故もない」箇所は後回しにして構いません。この優先順位づけこそが、限られた予算でテストを効かせるための最重要ステップです。

ステップ2: 特性化テスト(characterization test)で現状を固定する

リスクの高い箇所が分かったら、まず書くのは「あるべき仕様のテスト」ではなく、「今の挙動をそのまま記録するテスト」です。これを特性化テスト(characterization test)と呼びます。

  • 対象の関数・APIに実際の入力を与え、今返ってきている出力をそのままアサーションにする
  • 「この挙動が正しいか」は一旦判断せず、バグに見えても現状を記録する
  • これにより「変更後に意図しない箇所まで変わっていないか」を機械的に検出できる

仕様書が無いシステムほど、この特性化テストが効きます。正解を知らなくても「今と違う」ことさえ検出できれば安全網として十分です。バグが判明したら、修正と同時にテストの期待値も正しい挙動に書き換えます。

ステップ3: 変更する箇所の周りだけに安全網を張る

新しい機能追加やバグ修正で特定の箇所に手を入れるときは、その周辺だけテストを足してから着手します。

  1. 変更するメソッド・エンドポイントに対し、変更前の挙動を確認するテストを先に書く(特性化テスト)
  2. 変更を加える
  3. テストが意図通りに通ることを確認する。仕様変更が目的なら、その箇所のテストを新しい仕様に更新する

この「触る場所だけテストを足す」ルールを徹底すると、改修を重ねるたびにテストが自然に増えていきます。数ヶ月後には「よく変更される中心的な機能」から順にテストが厚くなり、リスクマップの優先順位と一致します。

ステップ4: CIに乗せて「後退させない」仕組みにする

テストが増えてきたら、手元で実行するだけでなく必ずCI(GitHub Actionsなど)で自動実行する状態にします。

  • プルリクエストごとにテストが走り、落ちたらマージできないようにする
  • 最初は「新規に足したテストだけCIで必須にする」でも構わない。既存の不安定なテストまで一度に厳格化すると開発が止まる
  • 検証コマンドを1つにまとめ、「これを実行すれば安全性が分かる」状態を作ると文化が定着しやすい

CIに乗った瞬間から、せっかく書いたテストが「誰も実行していない」形骸化を防げます。安全網は維持されて初めて意味を持ちます。

ステップ5: リファクタリングは「テストが張れた箇所」から

複雑で触りにくいコード(巨大なコントローラ、ビューに書かれたビジネスロジックなど)のリファクタリングは、特性化テストで挙動を固定できた箇所から着手します。テストのない箇所をいきなり書き直すのは、挙動が変わったかを誰も検証できない、最もリスクの高い進め方です。

構造の見極め方や、テスト以外に確認すべき観点(デプロイの再現性・依存関係の古さなど)は 既存プロダクト改善、外部チームが最初に見る観点 で詳しく解説しています。フレームワーク自体が古くバージョンアップも絡む場合は Railsアップグレードを外部に依頼する判断基準 も参考にしてください。

外部チームに依頼する場合の進め方

私たちが既存システムの改修を引き継ぐときも、この手順を踏みます。まずリスクマップを作るところから始め、いきなり全面リファクタリングは提案しません。テストがない状態を理由に着手を諦める必要はなく、モダナイゼーション保守・運用のサービスとして、リスクの高い箇所の見極めから伴走できます。

まとめ

  • 「テストが無いから全部書いてから改修」は非現実的。変更頻度・事故履歴・影響範囲でリスクマップを作り、優先順位をつけることが出発点
  • いきなり仕様どおりのテストを書くのではなく、現状の挙動をそのまま固定する特性化テストで安全網を張り、触る箇所から段階的に増やしていく
  • テストはCIに乗せて初めて維持される。書いて終わりにせず「後退させない仕組み」まで作ることが、負債を増やさない改修の土台になる

「テストがないシステムをどう改修すればいいか分からない」という段階でも、torcheees はご相談を受け付けています。まずは開発診断の「既存プロダクト改善」で、リスクの高い箇所の見極めと改修の進め方をご提示します。継続的な改善支援も承っています。お問い合わせフォームからお気軽にご連絡ください。

Discuss Your AI × Rails Development

Contact Us
Quick Estimate