Я только что прочитал следующее сообщение и попытались реализовать описанный подход здесь:Можно ли проверить, что основная нить простаивает/сливает основной цикл?
Writing iOS acceptance tests using Kiwi - Being Agile
Все вещи описаны там работает отлично. Но! есть одна вещь, которая ломает детерминизм, когда я выполняю приемочные испытания.
Вот репо на Github, где автор поста сдвинул экспериментов (его можно найти в нижней части страницы, в комментариях): https://github.com/moredip/2012-Olympics-iOS--iPad-and-iPhone--source-code/tree/kiwi-acceptance-mk1
Рассмотрим этот код, он использует для нарезания вид:
- (void) tapViewViaSelector:(NSString *)viewSelector{
[UIAutomationBridge tapView:[self viewViaSelector:viewSelector]];
sleepFor(0.1); //ugh
}
... где sleepFor
имеет following definition behind itself:
#define sleepFor(interval) (CFRunLoopRunInMode(kCFRunLoopDefaultMode, interval, false))
это наивная попытка ('наивный' не абы но о том, что это первое, что приходит в голову) дождаться крошечного периода времени до тех пор, пока все анимации не обработаны и не замораживают все возможные события, которые (или могут быть) запланированы на (см. также this comment).
Проблема в том, что этот наивный код не работает детерминированным образом. Есть пучки взаимодействий пользовательского интерфейса, которые вызывают нажатие кнопки fx next button до исчезновения клавиатуры текущего отредактированного текстового поля и т. Д.
Если я просто увеличиваю время от 0,1 до fx 1, все проблемы исчезнут, но это приводит к тому, что каждое отдельное взаимодействие, такое как «заполнение текстового поля текстом ...» или «нажмите кнопку с заголовком ...», станет стоить одну секунду!
Поэтому я не имею в виду просто увеличить время ожидания здесь, а скорее способ сделать такие искусственные ожидания гарантией, что я могу продолжить свой тестовый пример со следующего шага.
Надеюсь, что это будет более надежный способ подождать достаточно, пока все вещи, вызванные текущим действием (все переходы/анимации или все, что происходит от основного цикла цикла).
Суммируя все это будет вопрос:
Есть ли способ, чтобы исчерпать/сливы/впитать весь материал, запланированный на основной поток и его цикл выполнения, чтобы быть уверенными, что основной поток находится в режиме ожидания и его цикл запуска «пуст»?
Это было мое первое решение:
// DON'T like it
static inline void runLoopIfNeeded() {
// https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFRunLoopRef/Reference/reference.html
while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES) == kCFRunLoopRunHandledSource);
// DON'T like it
if (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES) == kCFRunLoopRunHandledSource) runLoopIfNeeded();
}
спасибо за ответ. Это было мое оригинальное решение, прежде чем я создал этот пост. Я отправлю свой текущий через минуту. Я очень рад, что мы думаем в одном направлении! –
Я обновил свой вопрос с первой попытки, чтобы вы могли поймать мое первоначальное мышление и способ его развития (надеюсь, что так)./cc @xlc –