Запускать логические тесты в Xcode 4 без запуска симулятора - PullRequest
28 голосов
/ 01 сентября 2011

Я хочу запустить тесты в Xcode 4, используя OCUnit без запуска симулятора. Пожалуйста, не пытайтесь убедить меня, что я делаю модульное тестирование неправильно или что-то в этом роде. Мне нравится делать TDD традиционным способом: написать API для класса в тестах, а затем заставить класс пройти тесты. Я напишу отдельные тесты, которые являются сквозными и выполняются в симуляторе.

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

Ответы [ 7 ]

28 голосов
/ 03 сентября 2011

Может, кто-нибудь подскажет, как сделать так, чтобы тестовое устройство не создавало целое приложение?Мое приложение управляется событиями, и оно отправляет кучу событий, когда запускает этот беспорядок с моими тестами.

Я использую встроенное тестирование Xcode 4.Создание экземпляров приложения может показаться болезненным, но когда я пишу о Модульное тестирование Xcode: «Хорошо», «Плохо», «Уродливо» ), это позволяет писать тесты, не различая логические и прикладные тесты.В частности, он позволяет мне писать модульные тесты для контроллеров представления.

Вот что я делаю, чтобы избежать полной последовательности запуска:

Редактирование схемы

  • Выберите действие «Тест»
  • В «Тесте» выберите вкладку «Аргументы»
  • Отключите «Использовать параметры действия« Выполнить »»
  • Добавьте переменную среды, задав runningTestsна YES

Отредактируйте делегата приложения

  • Добавьте следующее к -application:didFinishLaunchingWithOptions:, как только это будет иметь смысл:

    #if DEBUG
        if (getenv("runningTests"))
            return YES;
    #endif
    
  • Сделайте то же самое для -applicationDidBecomeActive:, но просто return.

Обновление: я изменил свой подход,См. Как легко переключать делегат приложения для тестирования .

5 голосов
/ 05 января 2014

В последней версии xcode (5.0.2) вы можете сделать это очень простым способом. Выберите цель тестирования, вкладка «Общие». Установите «Нет» в поле «Цель». Затем нажмите на вкладку «Построить фазы» и удалите основную цель из «Целевых зависимостей».

3 голосов
/ 01 сентября 2011

В вашей ситуации я предполагаю, что у вас есть отдельная цель Тесты логики и Тесты приложений (если нет - вам нужно). В конфигурации ваших схем вы определяете, какие цели создаются для схемы «Тест». Если тесты вашего приложения не запущены, симулятор не запустится.

Я подозреваю, что вы, возможно, пытаетесь запустить «логические тесты» в цели «Тесты приложений» (такой как созданная по умолчанию Xcode). Узнайте больше об этой разнице здесь (и как настроить ut).

2 голосов
/ 03 октября 2012

Примечание, не проверенное на Xcode 5.

Я использовал @ jon-reid's answer , но обнаружил, что Xcode добавляет переменные окружения в часть xcuserstated XcodeProjects, и они специфичны для пользователя и обычно не фиксируются в репозитории. Таким образом, я прошептаю свой AppDelegate, чтобы переопределить его загрузку:

@implementation MyAppDelegate (Testing)

+ (void)initialize {
    SEL new = @selector(application:didFinishLaunchingWithOptions:);
    SEL orig = @selector(swizzled_application:didFinishLaunchingWithOptions:);
    Class c = [self class];
    Method origMethod = class_getInstanceMethod(c, orig);
    Method newMethod = class_getInstanceMethod(c, new);

    if (class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) {
        class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
    } else {
        method_exchangeImplementations(origMethod, newMethod);
    }
}

- (BOOL)swizzled_application:(id)app didFinishLaunchingWithOptions:(id)opts {
    return YES;
}

@end

Обратите внимание, что следующее проще и все еще работает, хотя я не уверен, что это надежно:

@implementation MyAppDelegate (Testing)

- (BOOL)application:(id)app didFinishLaunchingWithOptions:(id)opts {
    return YES;
}

@end

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

2 голосов
/ 21 апреля 2012

В предыдущем ответе было указано, что логические тесты - правильная вещь для этого сценария.У меня были очень трудные времена, чтобы заставить логические тесты работать с XCode версии 4.3.2 (4E2002).Глядя на образец тестового проекта Apple , я понял, как сделать это с четким разделением.В этом примере логика тестирует тестовые файлы из библиотеки, а не из приложения.Модель была инкапсулирована в библиотеку, которая затем была связана с основной целью и целью логических тестов.Цель приложения содержала только представления и контроллеры.

Основываясь на этой модели, это то, что я сделал, чтобы мои логические тесты работали правильно.Создайте новую цель (Cocoa Touch Static Library) и переместите все файлы для проверки логики (как правило, все ваши модели) в эту новую цель.В настройках «Фазы сборки» добавьте эту новую библиотеку в «Связать двоичные файлы с библиотеками» вашей цели приложения и цели логических тестов.

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

1 голос
/ 25 мая 2016

Использование xCode 7 и xctool

xctool может выполнять модульные тесты без симулятора.

Чтобы это работало,

1.Обновление целевых параметров запускается без хост-приложения.

Выберите проект -> затем проверьте цель -> Установите для хост-приложения значение none.

enter image description here

2.Установите xctool, если у вас его нет.

brew install xctool

3.Запустите тесты, используя терминал с xctool.

 xctool -workspace yourWorkspace.xcworkspace -scheme yourScheme run-tests -sdk iphonesimulator
0 голосов
/ 01 сентября 2011

Я использовал GHUnit для создания совместимых с osx / ios наборов тестов.Есть несколько проблем, но я обнаружил, что это было более надежно / совместимо / просто, чем OCUnit.

GHUnit предоставляет базовые проекты шаблонов для OS X и iOS, что упрощает первоначальную настройку.

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

...