SenTestingKit в Xcode 4: асинхронное тестирование?
Я искал способ использования SenTestingKit для проведения интеграционного тестирования между моим клиентским кодом и нашим сервером. Мне не повезло. Кажется, что когда код запускается в методе, объект уничтожается. Это означает, что любые асинхронные ответы никогда не вызывают селекторов.
Вопросы:
- Есть ли способ сохранить экземпляр объекта до тех пор, пока я не захочу его уничтожить, т.е. после завершения тестов?
- Если нет, как я могу создать класс, который блокирует (т.е. действует синхронно), пока тесты не будут завершены?
FYI, я запускаю тестовый сервер, где я знаю ожидаемые результаты.
Я сделал справедливый бит Googling, но не видел доказательств так или иначе об этом. Я уверен, что другим тоже будет интересно.
Ответы
Ответ 1
Два варианта:
- перейти на GHUnit, который фактически содержит поддержку для ожидания асинхронных событий
- сузить дизайн ваших тестов, чтобы вы могли тестировать вещи, когда они стоят. Например. проверьте, что ваш код контроллера заставляет селектор быть отсоединенным и запущенным, и (отдельно) проверить, что этот селектор делает то, что он должен. Если обе эти вещи работают, тогда вы можете быть уверены, что ваш контроллер отделяет правильную работу.
Ответ 2
Семафор можно использовать для ожидания завершения асинхронного метода.
- (void)testBlockMethod {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
// Your block method eg. AFNetworking
NSURL *url = [NSURL URLWithString:@"http://httpbin.org/ip"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(@"IP Address: %@", [JSON valueForKeyPath:@"origin"]);
STAssertNotNil(JSON, @"JSON not loaded");
// Signal that block has completed
dispatch_semaphore_signal(semaphore);
} failure:nil];
[operation start];
// Run loop
while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW))
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate dateWithTimeIntervalSinceNow:10]];
dispatch_release(semaphore);
}
http://samwize.com/2012/10/03/sentestingkit-does-not-support-wait-for-blocks/
Ответ 3
Kiwi поддерживает асинхронное тестирование. Kiwi - это Поведенческая разработка (BDD) библиотека для iOS, которая расширяет SentTestingKit (OCUnit), поэтому ее легко настроить и использовать.
Кроме того, проверьте:
Ответ 4
Этот проект https://github.com/hfossli/AGAsyncTestHelper имеет очень удобный макрос
WAIT_WHILE(<expression_to_evaluate>, <max_duration>);
Что позволяет вам написать тест так:
- (void)testDoSomething {
__block BOOL somethingIsDone = NO;
[MyObject doSomethingAsyncThenRunCompletionBlockOnMainQueue:^{
somethingIsDone = YES;
}];
WAIT_WHILE(!somethingIsDone, 1.0);
NSLog(@"This won't be reached until async job is done");
}
Ответ 5
Оформить проект SenTestingKitAsync - https://github.com/nxtbgthng/SenTestingKitAsync. Связанный блог здесь - http://www.objc.io/issue-2/async-testing.html