Подождите XCTestExpectation перед началом следующего модульного теста в XCode

У меня есть ряд асинхронных модульных тестов, которые работают правильно самостоятельно, используя ожидания. Однако, когда я запускаю все тесты в костюме, они не ждут завершения друг друга - асинхронные обратные вызовы все еще ожидают, когда начнутся следующие тесты. Я хочу, чтобы каждый тест ожидал ожиданий предыдущего теста перед запуском. Эти тесты используют общую базу данных, поэтому их наложение приводит к раздражающей дополнительной сложности и провалам тестов при запуске в виде пакета.

- (void)testSignIn {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.

XCTestExpectation *expectation =
[self expectationWithDescription:@"Expectations"];

[_userManager signInWithUsername:kUserEmail andPassword:kUserPassword
                         success:^{
                             XCTAssertNotNil([_userManager getCurrentUser]);

                             XCTAssertNotNil([_userManager getCurrentUser].plan);
                             XCTAssertTrue([_userManager getCurrentUser].plan.liveStream == TRUE);

                             [expectation fulfill];

                         } failure:^(EDApiError *apiError) {
                             XCTAssertTrue(FALSE); // Should not fail
                             [expectation fulfill];

                         }];

[self waitForExpectationsWithTimeout:5.0 handler:^(NSError *error) {
    if (error) {
        NSLog(@"Timeout Error: %@", error);
    }
}];

}

2 ответа

Используйте XCTWaiter или waitForExpectations(timeout:handler:), чтобы остановить завершение каждого теста, пока ожидания не будут выполнены.

В этом блоге рассказывается о некоторых более сложных подводных камнях, с которыми вы можете столкнуться при написании асинхронных тестов, и о том, как их предотвратить: https://jeremywsherman.com/blog/2016/03/19/xctestexpectation-gotchas/

Я обнаружил, что вам нужно оправдать ожидания в основном потоке, что важно, если ваш асинхронный блок завершения работает в другом потоке. Я также обнаружил, что проблема может быть вызвана ошибочным тестом, который выполнялся ранее, поэтому он не всегда вызывается тестом, в котором проявляется сбой.

Кроме того, следите, не порождаете ли вы много асинхронных блоков (я делаю это для сумасшедших тестов безопасности потоков, или тесты, проверяющие, что монопольный доступ к ресурсу работает, как ожидалось, и в ожидаемом порядке). Как только вы выполните ожидание, тестирование переходит к следующему тесту, но если после этого вы выполнили много асинхронных блоков, возможно, они все еще работают.

Другие вопросы по тегам