2013-10-15 6 views
6

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

Есть ли стандартный способ указать, что эти тестовые примеры должны выполняться только на конкретной версии iOS?

Один из вариантов я думал о:

- (void) testSomethingThatOnlyWorksOniOS7 
{ 
    const BOOL iOS7OrHigher = floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1; 
    if (!iOS7OrHigher) return; 

    // Actual test goes here 
} 

В качестве альтернативы, я мог сказать SenTestCase пропустить некоторые тесты динамически?

ответ

4

Ваш подход кажется хорошо для меня.

Вообще говоря, я не думаю, что есть что-то вроде «стандартного способа» для выборочного выполнения модульных тестов на основе версии iOS.

С одной стороны, ваш подход является тем же самым, что можно использовать для реализации одной функции выборочно или по-разному в соответствии с версией iOS. Возможно, вы уже знаете об этом обсуждении на CocoaWithLove: Tips and Tricks from conditional.... Это довольно старый, но описанные здесь подходы сохраняются.

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

Это может быть сделано, например, через номер версии, связанный с каждым тестом; перед вызовом реализации модульного теста вы проверяете номер версии в вызове функции, например, testSomethingThatOnlyWorksOniOS7.

EDIT:

На самом деле, все было бы проще, что я думал, что в первую очередь. Теперь я немного взломал ...

Вы можете изменить место в OCUnit, где выполняется фактический вызов метода (не знаю, извините, но я не думаю, что это должно быть трудно найти. ..), так что он проверяет имя селектора: вы конвертируете имя селектора в строку (NSStringFromSelector), и если оно соответствует некоторому регулярному выражению, вы берете какую-то конкретную ветвь (которая просто была бы в вашем случае, игнорируя этот тест).

Если вы обеспокоены изменением OCUnit, что может быть неразумно, то, что я сказал выше, можно было бы сделать с помощью метода swizzling: только если имя селектора не соответствует вашему выражению, вы вызываете оригинальную реализацию, иначе ничего не делаете.

+0

", чтобы указать, какие из них предназначены только для iOS7 и не загрязняют вашу тестовую реализацию." Да, я надеялся найти какую-то непонятную функцию OCUnit, которая позволила мне это сделать. :) – hpique

+0

Я не знаю ни одного ... но я только что добавил некоторые идеи к моему ответу ... не выглядит так сложно сделать ... – sergio

+0

Возможно, переопределение «defaultTestSuite» может работать. Стоит проверить. – hpique

3

Лучший способ запускать respondsToSelector: по методу, который, как вы знаете, доступен только на iOS 7. Например.

[view respondsToSelector:@selector(snapshotViewAfterScreenUpdates:)] 

или

[UIView instancesRespondToSelector:@selector(snapshotViewAfterScreenUpdates:)] 
+1

Использование responsesToSelector: лучшее решение, потому что это будущее доказательство. Apple может удалить метод в любое время в будущем, и проверка номера версии не удалась в этой ситуации. –

+0

Не в этом случае. Я хочу явно отметить, что тест не должен запускаться на iOS 7. Это не код приложения. Это тестовый код. – hpique

+0

Вы все еще можете запустить этот код в тесте и вернуться в начале тестового метода. –

1

Существует не стандартный способ сделать это, и, вообще говоря, тестирование не является чем-то, о чем слишком много говорит сообщество iOS. Способ, которым я хотел бы подходить к этому, - поместить конкретные тесты iOS7 в тестовую цель самостоятельно, а затем в основном решить запустить этот пакет соответственно.

+2

"и вообще тестирование не является чем-то, о чем сообщество iOS слишком много говорит о": вот почему стоит задавать эти вопросы на SO. ;) – hpique

+0

Прошу прощения, я не хотел жаловаться. Было подчеркнуто, что нет «отраслевого стандарта» или, по крайней мере, того, о котором я знаю. – cescofry

+0

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

0

Я пробовал играть с OCUnit, поскольку предлагал @sergio, но я не мог пройти далеко далеко.Пока я комментирую тесты, связанные с версией, с макросом. Это выглядит следующим образом:

#define SKIP_IF_VERSION(v) if (floor(NSFoundationVersionNumber) <= v) return; 

- (void)testSomethingThatOnlyWorksOniOS7 
{ SKIP_IF_VERSION(NSFoundationVersionNumber_iOS_6_1) 
// Test goes here 
} 

Что мне не нравится в этом подходе является то, что тест выполняется в любом случае (и ничего не делает). Я бы предпочел, чтобы тест был полностью пропущен.