LoginSignup
28
22

More than 5 years have passed since last update.

Xcode8.3からXCTestExpectationが拡張されたよ

Posted at

XCTestExpectation

XCTestで非同期テストを実施するときに利用するAPI

Xcode8.3からAPIが追加されました
XCTextExpectation
XCTestCase

従来の非同期テストの書き方

// setUp()などは省略

- (void)testExample {
    XCTestExpectation* expectation = [self expectationWithDescription:@"Hoge Test"];

    Hoge* hoge = [Hoge new];
    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // 終わったらfulfill
        [expectation fulfill];
    }];

    // 3秒間待つ
    [self waitForExpectationsWithTimeout:3.0 handler:nil];
}

新しい非同期テストの書き方

今まではXCTestCaseクラスを経由してXCTestExpectationオブジェクトを作成する必要がありましたが、XCTestExpectationの指定イニシャライザを直接呼び出してのオブジェクト生成が可能になりました。
XCTWaiterクラスと組み合わせることによってできることが増えたようです。
XCTestCasewaitForExpectations:timeout:関数が追加されているので、これを使います。

- (void)testExample {
    // 指定イニシャライザ
    XCTestExpectation* expectation = [[XCTestExpectation alloc]initWithDescription:@"Hoge Test"];

    Hoge* hoge = [Hoge new];
    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        [expectation fulfill];
    }];

    [self waitForExpectations:@[expectation] timeout:3.0];
}

追加されたプロパティ

いくつかプロパティが追加されました。

expectationDescription

Descriptionを書き換えられるようになりました。

- (void)testExample {
    XCTestExpectation* expectation = [[XCTestExpectation alloc]initWithDescription:@"Hoge Test"];
    expectation.expectationDescription = @"Fuga Test";

    ・
    ・
    ・
}

expectedFulFillmentCount

成功に必要なfulfill()の回数を指定可能になりました。
デフォルトは1回。

- (void)testExample {
    XCTestExpectation* expectation = [[XCTestExpectation alloc]initWithDescription:@"Hoge Test"];
    // expectedFulfillmentCountを2回に設定
    expectation.expectedFulfillmentCount = 2;

    Hoge* hoge = [Hoge new];
    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // 1回目
        [expectation fulfill];
    }];

    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // 2回以上呼ばれたら成功
        [expectation fulfill];
    }];

    [self waitForExpectations:@[expectation] timeout:3.0];
}

assertForOverFulfill

expectedFulFillmentCountの回数以上のfulfill()が呼ばれた場合にエラーにするかどうか。
デフォルトはNO。(指定した回数以上fulfill()が呼ばれても成功扱い)
従来のAPIを使った場合も内部的にNOになる。

- (void)testExample {
    XCTestExpectation* expectation = [[XCTestExpectation alloc]initWithDescription:@"Hoge Test"];
    // 3回以上fulfill()が呼ばれたらエラーにする
    expectation.expectedFulfillmentCount = 2;
    expectation.assertForOverFulfill  = YES;

    Hoge* hoge = [Hoge new];
    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // 1回目
        [expectation fulfill];
    }];

    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // 2回目
        [expectation fulfill];
    }];

    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // 3回目の呼び出しでExceptionが発生
        // (NSException*) name: @"NSInternalInconsistencyException" - reason: @"API violation - multiple calls made to -[XCTestExpectation fulfill] for Hoge Test."
        [expectation fulfill];
    }];

    [self waitForExpectations:@[expectation] timeout:3.0];
}

isInverted

テスト条件を反転?する。
条件を満たさない(指定した回数のfulfill()が呼ばれない)場合に成功となります。

- (void)testExample {
    XCTestExpectation* expectation = [[XCTestExpectation alloc]initWithDescription:@"Hoge Test"];
    // 2回fulfill()が呼ばれなければ成功
    expectation.expectedFulfillmentCount = 2;
    expectation.inverted = YES;

    Hoge* hoge = [Hoge new];
    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // 1回目
        [expectation fulfill];
    }];

    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // コメントアウトを外して2回目が呼ばれると失敗
        // Fulfilled inverted expectation "Hoge Test".
        // [expectation fulfill];
    }];

    [self waitForExpectations:@[expectation] timeout:3.0];
}

28
22
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
28
22