mardi 1 décembre 2015

XCTestExpectation non-determinism when yielding to UIKit for verifying UINavigationController push

I've had some luck building a passing test that uses XCTestExpectation to verify that specific ViewControllers get pushed onto a UINavigationController from a button press. The code looks like this:

// MyTestCase.m
- (void)setUp {
    [super setUp];
    _sut = // instantiate the UINavigationController somehow

    [_sut beginAppearanceTransition:YES animated:NO];
    // You have to trigger the topViewController's lifecycle methods as well, because doing it for UINavigationController's doesn't automatically do it for the topViewController
    [_sut.topViewController beginAppearanceTransition:YES animated:NO];
}

- (void)tearDown {
    [_sut.topViewController endAppearanceTransition];
    [_sut endAppearanceTransition];

    [super tearDown];
}

- (void)testThatItDoesWhatIWant {
    // When
    [_sut.topViewController.button sendActionsForControlEvents:UIControlEventTouchUpInside];

    // Then
    XCTestExpectation *expectation = [self expectationWithDescription:@"should push email sign up view controller"];

    // Yield, and UIKit a chance to perform the non-animated view controller push
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 0), dispatch_get_main_queue(), ^{

        // Some arbitrary assertions with Expecta syntax
        expect([_sut topViewController]).toNot.beKindOf([InitialTopViewControllerType class]);
        // ...

        [expectation fulfill];
    });

    [self waitForExpectationsWithTimeout:0.01f handler:nil];
}

Don't let the zero delay fool you — this actually runs and works well and does pass.

The problem is that when I have put a few more of these tests in (say, testThatItDoesWhatIWant2) the same test suite, the tests start failing non-deterministically — as if there's some timing issue or race condition.

I don't really understand why there are timing issues, because I thought that XCTestExpectation blocks the main thread, and XCTest runs everything serially. There should be no problems.

Aucun commentaire:

Enregistrer un commentaire