Я знаю, что могу запустить модульные тесты своего приложения с помощью xcodebuild
, но мне интересно, что говорит приложению запускать тесты во время запуска, это специальный аргумент, отправленный приложению, или он скомпилирован по-другому для запуска тестов (с XCTest)?
Как приложение ios знает, что нужно запускать модульные тесты
Ответы (2)
Xcode использует сценарии xctest
и RunTargetUnitTests
(из /Developer/Tools/RunTargetUnitTests
) для модульного тестирования.
xctest
внедряет dynamic library
(набор для тестирования, который имеет отдельный поток для своих задач) в ваш двоичный файл, инъекция дает dylib
доступ к вашей памяти процесса (он может получить доступ к вашим классам/экземплярам в вашей памяти процесса), и он может выполнять вызовы и создавать единицы тесты. Обратные вызовы от устройства/симулятора принимаются от отладчика (специальной техники модульного тестирования нет).
Проще говоря: проект с test scheme
компилируется как обычно, но это линковка динамической библиотеки, которая будет троянить память вашего процесса, и делать тесты.
Также очень полезная информация:
RunUnitTests
принимает ENVIRONMENT variables
, вот некоторые интересные из них
TEST_HOST
— полный путь к исполняемому файлу, в который нужно «внедрить» указанный пакет модульных тестов. Для приложения это должен быть полный путь к приложению в его оболочке. Не устанавливайте это для каркасных работ или библиотек.
TEST_RIG
— полный путь к исполняемому файлу для использования в качестве тестовой установки вместо CPlusTestRig или otest. Исполняемый файл должен указать путь к тестовому пакету в качестве последнего аргумента. Его DYLD_FRAMEWORK_PATH и DYLD_LIBRARY_PATH будут настроены так, чтобы они указывали на BUILT_PRODUCTS_DIR перед выполнением. Не устанавливайте это, если вы используете один из тестовых стендов по умолчанию.
такжеBUNDLE_LOADER
используется как параметр компоновщика, который указывает компоновщику связать Testing dynamic library
с указанным двоичным файлом.
Целевые шаблоны тестовых пакетов имеют фазу сборки сценария оболочки в самом конце, которая вызывает /Developer/Tools/RunUnitTests
. RunUnitTests просматривает параметры сборки, которые он передает через свою среду, и определяет на основе этой информации, как запускать тесты в вашем тестовом пакете.
Если вы тестируете фреймворк, RunUnitTests запустит соответствующую тестовую установку и скажет ей загрузить и запустить тесты в вашем пакете. Поскольку ваш тестовый пакет должен быть связан с вашим фреймворком, ваш фреймворк будет загружен, когда тестовая установка загрузит ваш пакет.
Если вы тестируете приложение, вам необходимо указать приложение в качестве тестового хоста и загрузчика пакетов для вашего тестового пакета в настройках сборки его конфигурации. Параметр Bundle Loader указывает компоновщику связать ваш пакет с приложением, которое его загружает, как если бы приложение было фреймворком, что позволяет вам ссылаться на классы и другие символы в приложении из вашего пакета, фактически не включая их в пакет. Параметр Test Host указывает RunUnitTests запустить указанное приложение и внедрить в него тестовый пакет, чтобы запустить его тесты.
Дополнительную информацию см. на man
страницах RunTargetUnitTests
/xctest
.
https://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man1/xctest.1.html
Вот скрипт RunTargetUnitTests
#!/bin/sh # # Copyright (c) 2005-2013 Apple Inc. All rights reserved. # # Copyright (c) 1997-2005, Sen:te (Sente SA). All rights reserved. # # Use of this source code is governed by the following license: # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # (1) Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # (2) Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL Sente SA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Note: this license is equivalent to the FreeBSD license. # # This notice may not be removed from this file. if [ "${NATIVE_ARCH_ACTUAL}" = "" ]; then NATIVE_ARCH_ACTUAL=`arch` fi if [ "${ARCHS}" = "" ]; then ARCHS=`arch` fi if [ "${DEVELOPER_DIR}" = "" ]; then DEVELOPER_DIR="${SYSTEM_DEVELOPER_DIR}" fi if [ "${OTEST}" = "" ]; then OTEST="${DEVELOPER_DIR}/Tools/otest" fi if [ "${OTEST_TARGET}" = "" ]; then OTEST_TARGET="${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}" fi RunTargetUnitTestsForArch() { echo "${DEVELOPER_DIR}/Tools/RunTargetUnitTests:0: note: Starting tests for ${1}" if [ "${DYLD_FRAMEWORK_PATH}" = "" ] ; then DYLD_FRAMEWORK_PATH="${BUILT_PRODUCTS_DIR}:${DEVELOPER_DIR}/Library/Frameworks" else DYLD_FRAMEWORK_PATH="${BUILT_PRODUCTS_DIR}:${DEVELOPER_DIR}/Library/Frameworks:${DYLD_FRAMEWORK_PATH}" fi export DYLD_FRAMEWORK_PATH echo "OTEST=${OTEST}" arch -arch "${1}" "${OTEST}" "${OTEST_TARGET}" unset DYLD_FRAMEWORK_PATH echo "${DEVELOPER_DIR}/Tools/RunTargetUnitTests:0: note: Completed tests for ${1}" } SkipTargetUnitTestsForArch() { echo "${DEVELOPER_DIR}/Tools/RunTargetUnitTests:0: note: Skipped tests for ${1}" } if [ "${TEST_AFTER_BUILD}" = "YES" ]; then # Run the unit tests once per requested and supported architecture. for TEST_ARCH in ${ARCHS}; do case "${NATIVE_ARCH_ACTUAL}" in i386) if [ "${TEST_ARCH}" = "i386" ]; then RunTargetUnitTestsForArch "${TEST_ARCH}" else SkipTargetUnitTestsForArch "${TEST_ARCH}" fi ;; x86_64) if [ "${TEST_ARCH}" = "i386" -o "${TEST_ARCH}" = "x86_64" ]; then RunTargetUnitTestsForArch "${TEST_ARCH}" else SkipTargetUnitTestsForArch "${TEST_ARCH}" fi ;; *) RunTargetUnitTestsForArch "${TEST_ARCH}" ;; esac done fi
xctest/otest
вызывается скриптом RunTargetUnitTests
, и я не вижу никаких инъекций dylib.
- person Droppy; 31.07.2014
dynamic libraries
вводятся с помощью инструмента otest
/xctest
. otest
/xctest
вызываются из Xcode.
- person l0gg3r; 31.07.2014
TEST_RIG
, TEST_HOST
, а также BUNDLE_LOADER
в свой ответ, и вы получите мой голос.)
- person Eimantas; 31.07.2014
otest
или xctest
вообще вызываются для iOS.
- person Sulthan; 31.07.2014
RunUnitTests is obsolete. To run unit tests for your target, use the Test scheme action in the Xcode IDE and the test action in xcodebuild.
- person jmkk; 22.09.2015
Я знаю, как это работало с OCTest, и я полагаю, что XCTest работает аналогичным образом.
Раньше я запускал свои тесты с помощью WaxSim
, утилиты, которая обращается к частным платформам симулятора. Использование WaxSim
здесь не очень важно, оно просто позволяет нам осмотреть внутренности.
Команда запуска выполнялась MyApp.app
в симуляторе. Чтобы запустить тесты, их нужно сначала залить (они скомпилированы в отдельный бандл!). Команда выглядела так
WaxSim \
-e DYLD_INSERT_LIBRARIES="$INJECTION_FRAMEWORK_PATH" \
-e XCInjectBundle="MyApp.octest" \
-e XCInjectBundleInto="MyApp.app/MyApp" \
MyApp.app \
-SenTest All
Где INJECTION_FRAMEWORK_PATH
был определен следующим образом:
XCODE_PATH=$( xcode-select --print-path )
PLATFORM_PATH="$XCODE_PATH/Platforms/iPhoneSimulator.platform"
INJECTION_FRAMEWORK_PATH="$PLATFORM_PATH/Developer/Library/PrivateFrameworks/IDEBundleInjection.framework/IDEBundleInjection"
Также обратите внимание на параметры командной строки -SenTest All
, которые сообщали фреймворку, какие тесты запускать.
По сути, приложение работало как всегда, но был добавлен еще один пакет для запуска тестов один за другим, а затем выход из всего приложения.
xctest
для запуска тестов, а не приложения? developer.apple.com/library/ mac/документация/Дарвин/Справочник/ - person trojanfoe   schedule 25.07.2014