Главная / Блог / Как настроить се
ENGINEERING_BLOG · 2026.08.24

Как настроить сервер автоматизированного тестирования iOS? Руководство по удалённому Mac 2026

У команды xcodebuild test есть проверяемый сигнал завершения: код 0 сообщает об успешном выполнении, а ненулевой код позволяет автоматизации зафиксировать ошибку — это описано в документации Apple по командной сборке и тестированию. Поэтому сервер автоматизированного тестирования iOS лучше строить не как замену вашему рабочему компьютеру, а как отдельный этап: вы пишете код локально, а удалённый Mac собирает проект, запускает XCTest и UI-тесты, сохраняет xcresult и возвращает однозначный результат.

План на эту неделю

  • Сначала оставьте редактирование и отладку кода на Windows или Linux.
  • В первый сеанс на удалённом Mac проверьте Xcode, Simulator Runtime, Scheme и зависимости.
  • Затем запустите один тест на одном destination.
  • После этого подключите Test Plan, сохранение xcresult и повторный запуск выбранного теста.
  • К концу недели решите, нужен ли вам Mac по требованию или постоянно работающая тестовая машина.

SECTION 01 Кому подойдёт такая схема

Эта инструкция предназначена для вас, если вы пишете кроссплатформенный проект на Windows или Linux, но должны регулярно выполнять iOS-тесты. Она также подходит автору небольшого приложения, которому неудобно держать локальный Mac включённым ради XCTest или UI-регрессии.

Небольшой команде не обязательно сразу внедрять сложную CI-платформу. Отдельный удалённый Mac с root-доступом, SSH для команд и VNC или веб-консолью для проверки графической среды уже позволяет отделить разработку от воспроизводимого тестового контура. Если вы ещё не определили ограничения удалённой машины, сначала изучите требования к удалённой конфигурации Mac и совместимости Xcode.

У такого подхода есть ограничения, которые важно принять заранее:

  • macOS и Xcode остаются обязательными. Удалённый сервер не превращает Windows или Linux в среду для запуска Xcode; он лишь переносит эту среду в другое место.
  • Simulator сохраняет состояние. Разрешения, локальные базы, авторизация и оставшиеся процессы могут сделать UI-тест нестабильным.
  • Графическая сессия и командный запуск — не одно и то же. SSH удобен для xcodebuild, но визуальная проверка Simulator, диагностика зависшего окна и некоторые UI-сценарии требуют подготовленного пользовательского сеанса.
  • Результат теста не равен объяснению причины. Пакет xcresult содержит полезные результаты и журналы, однако сетевой сбой, повреждённая зависимость или зависший Simulator иногда требуют отдельного системного лога.
  • Параллельность не гарантирует ускорение. Несколько симуляторов могут конкурировать за CPU, память, дисковый ввод-вывод и общие тестовые данные. Сначала добейтесь повторяемости в последовательном режиме.

SECTION 02 До подключения: зафиксируйте границы и критерии

До аренды или настройки машины запишите четыре решения: какие тесты запускаются, как часто они выполняются, какую версию iOS вы проверяете и что считается успехом. Не начинайте с нескольких устройств: первый контрольный результат должен быть получен на одном Scheme, одном Test Plan и одном destination.

Разделите работу следующим образом:

Этап Где выполняется Что должно быть проверяемым результатом
Редактирование исходников Ваш локальный компьютер Изменения отправлены в репозиторий
Восстановление зависимостей Удалённый Mac Команда завершается без ошибки, каталог зависимостей создан
Сборка тестового продукта Удалённый Mac xcodebuild возвращает успешный код
XCTest и UI-тесты Удалённый Mac и Simulator Тестовый процесс стартует и завершается
Анализ Локально или через удалённую сессию Скачаны xcresult, журнал и дополнительные артефакты

В качестве базовой линии используйте уже существующие в проекте Scheme и Test Plan. Не меняйте одновременно настройки проекта, версию Xcode и сценарий запуска: иначе при первом падении вы не поймёте, проблема возникла в коде, окружении или миграции.

Проверьте совместимость macOS и Xcode по официальной таблице системных требований Xcode. Нужный Simulator Runtime также должен быть установлен; Apple отдельно описывает добавление дополнительных сред Simulator. Не подставляйте в скрипт конкретную версию только потому, что она была доступна на другой машине.

Важно. Названия проекта, Scheme, Test Plan, устройства, пользователя, каталога и репозитория в рабочих скриптах замените на ваши значения. В этой статье используются безопасные обозначения <PROJECT>, <SCHEME>, <PLAN>, <DEVICE> и <REPOSITORY>.

SECTION 03 Первый час: закрепите окружение удалённого Mac

Создайте отдельную учётную запись для тестов, например <TEST_USER>, и не смешивайте её домашний каталог с личными настройками администратора. Подготовьте отдельные каталоги:

mkdir -p "$HOME/test-workspace"
mkdir -p "$HOME/test-artifacts"
mkdir -p "$HOME/test-logs"

Первый каталог используйте для исходников, второй — для xcresult, скриншотов и прочих результатов, третий — для консольных журналов. Такое разделение упрощает очистку: вы не удалите случайно исходники вместе с кэшем или результатами неудачного запуска.

Проверьте активный набор инструментов:

xcode-select -p
xcodebuild -version
xcrun simctl list devices
xcrun simctl list runtimes

Путь от xcode-select должен указывать на ту установку Xcode, которую вы действительно собираетесь использовать. Если на Mac установлено несколько наборов инструментов, сначала переключите нужный путь, затем повторите проверку:

sudo xcode-select --switch /Applications/<XCODE>.app/Contents/Developer

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

Восстановите проект в чистом рабочем каталоге:

cd "$HOME/test-workspace"
git clone <REPOSITORY> <PROJECT_DIR>
cd <PROJECT_DIR>

Для Swift Package Manager это может быть отдельное восстановление зависимостей, а для проекта с CocoaPods или другим менеджером — команда из вашего репозитория. Сохраняйте вывод каждой команды в журнал и не маскируйте ошибку оператором, который всегда возвращает успешный статус.

На этом этапе достаточно минимального XCTest без UI. Он проверяет сразу несколько связей: SSH-доступ, checkout, выбор Xcode, восстановление зависимостей и запуск тестового процесса. Если этот слой не проходит, переход к UI-тестам только увеличит число возможных причин сбоя.

SECTION 04 Первый запуск: один Scheme, один destination

Для проекта с workspace используйте обезличенный пример:

RESULT="$HOME/test-artifacts/first-run.xcresult"
LOG="$HOME/test-logs/first-run.log"

set -o pipefail
xcodebuild \
  -workspace "<PROJECT>.xcworkspace" \
  -scheme "<SCHEME>" \
  -destination 'platform=iOS Simulator,id=<DEVICE_ID>' \
  -resultBundlePath "$RESULT" \
  test 2>&1 | tee "$LOG"
status=${PIPESTATUS[0]}

exit "$status"

Для проекта без workspace замените -workspace на -project. Конкретный destination лучше брать из списка устройств среды, а не вписывать название наугад. Apple описывает запуск приложения на Simulator и физических устройствах в документации о simulated и physical devices.

Здесь важны три независимых результата:

  1. проект смог разрешить зависимости и собраться;
  2. тестовый процесс действительно стартовал;
  3. оболочка получила код завершения, который можно использовать в автоматизации.

Если весь набор пока слишком велик, сузьте область:

xcodebuild \
  -workspace "<PROJECT>.xcworkspace" \
  -scheme "<SCHEME>" \
  -destination 'platform=iOS Simulator,id=<DEVICE_ID>' \
  -only-testing:"<TEST_TARGET>/<TEST_CASE>" \
  -resultBundlePath "$HOME/test-artifacts/one-test.xcresult" \
  test

only-testing нужен не для постоянного пропуска остальных тестов, а для локализации проблемы. После исправления вернитесь к полному Test Plan, иначе вы получите зелёный результат только для выбранного метода.

Test Plan разделите по назначению: быстрые unit-тесты для каждого изменения, полный набор для регрессии и более строгий сценарий перед выпуском. Такой порядок уменьшает время обратной связи без смешивания критериев. Apple объясняет организацию наборов в руководстве по Test Plan.

SECTION 05 UI-тесты: сначала сделайте состояние повторяемым

UI-тест ломается не только из-за производительности сервера. Частые причины — ожидание элемента до его появления, остаточная авторизация, другой язык, ранее выданное разрешение, уведомление системы или данные, оставшиеся от предыдущего запуска.

Для первого воспроизводимого сценария зафиксируйте:

  • тип устройства и идентификатор destination;
  • версию Simulator Runtime;
  • язык и регион;
  • тестовую учётную запись;
  • начальные данные приложения;
  • разрешения на уведомления, камеру, геолокацию и другие ресурсы;
  • стратегию очистки между запусками.

Очистка приложения, удаление данных и полная перезагрузка Simulator имеют разный охват. Перед разрушительной операцией сохраните журнал, xcresult и снимок состояния, иначе вы уничтожите доказательства сбоя вместе с причиной. Не добавляйте бездумно erase all: это может скрыть ошибку, связанную с миграцией данных или восстановлением пользовательского состояния.

Разбирайте падение по слоям:

  • Код приложения: ошибка воспроизводится в чистом Simulator и при ручном повторе.
  • Код теста: ожидание построено на задержке, а не на состоянии интерфейса.
  • Состояние Simulator: после сброса тест проходит, но причина требует отдельной проверки.
  • Удалённая сессия: команда запущена, но графический сеанс, доступ к окну или подключение были прерваны.
  • Ресурсы машины: сбой появляется только при конкурирующих задачах, а не в последовательном запуске.

Не объявляйте каждый timeout «медленным сервером». Сначала добавьте ожидание конкретного условия, проверьте логи приложения и повторите один тест в чистом окружении.

SECTION 06 Первая автоматизация: сохраняйте доказательства

Пакет результата должен иметь уникальное имя, иначе новый запуск перезапишет предыдущий. Для этого подойдёт метка времени, сформированная самим скриптом:

RUN_ID="$(date +%Y%m%d-%H%M%S)"
RESULT="$HOME/test-artifacts/<SCHEME>-$RUN_ID.xcresult"
LOG="$HOME/test-logs/<SCHEME>-$RUN_ID.log"

set -o pipefail
xcodebuild \
  -workspace "<PROJECT>.xcworkspace" \
  -scheme "<SCHEME>" \
  -testPlan "<PLAN>" \
  -destination 'platform=iOS Simulator,id=<DEVICE_ID>' \
  -resultBundlePath "$RESULT" \
  test 2>&1 | tee "$LOG"
status=${PIPESTATUS[0]}

printf 'status=%s\nresult=%s\nlog=%s\n' "$status" "$RESULT" "$LOG"
exit "$status"

В xcresult могут находиться сведения о тестах, логи и данные покрытия. Apple показывает, как просматривать результаты тестирования и интерпретировать их, а описание результата и xcresulttool помогает понять назначение пакета.

Сохраняйте вместе как минимум:

  • сам xcresult;
  • полный stdout и stderr;
  • скриншот или видео UI-теста, если сценарий это поддерживает;
  • сведения об устройстве и выбранном Runtime;
  • commit или иной идентификатор исходников;
  • код завершения;
  • причину повторного запуска, если он был.

Для повторного запуска используйте отдельную команду с only-testing, а не перезапускайте весь набор. Apple документирует повторное выполнение тестов; применяйте его как диагностический инструмент. Если второй запуск проходит, это ещё не доказывает исправность: нестабильный тест необходимо пометить, исследовать и проверить на независимом повторе.

SECTION 07 Как выбрать режим работы после первой недели

После нескольких рабочих циклов посмотрите не только на зелёные и красные статусы. Проверьте, очищаются ли старые Simulator, растёт ли каталог DerivedData, можно ли скачать артефакты после обрыва SSH и запускается ли тест после перезагрузки Mac.

Оценивайте четыре свойства:

  • воспроизводимость: одинаковый commit и одинаковое состояние дают сопоставимый результат;
  • восстановление: после сбоя можно повторить один тест без ручной настройки всей машины;
  • наблюдаемость: у каждого задания есть журнал, xcresult и понятный статус;
  • изоляция: параллельные задачи не используют одну учётную запись, один набор данных и один Simulator без необходимости.

Условия выбора

  • Если тесты запускаются эпизодически, нет ночных заданий и вы готовы подождать инициализацию среды — выбирайте арендованный Mac по требованию.
  • Если каждый день выполняются XCTest или UI-тесты, результаты должны сохраняться ночью, а повторный запуск нужен утром — выбирайте постоянно доступный Mac.
  • Если у вас несколько независимых Test Plan, но один destination и небольшая нагрузка — начните с последовательного режима и добавьте параллельность только после измерений.
  • Если несколько симуляторов конкурируют за ресурсы или используют общие тестовые данные — оставьте последовательное выполнение либо разделите состояния.
  • Если проект требует физического устройства, специального USB-доступа или длительной тяжёлой нагрузки — удалённая аренда может быть неподходящей без предварительной проверки условий.

Опытный ориентир. Сначала автоматизируйте восстановление одного теста после сбоя. Пока вы не можете получить журнал и повторить конкретный кейс одной командой, увеличение числа Simulator не решит проблему, а только усложнит расследование.

SECTION 08 Сравнение режимов для независимого разработчика

Критерий Mac по требованию Постоянный Mac для тестов Локальный Mac
Редкие регрессионные проверки Подходит лучше всего Избыточен Подходит, если устройство уже есть
Ночные задания Требует запуска и проверки готовности Подходит Зависит от состояния домашнего компьютера
Сохранение кэшей и зависимостей Ограничено жизненным циклом машины Удобнее контролировать Удобно, но занимает локальный диск
UI-диагностика Возможна при подготовленной сессии Проще организовать постоянно Обычно проще всего
Первоначальные расходы Нет необходимости покупать отдельный Mac Нет покупки, но есть регулярная аренда Нужна покупка и обслуживание
Восстановление после сбоя Нужно прописать в процедуре Можно автоматизировать на постоянной основе Зависит от доступа к устройству

Если выбираете услугу удалённой машины, до запуска проекта проверьте доступный тип Mac, способ подключения, срок аренды, права пользователя и процедуру восстановления. Сведения о вариантах и условиях можно сопоставить на странице тарифов VPSNIX, но окончательную совместимость определяет не название тарифа, а связка macOS, Xcode, Simulator Runtime и вашего проекта.

SECTION 09 Что проверять перед передачей проекта

Контрольная точка Команда или действие Критерий приёмки
Инструменты xcode-select -p, xcodebuild -version Выбран ожидаемый Xcode
Simulator xcrun simctl list devices Есть нужный destination
Исходники git clone <REPOSITORY> <PROJECT_DIR> Checkout воспроизводится
Зависимости Команда менеджера проекта Ошибки не скрываются оболочкой
Быстрый тест xcodebuild test с only-testing Получен корректный exit status
Полный набор Test Plan и фиксированный destination Все результаты сохранены
Диагностика -resultBundlePath и tee Есть xcresult и журнал
Восстановление Повтор после очистки или перезагрузки Не требуется ручное открытие проекта
Хранение Каталог артефактов и политика очистки Старые результаты не заполняют диск

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

Если после этого вы подключаете планировщик, добавьте уведомление только после сохранения артефактов. Сначала скрипт должен завершить xcodebuild, записать статус и закрыть результат; затем отдельный шаг может отправить сообщение. Иначе уведомление о сбое окажется раньше самого важного файла.

Локальная разработка плюс удалённый Mac обычно лучше, чем попытка полностью перенести редактор, Simulator и отладку на удалённую сессию: вы сохраняете быстрый цикл написания кода, а тяжёлые XCTest и UI-регрессии выполняются отдельно. По сравнению с локальным Mac такой сервер не занимает ваш рабочий компьютер и не требует покупать отдельную машину под ночные задания, но добавляет расходы на подключение, подготовку среды и передачу артефактов. По сравнению с запуском тестов на случайной временной машине постоянный экземпляр лучше сохраняет состояние, однако требует контроля кэшей, Simulator и восстановления после перезагрузки.

Если вам нужны только редкие проверки, начните с краткосрочной аренды Mac в VPSNIX и завершайте её после получения воспроизводимого результата. Если же проект каждый день выполняет XCTest, UI-тесты или ночные задания, сравните постоянный срок аренды и заранее подтвердите совместимость Xcode, Simulator и способ удалённого восстановления на странице заказа VPSNIX. Так решение будет основано на реальном цикле тестов, а не на предположении, что любой удалённый Mac автоматически станет надёжным сервером.