Ответ 1
Важное примечание
С Xcode 5.1 (возможно, более ранний Xcode) test
- действительное действие сборки.
Мы смогли заменить весь хак ниже вызовом xcodebuild, используя действие сборки теста и с соответствующими параметрами -destination
. man xcodebuild
для получения дополнительной информации.
Информация ниже приведена для потомков
Я попытался взломать сценарии Apple для запуска модульных тестов, как указано в
Запуск Xcode 4 модульных тестов из командной строки
и
Xcode4: запуск тестов приложений из командной строки в iOS
и многочисленные подобные публикации в Интернете.
Однако у меня возникла проблема с этими решениями. Некоторые из наших модульных тестов использовали iOS Keychain, и эти вызовы при работе в среде, возникающей из-за взлома скриптов Apple, потерпели неудачу с ошибкой (errSecNotAvailable
[- 25291] для странно любопытных). В результате тесты всегда терпели неудачу... нежелательная функция в тесте.
Я попробовал ряд решений на основе информации, которую я нашел в другом месте в Интернете. Некоторые из этих решений включали, например, попытку запуска демона служб безопасности симулятора iOS. После того, как я боролся с ними, лучшим вариантом, казалось, было выполнение в симуляторе iOS с полным преимуществом симуляторной среды.
То, что я сделал, тогда было получить инструмент запуска iOS Simulator ios-sim. Этот инструмент командной строки использует частные фреймворки Apple для запуска приложения iOS из командной строки. Однако для меня было особенно полезно, что он позволяет мне передавать как переменные среды, так и аргументы командной строки в приложение, которое оно запускает.
Несмотря на переменные окружения, мне удалось получить пакет Unit Testing, введенный в мое приложение. Через аргументы командной строки я могу передать "-SenTest All", чтобы получить приложение для запуска модульных тестов и выхода.
Я создал схему (которую я назвал "CommandLineUnitTests" ) для моего модуля тестирования модулей и проверил действие "Запустить" в разделе сборки, как описано в сообщениях выше.
Вместо того, чтобы взломать скрипты Apple, я заменил script на тот, который запускает приложение с помощью ios-sim, и настраивает среду для ввода моего модуля тестирования модулей в приложение отдельно.
Мой script написан в Ruby, который мне больше знаком, чем BASH scripting. Здесь script:
if ENV['SL_RUN_UNIT_TESTS'] then
launcher_path = File.join(ENV['SRCROOT'], "Scripts", "ios-sim")
test_bundle_path= File.join(ENV['BUILT_PRODUCTS_DIR'], "#{ENV['PRODUCT_NAME']}.#{ENV['WRAPPER_EXTENSION']}")
environment = {
'DYLD_INSERT_LIBRARIES' => "/../../Library/PrivateFrameworks/IDEBundleInjection.framework/IDEBundleInjection",
'XCInjectBundle' => test_bundle_path,
'XCInjectBundleInto' => ENV["TEST_HOST"]
}
environment_args = environment.collect { |key, value| "--setenv #{key}=\"#{value}\""}.join(" ")
app_test_host = File.dirname(ENV["TEST_HOST"])
system("#{launcher_path} launch \"#{app_test_host}\" #{environment_args} --args -SenTest All #{test_bundle_path}")
else
puts "SL_RUN_UNIT_TESTS not set - Did not run unit tests!"
end
Запуск этого из командной строки выглядит следующим образом:
xcodebuild -sdk iphonesimulator -workspace iPhoneApp.xcworkspace/ -scheme "CommandLineUnitTests" clean build SL_RUN_UNIT_TESTS=YES
После поиска переменной среды SL_RUN_UNIT_TESTS
, script находит "пусковую установку" (исполняемый файл iOS-sim) в дереве исходных текстов проекта. Затем он конструирует путь к моему модульному пакетному тестированию на основе параметров сборки, которые Xcode передает в переменных среды.
Затем я создаю набор переменных среды выполнения для моего запущенного приложения, которые вводят пакет тестирования модулей. Я установил эти переменные в хеше environment
в середине script, а затем использовал некоторый рубиновый гранж, чтобы объединить их в ряд аргументов командной строки для приложения ios-sim
.
Рядом с нижним я беру TEST_HOST
из среды в качестве приложения, которое я хочу запустить, и команда system
фактически выполняет ios-sim
передачу приложения, аргументы команды для настройки среды и аргументы -SenTest All
и путь тестового пакета к запущенному приложению.
Преимущество этой схемы состоит в том, что она запускает модульные тесты в среде симулятора, так как я считаю, что сам Xcode. Недостатком схемы является то, что она использует внешний инструмент для запуска приложения. Этот внешний инструмент использует частные фреймворки Apple, поэтому он может быть хрупким с последующими выпусками ОС, но он работает на данный момент.
P.S. Я использовал "Я" много в этом посте по причинам повествования, но большая заслуга моего партнера в преступности Павела, который работал со мной с этими проблемами.