回帰テストは、変更後にアプリケーションを再確認して、以前動作していた機能の欠陥を検出するプロセスです。コードの変更(新機能、バグ修正、リファクタリング)は、意図せずに既存のアプリケーション機能を壊す可能性があります。回帰テストは、古い機能が引き続き動作することを自動的に検証します。IBM, 2023の調査によると、回帰テストは商用プロダクトチームで実行される全テストの30〜70%を占め、本番インシデントに対する主要な防御壁としての役割を強調しています。
重要なポイント
回帰テストは、コードの変更が既存の機能を壊していないことを確認するためのテストの一種です。「回帰」という用語は、以前のバージョンで動作していた機能が新しいバージョンで動作しなくなる、より悪い状態への回帰を意味します。回帰テストは各開発サイクルで繰り返し実行され、一度だけ書かれる新機能テストとは異なります。
回帰テストの必要性は、カスケード変更の効果から生じます。あるモジュールのバグ修正が問題を解決する一方で、それに依存していた隣接機能を壊す可能性があります。たとえば、ユーザーリポジトリのSQLクエリを変更すると認証が高速化される一方で、同じクエリを使用していたデータエクスポートが壊れる可能性があります。データエクスポートの回帰テストは、リリース前にこの問題を検出します。
CISQ 2023レポートによると、本番環境で発見された回帰欠陥の修正コストは、自動回帰テスト段階の15倍です。Capgemini World Quality Reportによると、自動回帰テストに投資する企業は、導入から1年以内にリリースにおける回帰欠陥の割合を25%から5%に削減します。
回帰テストには、範囲とテスト選択基準が異なるいくつかのアプローチがあります。アプローチの選択は、プロジェクトの規模、変更の頻度、CIパイプラインで利用可能な時間によって異なります。以下に、その特性とともに回帰テストの主要な種類を示します。
完全回帰テストは、例外なくプロジェクトのすべての自動化テストを実行します。このアプローチは最大の信頼性を提供しますが、かなりの計算リソースと時間を必要とします。完全実行は、2〜4週間ごとの主要リリース前に行われます。5000テストのアプリケーションの場合、完全実行にはインフラストラクチャに応じて2〜6時間かかります。
選択的アプローチは、変更されたモジュールに関連するテストのみを実行します。関連性を判断するために、コードレベルの依存関係分析が使用されます。UserRepositoryクラスが変更された場合、UserRepositoryに直接的または推移的に依存するテストが実行されます。Jacoco、Android Test Coverage、Xcode Code Coverageなどのツールは、正確な選択のためのカバレッジマップを提供します。選択的実行は各プルリクエストで行われ、5〜15分かかります。
リスクベース回帰テストは、機能の重要度と破損の可能性によってテストをランク付けします。重要な機能(決済、認証、同期)はコード変更のたびにテストされます。補助的な機能(「について」画面、アニメーション)はリリース前のみテストされます。ランキングは、本番インシデントデータに基づいて四半期ごとに見直されます。
回帰テストと再テストの概念は、異なるプロセスであるにもかかわらず、しばしば混同されます。再テストは、欠陥修正後に、以前失敗した特定のテストを再実行することです。再テストの目的は、修正が機能することを確認することです。バグが再現されなくなることを確認します。再テストは、修正と開発者による修正確認の直後に1回実行されます。
回帰テストは、変更されていない既存の機能に対してテストを実行することです。目標は、1つの欠陥を修正しても別の場所に新しい欠陥が生じていないことを確認することです。回帰テストは、どの特定のバグが修正されたかに関係なく、各開発サイクルで繰り返し実行されます。主な違い:再テストは修正自体を検証し、回帰テストは修正の結果を検証します。
CI/CDパイプラインでは、両方のプロセスが順次実行されます。プルリクエストをマージした後、特定のバグの再テストが実行され、その後に完全または選択的回帰テストが実行されます。SmartBear(2022)によると、これらのプロセスを分離することで、失敗したCI実行の診断時間が30%短縮されます。これは、チームがどの欠陥が回帰に関連し、どの欠陥が機能しない修正に関連するかを即座に確認できるためです。
回帰テストの自動化は、現代のモバイルプロジェクトにとって重要な成功要因です。手動回帰テストはスケーラブルではありません。200テストのスイートの場合、1回の実行にQAエンジニアの2〜3営業日が必要で、毎日の実行は不可能です。自動化された回帰テストは、人間の介入なしに10〜60分で実行され、各コミットまたはプルリクエストで実行できます。
回帰スイートを最新の状態に保つために、テスト分析が使用されます。Allure、ReportPortal、Xrayなどのツールは、各テストの合格率、期間、安定性を追跡します。安定性が90%を下回るテスト(要件変更により頻繁に壊れる)は、レガシーとしてマークされ、レビューのために所有者に割り当てられます。
JUnit 5ライブラリとEspressoを使用したAndroidでの自動回帰テストの設定を見てみましょう。この例は選択的回帰を示しています。ユーザーリポジトリのリファクタリング後にプロファイル画面が壊れていないことをテストが検証します。iOSでは、同様のロジックでXCTestが使用されます(主要なシナリオでの繰り返しテスト)。
このテストはMockWebServerを使用してサーバーをエミュレートし、完全なパスをチェックします。ユーザーデータの読み込み、プロファイル画面での表示、サーバーが利用できない場合のエラー処理などを検証します。このようなテストは回帰スイートに含まれ、module-profileの変更ごとに実行されます。
@RunWith(AndroidJUnit4::class)
class ProfileRegressionTest {
@get:Rule
val composeRule = createComposeRule()
@Test
fun profileScreen_rendersCorrectly() {
val user = User(id = 1, name = "Alice", email = "alice@test.com")
composeRule.setContent {
ProfileScreen(user)
}
composeRule.onNodeWithText("Alice").assertIsDisplayed()
composeRule.onNodeWithText("alice@test.com").assertIsDisplayed()
}
@Test
fun profileScreen_handlesNetworkError() {
setNetworkError()
composeRule.onNodeWithText("読み込みエラー").assertIsDisplayed()
}
}
iOSの場合、回帰テストはXCTestExpectationを使用して、APIからデータを受信した後のUI更新を非同期で検証します。テストはネットワーク応答をエミュレートし、UI要素が正しく更新されたことを確認します。
class ProfileRegressionTests: XCTestCase {
func testProfileScreen_rendersCorrectly() {
let viewModel = ProfileViewModel(userId: 1)
let view = ProfileView(viewModel: viewModel)
viewModel.loadProfile()
let expectation = expectation(description: "profile loaded")
viewModel.onProfileLoaded = {
XCTAssertEqual(viewModel.userName, "Alice")
XCTAssertEqual(viewModel.userEmail, "alice@test.com")
expectation.fulfill()
}
waitForExpectations(timeout: 3.0)
}
}
効果的な回帰スイートの構築は、欠陥とコード変更データに基づく反復プロセスです。初期戦略は、既存のテストをすべて回帰スイートに含め、各リリース前に完全実行を行うことです。テストベースが成長するにつれて(2000テスト以上)、完全実行は長くなりすぎ、選択的アプローチが必要になります。
第2フェーズ — 依存関係分析ツールの導入:Android用のJacoco、iOS用のXcode Test Plan。これらのツールは「テスト — クラス — メソッド」マップを構築し、特定の変更によってどのテストが影響を受けるかを判断できます。Spotify Engineering(2022)によると、カバレッジ分析に基づく選択的実行は、95%の回帰検出効果を維持しながら、実行時間を60〜80%削減します。
第3フェーズ — 継続的な監視と最適化。6か月間失敗しなかったテストは、優先度の低いスイートに移動されます。月1回以上失敗するテストはレビューの候補です。実際の問題を捕捉しているか(修正が必要)、または脆弱すぎるか(安定化が必要)です。回帰スイートの四半期ごとのレビューは、その効果と実行速度を維持するための標準的なプラクティスです。
よくある質問
選択的回帰テスト — 各プルリクエストで実行します。完全回帰テスト — 各リリース前および毎週(ナイトリービルド)で実行します。重要なルール:実行頻度が高いほど、回帰を迅速に検出でき、修正コストも低くなります。重要なプロジェクトでは、マージのたびに完全回帰テストを行うことも可能です。
すべてのユニットテスト(基本回帰)、主要コンポーネントの統合テスト、重要なユーザーシナリオのUIテストを含めます。含めないでください:実験的機能のテスト、flakinessが10%を超えるテスト、手動環境が必要なテスト。
削除された機能のテストを削除し、要件が変更されたらテストを更新し、四半期ごとにスイートの監査を実施します。CI分析(Allure、ReportPortal)は、関連性を失ったテストを特定するのに役立ちます。3か月間変更も失敗もなかったテストは、毎日の実行から削除する候補です。
複数のデバイスでテストを並列実行し、変更されたコードのカバレッジ分析に基づく選択的回帰を導入し、無関係な画面のビジュアルスナップショットを無効にします。目標時間:選択的実行は5〜10分、完全実行は2時間以内。
いいえ、回帰テストには手動チェックも含まれます。リリース後の探索的テスト、UX回帰、インターフェース変更後のアクセシビリティチェックなどです。自動化がカバーするのは回帰チェックの70〜80%で、残りの20〜30%は手動で、自動化が不可能またはコストがかかりすぎるシナリオに焦点を当てています。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。