モバイルアプリテストは、アプリケーションが正しく動作し、クラッシュせず、要件を満たしていることを確認するプロセスです。Software Testing Help (2025)によると、自動テストは手動テストと比較して回帰チェックの時間を70~80%削減します。この記事では、テストレベル、iOSとAndroidのツール、TDDとBDD、そしてCI/CDについて解説します。
重要ポイント
ユニットテストはモバイルアプリテストの基礎です。コードの最小単位—単一の関数、メソッド、クラスをシステムの残りから分離して検証します。モバイル開発では、ユニットテストはJUnit(Android)とXCTest(iOS)で記述されます。優れたユニットテストは高速で、独立しており、再現可能でなければなりません—ネットワーク、データベース、UIコンポーネントに依存してはいけません。分離にはテストダブル(モック、スタブ、フェイク)が使用されます。
Mockito(Java/Kotlin)とMockK(Kotlinファースト)はAndroidでモックオブジェクトを作成する人気のライブラリです。iOSでは、OCMock、Cuckoo、または手動プロトコルが使用されます。ルール:ユニットテストはビジネスロジックとデータモデルをカバーする必要があります。UIテストはユニットテストを重複してはいけません—UIテストはユーザーとインターフェースの相互作用を検証します。
統合テストはコンポーネント間の相互作用を検証します:データベースとのリポジトリ、APIサービスとのViewModel、画面間のナビゲーション。ユニットテストとは異なり、統合テストは実際のまたは実際に近い依存関係(例:インメモリデータベースやモックサーバー)を使用します。RobolectricはエミュレータなしでJVM上でAndroidテストを実行するフレームワークで、統合テストを10倍高速化します。
スナップショットテスト(ゴールデンテスト)は、レンダリングされたUIコンポーネントを参照画像(スナップショット)と比較する特別な統合テストです。外観が変更されるとテストは失敗し、開発者は何が変更されたかを確認できます。Facebook SnapshotTestCase(iOS)とShot(Android)はスナップショットテストの人気ツールです。
E2Eテスト(エンドツーエンド)は、アプリの起動、ログイン、アクションの実行、結果の確認まで、完全なユーザーシナリオを最初から最後まで検証します。UIテストはインターフェースに焦点を当てたE2Eのサブセットです。ツール:Espresso(Android)、XCUITest(iOS)、Detox(React Native)。E2Eテストは最も遅いため、CIで別途実行されます—通常はナイトリービルドで。
XCTestはAppleのモバイルアプリ用ユニットテストフレームワークです。XCTestRunnerはシミュレータまたは実機でテストを実行します。テストはXCTestCaseを継承し、準備とクリーンアップのためにsetUpとtearDownを含みます。XCTestにはアサーション用のXCTAssert(XCTAssertEqual、XCTAssertNil、XCTAssertTrue)と非同期操作を待機するXCTWaiterが含まれています。
簡単なXCTestの例:Userモデルを作成し、初期化の正確性、名前の書式設定、年齢計算を検証します。Xcodeのコードカバレッジはテストでカバーされているコード行を示します—商用プロジェクトの目標:ビジネスロジックの少なくとも70~80%のカバレッジ。XCTestはxcodebuild testを介してXcode ServerおよびCIシステムと統合されています。
XCUITestはAppleのUIテストフレームワークです。アクセシビリティ識別子を介して動作します:XCUIElementQueryはラベル、識別子、またはタイプによってボタン、入力フィールド、テーブルを見つけます。XCUITestはアクションのシーケンスを記録(レコード/プレイバック)し、テストコードを生成します。重要:安定したテスト運用のために、すべてのUI要素にaccessibilityIdentifierが必要です。
JUnitはJava/Kotlinでのモバイルアプリの単体テストの基本フレームワークです。Androidでは、JUnit 4(最新安定版4.13.2)と新しいプロジェクト向けのJUnit 5が使用されます。Mockitoはモックオブジェクトを作成するライブラリです:when(mock.method()).thenReturn(value) — テスト対象クラスを依存関係から分離する標準パターン。
Android用JUnitテストの例:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class LoginViewModelTest {
@Mock
AuthRepository authRepository;
@Test
public void login_emptyEmail_returnsError() {
LoginViewModel vm = new LoginViewModel(authRepository);
String result = vm.login("", "password123");
assertEquals("Email cannot be empty", result);
verify(authRepository, never()).authenticate(any());
}
}
EspressoはGoogleのAndroid UIテストフレームワークです。Espressoは自動的にUIスレッドと同期します:onView(withId(R.id.button)).perform(click()).check(matches(isDisplayed()))。Espressoは組み込みのアイドル状態待機により、記述が容易で安定しています。UI Automatorはシステム要素(権限ダイアログ、通知シェード)と対話できるクロスアプリケーションテストのフレームワークです。
DetoxはWixによるReact Nativeモバイルアプリテスト用のグレーボックスE2Eフレームワークです。Detoxは内部でEspresso(Android)とXCUITest(iOS)を使用し、単一のテストコードベースから両方のプラットフォームで動作します。Detoxはアプリがアイドル状態(アニメーション、ネットワークリクエスト、タイマーなし)になるまで自動的に待機し、その後次のアクションを実行します。
AppiumはAndroid、iOS、Web、ハイブリッドアプリをサポートする汎用クロスプラットフォームフレームワークです。AppiumはWebDriverプロトコルを使用し、任意のプログラミング言語(Java、Python、JS、Ruby)をサポートします。Appium ServerはHTTPサーバーとして動作し、コマンドをネイティブのUI Automator / XCUITestコマンドに変換します。Appiumの主な欠点は速度です:テストはネイティブのEspressoやXCUITestよりも遅く実行されます。
| 基準 | iOS | Android |
|---|---|---|
| ユニットテスト | XCTest | JUnit 4/5 + Mockito |
| UIテスト | XCUITest | Espresso, UI Automator |
| スナップショットテスト | FBSnapshotTestCase | Shot, Roborazzi |
| ジェスチャー自動化 | XCUIGesture | UiAutomator touch |
| コードカバレッジ | Xcode Code Coverage | Jacoco |
| CI統合 | xcodebuild test | Gradle connectedCheck |
TDDは実装コードの前にテストを記述するモバイルアプテスト方法論です。Red-Green-Refactorサイクル:(1)失敗するテストを書く(Red)、(2)テストを通す最小限のコードを書く(Green)、(3)テストを通したままコードをリファクタリングする。TDDは新しい機能に対して100%のテストカバレッジとクリーンなアーキテクチャを提供します。なぜならテストが要件の最初の仕様だからです。
BDDはTDDの拡張で、テストを自然言語でGiven-When-Then形式で記述します。Given(コンテキスト)— When(アクション)— Then(期待される結果)。BDDテストは開発者、テスター、アナリスト、クライアントなどチームの全メンバーが理解できます。Mock vs Stub vs Fake:Mockは相互作用(メソッドが呼び出されたか)を検証し、Stubは固定データを返し、Fakeは簡略化された実用的な実装(例:インメモリDB)です。IT Sectrでは、重要なビジネスロジックにTDDを、受け入れシナリオにBDDを使用しています。
テストダブルはテストで実際の依存関係を置き換えるオブジェクトの総称です。4つのタイプがあります:Dummy(パラメータを埋めるためのオブジェクト、使用されない)、Stub(指定された値を返す)、Spy(検証のために呼び出しを記録する)、Mock(期待される呼び出しを事前定義する)。違いを理解することは適切なテスト設計にとって非常に重要です。
CI/CD—継続的インテグレーションと継続的デリバリー:コード変更のたびにモバイルアプリを自動的にビルドしてテストするプラクティスです。モバイル開発では、CI/CDパイプラインには以下が含まれます:リンター、ユニットテスト、統合テスト、APK/IPAビルド、UIテスト。GitHub ActionsとBitriseはモバイルCI/CDの人気プラットフォームです。テストは高速に実行されるべきです:ユニットテストは1〜2分、統合テストは5〜10分、UIテストは15〜30分。
Device Farmはテスト用の実機ファームです。Firebase Test Lab(Android)とXcode Cloud(iOS)は多数のデバイスモデルへのクラウドアクセスを提供します。Device Farmはエミュレータでは見えない問題を明らかにします:異なる画面サイズ、古いデバイスでのパフォーマンス、互換性の問題。IT Sectrでは、AndroidにはFirebase Test Lab、iOSにはXcode Cloudを定期的に使用しています。
よくある質問
商用プロジェクトでは、ビジネスロジックの少なくとも70~80%のカバレッジが必要です。UIコードはカバーが難しく—50%で十分です。重要なのはパーセンテージではなく、テストの品質です:重要なシナリオ、エッジケース、エラー処理をテストしてください。
Mockは相互作用を検証します—特定のパラメータで特定のメソッドが呼び出されたかどうか。Stubは事前定義されたデータを返します。Mockは動作を検証し、Stubは状態を検証します。
はい、ただし重要なシナリオに限ります:ログイン、登録、注文完了、支払い。UIテストは遅くて壊れやすいです—すべての画面にテストを書かないでください。ユーザーのE2Eシナリオに集中してください。
スナップショットテスト(ゴールデンテスト)は、レンダリングされたUIコンポーネントを参照画像と比較します。外観が変更された場合(フォント、パディング、色)、テストは失敗し—開発者は変更が意図的かどうかを確認します。コンポーネントライブラリに最適です。
E2Eテストを複数のデバイスで並列実行し、Cloud Device Farmを使用し、テストを独立したグループに分割します。テストを最適化:待機を最小限にし、ネットワークリクエストにはモックを使用します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。