- 検証・テスト
リグレッションテストの範囲の決め方|影響範囲の調べ方
リグレッションテスト(回帰テスト)は、変更によって、変更していないはずの機能が壊れていないか(デグレしていないか)を確かめるテストです。 範囲は「全部」か「変えたところだけ」の二択ではなく、変更の影響が届くところを調べて決めます。
① 変更点を一覧にする → ② 影響が届くところを洗い出す → ③ 流すテストを選ぶ
(git diff) (呼び出し元・データ・画面) (必ず流す+選んで流す)
変えたところのテストだけでは足りない例を、小さなプログラムで再現しました。税の計算を「切り捨て」から「四捨五入」に変え、税の計算のテストは通ったのに、それを使うカートと請求書の2つの機能の結果が変わりました。
| 流したテスト | 結果 |
|---|---|
変えた tax.py のテストだけ |
2件すべて成功(変更の影響に気づけない) |
| 全部のテスト | 2件失敗(カートの合計、請求書の明細の税) |
確認環境:Python 3.11・pytest 9.1.1・git(Linux)で再現しました(確認日 2026年10月12日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「リグレッションテストの範囲の決め方|影響範囲の調べ方」
再現:変えたところのテストは通るのに、別の機能が変わる
税額を計算する共通の関数 calc_tax を、カート(cart.py)と請求書(invoice.py)が使っている構成です。
app/
├── tax.py calc_tax() ← ここを変更
├── cart.py cart_total() が calc_tax() を使う
├── invoice.py invoice_lines() が calc_tax() を使う
└── point.py points()(calc_tax を使わない)
変更前(切り捨て)と変更後(四捨五入)です。
# 変更前
def calc_tax(price: int, rate: float = 0.10) -> int:
return math.floor(price * rate) # 10.5 → 10
# 変更後
def calc_tax(price: int, rate: float = 0.10) -> int:
return math.floor(price * rate + 0.5) # 10.5 → 11
変えたファイルのテストだけを流すと、全部通りました。
$ pytest -q tests/test_tax.py
.. [100%]
2 passed
全部のテストを流すと、カートと請求書のテストが失敗しました。
$ pytest -q
FAILED tests/test_cart.py::test_cart_total - assert 336 == 335
FAILED tests/test_invoice.py::test_invoice_tax_per_line - assert [11, 10] == ...
2 failed, 4 passed
ここで大事なのは、失敗が「不具合」とは限らないことです。四捨五入への変更が仕様どおりなら、カートの合計が 336 円になるのは正しい結果です。リグレッションテストで見つかるのは「変わったところ」で、それが意図した変更か、意図しない変更(デグレ)かを判断するのが次の仕事です。請求書の明細の税額が変わるなら、お客さまに届く金額が変わるので、関係者に確かめてから進めます。
① 変更点を一覧にする
まず、何を変えたかを漏れなく出します。
git diff --stat main...HEAD # 変えたファイルの一覧
git diff main...HEAD -- app/ # 中身
app/tax.py | 4 ++--
tests/test_tax.py | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
| 変更の種類 | 影響が届きやすいところ |
|---|---|
| 共通の関数・クラス | 呼び出し元すべて |
| テーブルの列・データの形 | その列を読む・書く処理、帳票、連携先 |
| 設定値・定数 | その値を参照する処理すべて |
| ライブラリ・フレームワークの版上げ | 全体(版上げは範囲を絞りにくい) |
| 画面の部品(共通コンポーネント) | その部品を使う画面すべて |
② 影響が届くところを洗い出す
呼び出し元を検索する
変更した関数名で、呼び出し元を検索します。 この例では、calc_tax を使うのが cart.py と invoice.py だと分かりました。
git grep -n "calc_tax" -- app
app/cart.py:1:from app.tax import calc_tax
app/cart.py:5: return subtotal + calc_tax(subtotal)
app/invoice.py:1:from app.tax import calc_tax
app/invoice.py:4: return [{"name": n, "price": p, "tax": calc_tax(p)} for n, p in items]
app/tax.py:3:def calc_tax(price: int, rate: float = 0.10) -> int:
呼び出し元がさらに別の機能から呼ばれていれば、そこもたどります。 IDE の「呼び出し階層(Call Hierarchy)」を使うと、何段か上までまとめて見られます。
| 調べ方 | 見つかるもの | 見落としやすいもの |
|---|---|---|
git grep で名前を検索 |
直接の呼び出し | リフレクション・文字列で組み立てた呼び出し |
| IDE の呼び出し階層 | 呼び出しの何段か上まで | 別リポジトリ・別システムからの呼び出し |
| テーブル・列名で検索(SQL・ORM) | そのデータを使う処理 | バッチ・帳票・外部連携 |
| 設計書・CRUD図 | 機能とデータの対応 | 設計書に書かれていない処理 |
データの変更は、コードの検索だけでは足りません。 列の意味や桁数を変えたときは、その列を読むバッチ・帳票・CSV 出力・外部システムまで見ます。機能とテーブルの対応は、関連記事「CRUD図(CRUDマトリクス)の書き方と例|貼って使えるテンプレート」で扱っています。
影響範囲の洗い出し表
洗い出した結果は、表にしてレビューで見てもらいます。
| 変更点 | 影響が届く機能 | 影響の内容 | 確かめ方 | 判断 |
|---|---|---|---|---|
calc_tax を四捨五入に |
カート合計 | 端数で1円変わる | 既存テスト+端数のケース追加 | 仕様どおり |
| 同上 | 請求書の明細 | 明細ごとの税が変わる | 既存テスト+帳票の目視 | 関係者に確認 |
| ― | ポイント | 影響なし(calc_tax を使わない) |
スモークテストのみ | ― |
「影響なし」と判断した機能も、理由と一緒に書いておくと、レビューする人が判断を確かめられます。
③ 流すテストを選ぶ:必ず流す+選んで流す
リグレッションテストは、2つに分けて考えると範囲を決めやすくなります。
| 区分 | 中身 | いつ流すか |
|---|---|---|
| 必ず流す(スモーク) | ログイン・主要な画面の表示・主要な登録など、止まると業務が止まる機能 | 変更のたびに毎回 |
| 選んで流す | ②で洗い出した、影響が届く機能のテスト | その変更のとき |
| 全部流す | すべてのテスト | リリース前、版上げのとき、範囲を絞りにくい変更のとき |
pytest なら、マーカーで「必ず流す」テストに印を付けておけます。
# pytest.ini
[pytest]
markers =
smoke: 毎回まわす最小のテスト
@pytest.mark.smoke
def test_cart_total():
assert cart_total([100, 205]) == 335
pytest -m smoke # 印を付けたテストだけ
pytest --lf # 前回失敗したテストだけ(直したあとの確認テスト)
この例では、-m smoke でカートのテストだけが流れ(1 failed, 5 deselected)、--lf で前回失敗した2件だけが流れました。
選ぶときの優先順位
全部を流せないときは、次の順で選びます。
| 優先 | 選ぶテスト | 理由 |
|---|---|---|
| 1 | 変更したところと、その直接の呼び出し元 | 影響が一番濃い |
| 2 | お金・個人情報・権限にかかわる機能 | 壊れたときの影響が大きい |
| 3 | 過去に不具合が多かった機能 | 同じところがまた壊れやすい |
| 4 | よく使われる機能(利用の多い画面・API) | 壊れたときに気づかれやすい |
| 5 | それ以外 | 時間があれば・リリース前にまとめて |
手で流すか、自動化するか
リグレッションテストは、同じテストを何度も繰り返すので、自動化の効果が一番出やすいテストです。 一方で、全部を一度に自動化しようとすると続きません。
| 順番 | 自動化するもの | 道具の例 |
|---|---|---|
| 1 | 共通の計算・業務ルール(単体テスト) | JUnit・pytest |
| 2 | API の入出力 | MockMvc・REST Assured・pytest+httpx |
| 3 | 必ず流す画面操作(スモーク) | Playwright・Selenium |
| 手で残す | 帳票の見た目、使い勝手、一度きりの確認 | テスト仕様書で管理 |
CI(GitHub Actions など)で、プルリクエストのたびに単体テストとスモークテストを流すと、デグレに気づくのが「リリース前」から「変更した直後」に早まります。画面の自動テストは、関連記事「Playwright入門|E2Eテストの書き方とCI実行まで実行結果つきで解説」で扱っています。
確認テストとの違い
| 確認テスト(再テスト) | リグレッションテスト | |
|---|---|---|
| 目的 | 直した不具合が直ったか | 直していないところが壊れていないか |
| 範囲 | その不具合のテスト | 影響が届く範囲+必ず流すテスト |
| 例 | 端数の不具合を直し、端数のテストを流す | 端数を直したあと、カート・請求書・ポイントを流す |
不具合を直したときは、確認テストのあとに、リグレッションテストも流します。 直した変更そのものが、別の機能を壊すことがあるからです。
よくある質問
Q. 毎回全部のテストを流せば、範囲を考えなくていいのでは? A. 自動テストが数分で終わるなら、毎回全部流すのが一番安全です。範囲を決める考え方が要るのは、手で流すテストが多いときや、全部流すと何時間もかかるときです。
Q. 影響範囲の調査に時間がかかりすぎます。 A. 共通の関数・テーブルを変えるときほど、調査に時間がかかります。変更する前に「この関数を使っているのはどこか」を検索しておくと、見積もりにも調査の時間を入れられます。
Q. テストが失敗したのが、意図した変更かどうか分かりません。 A. 変更の目的(チケット・仕様変更の記録)に照らして判断します。判断がつかないときは、勝手にテストの期待値を書き換えず、仕様を決める人に確かめます。仕様変更の記録の仕方は、関連記事「仕様変更の管理方法 変更管理表テンプレートと変更要求フロー」で扱っています。
Q. テストケースそのものの作り方は? A. 関連記事「テスト仕様書の書き方|テストケースの記入例と観点の洗い出し方」で扱っています。
まとめ
- リグレッションテストは、変更していないところが壊れていないかを確かめるテスト
- 範囲は ① 変更点 → ② 影響が届くところ → ③ 流すテスト の順で決める
- 変えたところのテストだけでは、呼び出し元の変化に気づけない(再現では2件見落とし)
- 呼び出し元は
git grep・IDE の呼び出し階層、データの変更は CRUD図・帳票・連携先まで - テストは 必ず流す(スモーク)+選んで流す(影響範囲) に分け、繰り返すものから自動化
参考・出典
確認日はいずれも 2026年10月12日です。
- pytest ドキュメント「How to mark test functions with attributes」:https://docs.pytest.org/en/stable/how-to/mark.html
- pytest ドキュメント「How to re-run failed tests and maintain state between test runs」(--lf):https://docs.pytest.org/en/stable/how-to/cache.html
- Git ドキュメント「git-grep」:https://git-scm.com/docs/git-grep
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「リグレッションテストの範囲の決め方|影響範囲の調べ方」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。