Важное примечание
С Xcode 5.1 (возможно, и более ранним Xcode) test
является допустимым действием сборки.
Мы смогли заменить весь хак, приведенный ниже, вызовом xcodebuild, используя действие сборки test и соответствующие опции -destination
. man xcodebuild
для получения дополнительной информации.
Информация ниже оставлена здесь для потомков
Я пытался взломать скрипты Apple для запуска модульных тестов, как указано в
Запуск модульных тестов Xcode 4 из командной строки
и
Xcode4: запуск тестов приложений из командной строки в iOS
и множество аналогичных сообщений в Интернете.
Однако я столкнулся с проблемой с этими решениями. Некоторые из наших модульных тестов выполняли брелок для iOS, и эти вызовы, когда они выполнялись в среде, которая происходит от взлома скриптов Apple, завершились с ошибкой (errSecNotAvailable
[- 25291] для странно любопытных). В результате тесты всегда терпели неудачу ... нежелательная особенность теста.
Я попробовал несколько решений, основанных на информации, которую я нашел в Интернете. Например, некоторые из этих решений включали в себя попытку запуска демона служб безопасности симулятора iOS. После того, как я с этим боролся, мне показалось, что лучше всего было работать на симуляторе iOS с полным преимуществом среды симулятора.
То, что я сделал, затем взял в руки инструмент запуска iOS Simulator ios-sim . Этот инструмент командной строки использует частные платформы Apple для запуска приложения iOS из командной строки. Однако мне особенно пригодился тот факт, что он позволяет передавать как переменные среды, так и аргументы командной строки в приложение, которое оно запускает.
Несмотря на то, что переменные окружения, мне удалось внедрить свой пакет модульного тестирования в мое приложение. Через аргументы командной строки я могу передать «-SenTest All», необходимый для того, чтобы приложение запустило модульные тесты и завершило работу.
Я создал схему (которую я назвал «CommandLineUnitTests») для моего пакета модульного тестирования и проверил действие «Выполнить» в разделе сборки, как описано в постах выше.
Однако вместо того, чтобы взламывать скрипты Apple, я заменил скрипт на тот, который запускает приложение с помощью ios-sim и настраивает среду для добавления моего пакета модульного тестирования в приложение отдельно.
Мой сценарий написан на Ruby, который мне более знаком, чем сценарии BASH. Вот этот скрипт:
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
сценарий находит «панель запуска» (исполняемый файл iOS-sim) в дереве исходного кода проекта. Затем он создает путь к моему пакету модульного тестирования на основе параметров сборки, которые XCode передает в переменных среды.
Затем я создаю набор переменных среды выполнения для моего работающего приложения, которые внедряют пакет модульного тестирования. Я установил эти переменные в хэш environment
в середине скрипта, а затем использовал рубиновый гранж, чтобы объединить их в серию аргументов командной строки для приложения ios-sim
.
Внизу я извлекаю TEST_HOST
из среды как приложение, которое я хочу запустить, и команда system
фактически выполняет ios-sim
, передавая приложение, аргументы команды для настройки среды и аргументы -SenTest All
и путь к тестовому пакету с запущенным приложением.
Преимущество этой схемы в том, что она запускает модульные тесты в среде симулятора так же, как я полагаю, сам Xcode. Недостаток схемы в том, что она использует внешний инструмент для запуска приложения. Этот внешний инструмент использует частные фреймворки Apple, поэтому он может быть хрупким при последующих выпусках ОС, но пока работает.
P.S. Я много использовал «я» в этом посте по повествовательным причинам, но большая заслуга принадлежит моему преступному партнеру Павлу, который работал со мной над этими проблемами.