Подождите 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/
Я обнаружил, что вам нужно оправдать ожидания в основном потоке, что важно, если ваш асинхронный блок завершения работает в другом потоке. Я также обнаружил, что проблема может быть вызвана ошибочным тестом, который выполнялся ранее, поэтому он не всегда вызывается тестом, в котором проявляется сбой.
Кроме того, следите, не порождаете ли вы много асинхронных блоков (я делаю это для сумасшедших тестов безопасности потоков, или тесты, проверяющие, что монопольный доступ к ресурсу работает, как ожидалось, и в ожидаемом порядке). Как только вы выполните ожидание, тестирование переходит к следующему тесту, но если после этого вы выполнили много асинхронных блоков, возможно, они все еще работают.