Вопрос

Я нахожусь в процессе переноса моего проекта с Xcode 4.6.3 на Xcode 5.0.2.Модульные тесты проекта были разработаны с помощью SenTestingKit / OCUnit.Теперь, когда я запускаю тесты в Xcode 5, я получаю сообщение об ошибке от RunUnitTests сценарий говорит мне , что

RunUnitTests устарел.

Возможно, это замечание связано с примечаниями к выпуску Xcode 5:

SenTestingKit и OCUnit устарели.Используйте мигратор для перехода к XCTest.

К сожалению, мне не удалось узнать больше об этом таинственном "мигранте".Возможно, моего google-fu не хватает [снова], поэтому мой главный вопрос таков:Как мне перенести модульные тесты из SenTestingKit / OCUnit в новый XCTest (с "переносчиком" или без него)?

Второстепенный вопрос на случай, если миграция - сложное дело:Можно ли заставить Xcode 5 запускать модульные тесты, которые по-прежнему основаны на SenTestingKit / OCUnit?В конце концов, они просто устарели, поэтому они все еще должны быть рядом и функционировать.

Это было полезно?

Решение

Благодаря ответу Shaggy Frog мы знаем, что таинственный "migrator", упомянутый в примечаниях к выпуску Xcode, является мастером, запускаемым путем выбора "Edit > Refactor > Convert To XCTest".Я собираюсь написать о своем опыте работы с этим мастером в двух частях.Первая часть является неполным ответом на основной вопрос, вторая часть отвечает на второстепенный вопрос.


Часть 1:Как перейти с OCUnit на XCTest

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

Как только я узнал об этом, я смог пройти через мастера, но в моем случае конечным результатом по-прежнему был впечатляющий провал!Мастер заявил, что никаких изменений исходного кода не требуется и что для перехода на XCTest необходимо обновить только параметры сборки.В конце концов, мастеру даже не удалось сделать это правильно:IT сделал удалите ссылку на фреймворк SenTestingKit, но это сделало нет вставьте ссылку на фреймворк XCTest.

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

  1. Удалите фазу сборки "Запустить скрипт" из целевого объекта модульного тестирования
  2. Измените базовый класс всех классов тестовых примеров с SenTestCase Для XCTestCase
  3. Измените импортированный заголовок из <SenTestingKit/SenTestingKit.h> Для <XCTest/XCTest.h>
  4. В настройках сборки тестовой цели измените расширение оболочки на octest Для xctest.
  5. Переименуйте все макросы assert из ST* Для XCT* (например, STAssertTrue становится XCTAssertTrue)
  6. Исключение из вышеизложенного: STAssertEquals необходимо переименовать в XCTAssertEqual (обратите внимание на пропущенную букву "s" в конце).Вы поймете, что забыли об этом, если получите это предупреждение компилятора: warning: implicit declaration of function 'XCTAssertEquals' is invalid in C99
  7. Новые макросы XCSTEST assert не позволяют nil будет передано в качестве описания сбоя.Например, XCTAssertNotNil(anObject, nil) это невозможно и должно быть изменено на XCTAssertNotNil(anObject).Вы узнаете, что у вас есть эта проблема, когда получите эту ошибку компилятора: error: called object type 'NSString *' is not a function or function pointer.
  8. Если вы делай необходимо передать описание сбоя, новые макросы XCTest assert требуют постоянного выражения для спецификатора формата, точно так же, как NSString метод класса stringWithFormat: делает.Вы узнаете, что у вас есть эта проблема, когда получите эту ошибку компилятора: error: expected ')'.Несколько примеров:
NSString* formatSpecifier = @"%@";
NSString* failureDescription = @"foo";
// These are OK
XCTAssertNotNil(anObject, @"foo")
XCTAssertNotNil(anObject, @"%@", failureDescription)
// These are not OK
XCTAssertNotNil(anObject, failureDescription);
XCTAssertNotNil(anObject, formatSpecifier, failureDescription);

И последнее, но не менее важное, как уже упоминалось далее, ссылку на фреймворк XCTest необходимо добавить к цели модульного тестирования.Вы поймете, что забыли об этом, если получите ошибки компоновщика, такие как Undefined symbols for architecture i386: "_OBJC_CLASS_$_XCTestCase", referenced from: foo.

Обновление Xcode 6:Привязка к XCTest больше не требуется в Xcode 6 (фактически XCTest даже больше не указан в списке доступных фреймворков).Вместо этого установите для параметра сборки CLANG_ENABLE_MODULES значение YES (отображается в пользовательском интерфейсе как "Включить модули (C и Objective-C)").Это приведет к clang для автоматической привязки к XCTest, когда он видит #import <XCTest/XCTest.h> заявление.Подробная информация доступна в разделе Раздел "Модули" документации clang.


Часть 2:Как запустить тесты OCUnit в Xcode 5

В этот момент я получил ошибку компоновщика, которая заставила меня понять, что моя миссия по переходу на XCTest провалилась.Причина:XCTest не является частью SDK 6.1, но я все еще создаю свой проект с базовым SDK iOS 6.1 (это ТАКОЙ ответ объясняет, как интегрировать SDK 6.1 в Xcode 5).

Поскольку я не могу продолжить миграцию, мое решение на данный момент состоит в том, чтобы сохранить мои модульные тесты на основе SenTestingKit / OCUnit, пока я не найду время обновить свое приложение до iOS 7.Это то, что я должен был сделать, чтобы запустить модульные тесты:

  1. Удалите фазу сборки "Запустить скрипт" из целевого объекта модульного тестирования.Это все, что требуется, чтобы позволить Xcode выполнять модульные тесты с помощью действия "Test" ( + U) пока выбрана цель модульного тестирования.
  2. Однако это не идеально, потому что я не хочу переключать цели только для выполнения модульных тестов.Вместо этого я хочу выполнить модульные тесты пока выбрана основная цель.Поэтому вторым шагом является изменение схемы Xcode основной цели таким образом, чтобы при выполнении действия "Test" вместо него выполнялись тесты цели модульного тестирования.

Окончательное решение не так хорошо, как в Xcode 4.x, где модульные тесты выполнялись автоматически каждый раз, когда я запускал действие "Выполнить" или "Построить" основной цели.К сожалению, кажется, что я не могу заставить это работать без этапа сборки "Запустить скрипт".

Другие советы

Редактировать -> Refactor -> преобразовать в xctest

Ocunit Tests все равно будет работать, но вы можете также мигрировать.Изменения в конечном итоге являются довольно минимальными.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top