【Swift/Xcode】XCTestの使い方!Unit Test(単体テスト)の作成方法

この記事からわかること

  • SwiftXCTestフレームワークとは?
  • XcodeUnit Test(単体テスト)を作成する方法
  • iOSアプリ開発におけるテストとは
  • UI Test(User Interfaceテスト)」と「Unit Test(単体テスト)」の違い
  • @testableとは?
  • アサーション(検証関数)の種類

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

iOSアプリ開発においてなかなか学べなかったテストについてまとめていきたいと思います。

今回は以下のような流れでまとめているので興味のあるところまで飛ばしながら読んでください。

  1. 開発におけるテストとは?
  2. iOSアプリとテスト
  3. XCTestフレームワーク
  4. Xcodeプロジェクトへのテストの導入方法
  5. Unit Testの実装方法

アプリ開発におけるテストの必要性

アプリ開発に限った話ではありませんが何かしらのプログラムを作る際には作成したプログラムが正しく動作しているかテストすることが重要になります。

テストを行うメリット

事前にテストを行うことでユーザーが使用している際におかしな挙動を引き起こす可能性を減らし、アプリの信頼性や使い心地を向上させることができます。

iOSアプリ開発のテスト

iOSアプリ開発におけるテストは統合開発環境であるXcode内にあらかじめ用意されている様々な種類のテストを使用することで簡略化されています。

またXcode内からメモリやCPUの使用状況を事前準備を必要なく簡単に確認することができるのでアプリケーションの速度や負荷といった性能もテストすることが可能になっています。

【Swift/Xcode】XCTestの使い方!Unit Test(単体テスト)を作ろう

アプリの性能ではなく機能的なテストにおいてXcodeは「UI Test(User Interfaceテスト)」と「Unit Test(単体テスト)」の2種類に分かれます。

UI Test(User Interfaceテスト)

UI Test(User Interfaceテスト)はiOSアプリのユーザーインターフェース(UI)をテストするためのテスト方法です。実際のユーザーが行う操作をシミュレートしながらアプリケーションの正常な動作を確認することが目的になります。

例えば以下のようなテストを行います。

Unit Test(単体テスト)

Unit Test(単体テスト)は個々のユニット(メソッド、関数、クラスなど)が期待どおりに動作するかどうかを確認するためのテスト方法です。

実装した処理自体が間違っていないか、異なる結果を出力しないかを個々にチェックすることが目的になります。

例えば以下のようなテストを行います。

別ターゲットとして管理される

iOSアプリのテストはXcodeプロジェクト内に別のターゲットとして実装されるのでテスト対象のコードとは別にビルドされます。テスト結果は、Xcodeのテストナビゲーターペインに表示され、成功、失敗、スキップなどの結果が分かります。

【Swift/Xcode】XCTestの使い方!Unit Test(単体テスト)を作ろう

SwiftとObjective-Cの両方をサポートしており、XCTestフレームワークを使用してテストを作成します。

XCTestフレームワーク

公式リファレンス:XCTestフレームワーク

XCTestフレームワークはUI Test、Unit Test、性能テストなどを作成、実行するための機能を提供するフレームワークで、主に2つのクラスが重要になってきます。

XCTestクラス

XCTestクラスはテストを作成、管理、実行するための抽象的な基本クラスです。このクラスを継承して様々なテストクラスが提供されています。

XCTestCaseクラス

XCTestCaseクラスはテストケースの基本クラスです。XCTestCaseを継承して、単体テストやUIテストなど、様々なテストケースを作成できます。テストケースのセットアップやクリーンアップのためのメソッド、アサーションを行うためのメソッドが用意されています。テストメソッドは、メソッド名がtestで始まる必要があります。

プロジェクト作成時からテストを導入する

UI TestやUnit Testはプロジェクトを作成時または作成後に導入する必要があります。

プロジェクト作成時からテストを導入するには新規プロジェクト作成時の以下の画面の際に「Include Tests」にチェックを入れるだけです。

Xcodeの新規プロジェクト作成画面

チェックを入れて作成されたプロジェクトには2つのテストターゲットが追加されていることがナビゲータエリアから確認できます。

【Swift/Xcode】XCTestの使い方!Unit Test(単体テスト)を作ろう

プロジェクト作成後からテストを導入する

プロジェクト作成後からテストを導入するためにはXcodeの上部メニューから「File」 > 「New」 > 「Target...」をクリックし、Test内の「UI Testing Bundle」または「Unit Testing Bundle」を選択して「NEXT」をクリックします。

【Swift/Xcode】XCTestの使い方!Unit Test(単体テスト)を作ろう

テストターゲット名などを設定できるので変更したければ任意の設定に変更して「NEXT」をクリックします。

【Swift/Xcode】XCTestの使い方!Unit Test(単体テスト)を作ろう

ナビゲータエリアにテストターゲットが表示されていれば導入は成功です。

【Swift/Xcode】XCTestの使い方!Unit Test(単体テスト)を作ろう

Unit Test(単体テスト)の作成方法

今回はUnit Test(単体テスト)を実際に作成してみます。テストターゲットを追加すると「[プロジェクト名]Tests.swift」というファイルが作成され、中には以下のようなコードが記述されています。


import XCTest
@testable  import Test

final class TestTests: XCTestCase {

    override func setUpWithError() throws {
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }

    override func tearDownWithError() throws {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
    }

    func testExample() throws {
        // This is an example of a functional test case.
        // Use XCTAssert and related functions to verify your tests produce the correct results.
        // Any test you write for XCTest can be annotated as throws and async.
        // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
        // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
    }

    func testPerformanceExample() throws {
        // This is an example of a performance test case.
        measure {
            // Put the code you want to measure the time of here.
        }
    }

}

testExampleメソッドはデフォルトで用意されているメソッド名なので任意のものに置き換えて使用しても問題ありません。その際には接頭辞にtestを付与する必要があります。(例:testInputなど)

実装の手順

テスト対象コードの準備

今回は単純な単体テストとして「文字列を数値に変換できるかチェックする関数」が正しく動作するか確認してみます。


struct ContentView: View {
    static func canConvertToNumber(_ string: String) -> Bool {
        return Double(string) != nil
    }
    var body: some View {
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

テストコードの作成

続いてテストコードを作成します。テストコードは「[プロジェクト名]Tests.swift」内に新しく追加していきます。接頭辞にtestをつけてテスト内容がわかりやすい名前を意識してメソッド名をつけます。


func testCanConvertToNumber() throws {
    XCTAssertEqual(ContentView.canConvertToNumber("123"),true)
    XCTAssertEqual(ContentView.canConvertToNumber("-123"),true)
    XCTAssertEqual(ContentView.canConvertToNumber("0.5"),true)
    XCTAssertEqual(ContentView.canConvertToNumber("123a"),false)
    XCTAssertEqual(ContentView.canConvertToNumber(""),false)
}

実際のテストコードにはアサーション(検証関数)を使用します。詳細は後述しますので次に進みます。

(Membershipの登録)→@testable importでOK

プロジェクトとテストはターゲットが異なるので別ターゲットのコードを参照できるようにする必要があります。Membershipの登録をして参照する方法が紹介されていることが多いですが、@testableを使用することで別ターゲットのコードを参照することが可能です。

@testable  import [プロジェクト名]

「[プロジェクト名]Tests.swift」内には最初から記載されているので特に何もしなくても良いですが、記載がない場合や新規でテストファイルを追加した場合は忘れずに記述しておきます。

新規テストファイルの追加はXcode上部メニュー>「File」>「New」>「File...」から「Unit Test Case Class」を追加します。

【Swift/Xcode】XCTestの使い方!Unit Test(単体テスト)を作ろう

Membershipを使用して登録したい場合はプロジェクトを追加すると「No such module 'XCTest'」というエラーが発生することがあるので以下の記事を参考にしてください。

【Swift/Xcode】XCTestの使い方!Unit Test(単体テスト)を作ろう

テストの実行

これで準備が整ったのでテストを実行してみます。テストごとに「開始ボタン」が左側に表示されるのでクリック、もしくはCommand + Uで実行できます。

【Swift/Xcode】XCTestの使い方!Unit Test(単体テスト)を作ろう

テストが期待通りに実行できると以下のように表示されます。

【Swift/Xcode】XCTestの使い方!Unit Test(単体テスト)を作ろう

@testableとは?

@testable属性はモジュールの内部インターフェース(関数、メソッド、クラスなど)へのアクセスを可能にする属性です。通常別ターゲットにあるファイル内部のコードを参照することはできませんが、@testableを使うことでテストで使用する目的としてコードにアクセスできます。

@testable  import モジュール名

Xcodeにおけるモジュールとは?

今回利用するモジュール名は「プロジェクト名」です。そもそもモジュールとはコードの集合体のことでありXcodeではライブラリやパッケージ、その他のアプリケーションのことを指します。

Xcodeではターゲットもモジュールと見なすのでimportするのはターゲット名になります。

アサーション(検証関数)の種類

アサーションとは「断言」などの意味を持つ英単語でプログラミングにおいては「検証する仕組み」のことを指します。

Swiftでも検証時に実行エラーを発生させるassertメソッドなどが用意されていますがXCTestでは独自の検証関数が複数用意されています。

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index