0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Swift開発 単体テストに入門する

0
Posted at

Swift開発におけるテストの順序

Swiftでモバイルアプリを開発する場合、テストは次の2段階に分けます。
本記事では、モバイルアプリ単体のテストを扱います。

  • モバイルアプリ単体のテスト
  • サブシステムと接続するテスト

モバイルアプリ単体のテストの実施順序

順序 テスト 接続範囲 主な確認内容
1 静的検査 Swiftコードのみ コンパイル、警告、Lint、並行処理の問題
2 単体テスト クラス・関数単位 業務ロジック、入力検証、データ変換
3 View・コンポーネントテスト SwiftUI View単位 状態ごとの表示、入力、操作
4 アプリ内結合テスト アプリ内部 View、Model、UseCase、Repositoryの連携
5 UIテスト アプリ+モックAPI 主要な画面遷移と操作フロー
6 API契約テスト アプリとAPI仕様 リクエスト・レスポンス形式の一致

モバイルアプリ単体で行うテスト段階では、バックエンドAPIや認証基盤をモック、Stub、Fakeへ置き換えます。

モバイルアプリ単体完了

静的検査
  → 単体テスト
  → Viewテスト
  → アプリ内結合テスト
  → モックAPI UIテスト

1. 静的検査

アプリを実行する前に、コード上の問題を検出します。

検査 確認内容 主な手段・公式情報
コンパイル検査 型、構文、APIの使い方が正しいか Swiftコンパイラ、Xcode Build
コンパイラ警告 未使用変数、到達不能コード、非推奨APIなど Xcode Build Settings
並行処理検査 データ競合、Sendable、Actor境界の違反 Swift Concurrency
静的解析 メモリや制御フローに関する潜在的不具合 Xcode Analyze/Clang Static Analyzer設定
コーディング規約検査 命名、複雑度、強制アンラップなど SwiftLint
フォーマット検査 インデントや改行などの書式差異 SwiftFormat
依存関係検査 パッケージのバージョン固定と既知の脆弱性 Swift Package Manager、GitLab Dependency Scanning
独自ルール検査 プロジェクト固有の禁止事項 SwiftLint Custom Rules、シェルスクリプト

2. 単体テスト

関数や型の振る舞いを、UIや通信から切り離して確認します。新規開発ではSwift Testing、既存資産との互換性が必要な場合はXCTestを使用します。

テストフレームワーク 短い説明 主な用途
Swift Testing @Testや#expectを使う、Swift向けの新しいテストフレームワークです。 新規開発の単体テスト・結合テスト
XCTest Apple製アプリで長く使われている標準テストフレームワークです。 既存テストの継続、性能テスト、XCUITestによるUIテスト

Swift Testingは、2024年6月のWWDC24で発表され、2024年9月に正式版のXcode 16/Swift 6とともに利用可能になりました。

単体テストの主な対象は次のとおりです。

  • 入力チェック
  • 金額や日付の計算
  • データ変換
  • 状態遷移
  • エラー判定
  • ViewModelや状態管理クラス
  • UseCaseなどの業務処理

image.png

3. View・コンポーネントテスト

SwiftUIのView(画面表示)が、与えられた状態に対して正しく表示されるか確認します。

対象は次のとおりです。

  • 初期状態
  • 読み込み中
  • データ取得成功
  • データが0件
  • 入力エラー
  • 通信エラー
  • 長い文字列
  • Dynamic Type
  • ダークモード
#Preview("エラー") {
    LoginView(
        state: .error("ログインに失敗しました")
    )
}

ただし、Previewはテストの代わりにはなりません。Previewは表示確認を速める手段であり、期待結果を自動判定しないためです。

ロジックは単体テスト、重要な操作はUIテスト、見た目はPreviewと必要に応じた画像比較で確認します。

4. アプリ内結合テスト

複数の部品を接続し、データが正しく流れることを確認します。
アプリ内結合テストに含める範囲は次のとおりです。

含める
├── View
├── 画面Model
├── UseCase
├── Repository
├── API Client
├── DTO・Domain変換
├── Local Store
├── Token管理
└── Router

モックへ置き換える
├── バックエンドAPI
├── 外部認証基盤
├── Push通知サーバー
├── 外部ストレージ
└── 他サブシステム

優先度が最も高い接続点は、Model → UseCase → Repository → API Client → DTO → Domain Model → Repository → UseCase → Modelのフローです。

この経路を通すことで、画面から発生した要求がHTTPリクエストへ変換され、レスポンスが画面状態へ戻るまでのアプリ内部のデータフローを検証できます。

5. UIテスト

アプリを利用者と同じように操作して、主要な業務フローを確認します。通常はXCUITestを使用します。

XCUITestとは
iPhoneやiPadアプリを利用者と同じように操作し、画面の振る舞いを自動確認するApple標準のUIテスト機能です。
XCTestの一部として提供され、Xcodeから実行します。

import XCTest

final class LoginUITests: XCTestCase {
    func testLoginSuccess() {
        let app = XCUIApplication()
        app.launch()

        app.textFields["メールアドレス"].tap()
        app.textFields["メールアドレス"].typeText("user@example.com")

        app.secureTextFields["パスワード"].tap()
        app.secureTextFields["パスワード"].typeText("password")

        app.buttons["ログイン"].tap()

        XCTAssertTrue(app.staticTexts["ホーム"].waitForExistence(timeout: 5))
    }
}

UIテストは、すべての入力パターンを網羅する場所ではありません。次のような重要経路に絞ります。

  • ログインから主要画面への遷移
  • 登録・更新・削除
  • 検索
  • エラーからの復帰
  • アプリ再起動後の状態
  • 重要な権限許可・拒否

細かい条件分岐は単体テストで網羅します。UIテストを増やしすぎると、実行時間と不安定性が増えます。


0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?