修正によって既存機能に不具合が生じていないか確認するテスト。
回帰テスト(リグレッションテスト)とは、プログラムを修正したことで、これまで正常に動いていた既存の機能に不具合が生じていないかを確認するテストです。「回帰」とは「元に戻る・後退する」という意味で、品質が後戻りしていないかを確かめます。
プログラムは部品どうしが複雑に関係しているため、1か所を直すと思わぬ別の場所に影響が及ぶことがあります。直したつもりが別の機能を壊してしまう現象をデグレード(デグレ・先祖返り)と呼びます。回帰テストはこのデグレードを早期に見つけるためのものです。
身近な例で考えると、料理のレシピ修正に似ています。スープの塩を減らしたら、他の料理と味のバランスが崩れていないかを全体で味見し直す──このように「一部を変えたら全体を確認し直す」のが回帰テストです。上の図解で、機能Aを修正した結果、巻き添えで機能Cが壊れていないかを確認する流れを示しています。
回帰テストは、プログラムに変更を加えたあとに必要になります。代表的な場面は次のとおりです。
・バグ修正のあと:直した箇所が他の機能を巻き添えにしていないか確認する
・機能追加のあと:新機能を入れたことで既存機能が壊れていないか確認する
・仕様変更のあと:変更の影響が想定外の範囲に及んでいないか確認する
・ソフトウェア保守:リリース後の改修でも、その都度実施する
ポイントは、変更した部分だけでなく、これまで動いていた既存機能もまとめて再テストすることです。変更箇所だけ確認しても、影響を受けた別の機能の故障は見逃してしまうためです。
とくにリリース後のソフトウェア保守では小さな修正を何度も繰り返すため、そのたびに回帰テストが発生します。修正のたびに同じテストを繰り返すことになる点が、次の自動化の話につながります。
回帰テストは修正のたびに同じテストを繰り返すため、人手で毎回行うと膨大な手間がかかります。そこでテストの自動化が有効です。あらかじめテストの手順をプログラムにしておき、ボタン1つで実行できるようにします。
・高速・反復:大量のテストを短時間で、何度でも実行できる
・省力化:人手の作業時間を削減し、ミスも減る
・早期発見:変更直後に実行して、壊れた箇所をすぐ見つけられる
・安心して修正できる:自動テストが守ってくれるため、積極的に改善できる
さらにCI(継続的インテグレーション)=コードを変更するたびに自動でビルドとテストを実行する仕組み、と組み合わせると、開発者が変更を反映するたびに回帰テストが自動実行され、デグレードを即座に検知できます。
身近な例で考えると、自動の品質チェック装置を備えた工場に似ています。製品を作り直すたびに人が全数検査するのは大変ですが、検査装置を置けば毎回自動で点検でき、不良品をすぐに見つけられます。
なぜ修正後に「また」テストする必要があるのか?それは、プログラムのどこかを変えると、意図しない別の場所にも影響が及ぶことがあるからです。
プログラムは各機能が複雑に絡み合っています。ある箇所を直すとき、その下で使われている共通の処理や、関連するデータのやり取りに予期しない変化が起きることがあります。
・直した箇所はOKになった
・しかし別の機能が「巻き添えで壊れた」——これがデグレード(=品質が後退すること)
・デグレードは「再テストして初めて発見できる」。テストしなければ気づかないまま
電球の例で考えると、配線を直して1か所の電球を点けたら、別の電球が消えた──それに気づくには、全部の電球をもう一度点けて確かめるしかありません。修正後に「変えていない部分も含めた全体」を再確認するのが回帰テストの本質です。
デグレード(デグレ・先祖返り)とは、修正や機能追加によって、それまで正しく動いていた機能が壊れてしまうことです。「グレード(品質)がデ(下)がる」→「品質の後退」というイメージです。
デグレードが起きやすい状況の例は次のとおりです。
・複数の機能が同じ処理を共有しているとき——1か所を変えると全体に影響する
・変数やデータの受け渡しが多いとき——データの形や意味がずれる
・急いで修正したとき——影響範囲を十分に確認できていない
回帰テストでデグレードをすぐに発見することが、リリース後に利用者が不具合に遭遇するリスクを大幅に下げます。修正のたびに回帰テストを実行する習慣が、品質の高いソフトウェアを維持する基本です。