2026 Параллельные тесты iOS Simulator в Mac cloud для PR: конкурентность, матрица destination, диск и очередь

Даже при статическом анализе на Linux частоту merge ограничивают macOS Simulator. Офисные пулы Mac mini первыми упираются в конкуренцию симуляторов, рост DerivedData и невидимую глубину очереди. Материал для команд, которые хотят видеть PR-тесты как инфраструктуру: три типичных заблуждения, таблица on-prem против предсказуемых Mac cloud runner’ов, не меньше пяти операционных шагов, цифры для runbook и FAQ со ссылками на гайд API за 90 секунд и очередь сборки и DerivedData.

Схема параллельных тестов iOS Simulator на Mac cloud CI runner’ах

Содержание

1. Три заблуждения: симулятор как дешёвый контейнер

Зрелые команды уже вынесли lint и лёгкие unit-тесты на Linux. Последний барьер почти всегда — macOS Simulator до merge. Инженеры с привычкой к SSH недооценивают нелинейность PR-тестов при включённом параллелизме. Без жёстких лимитов нельзя отличить реальные дефекты от ресурсных столкновений, особенно в 2026 году, когда рядом крутятся агенты и ночные пайплайны.

  1. Линейное масштабирование воркеров: рост -parallel-testing-enabled и лавина destination на одном хосте суммирует борьбу за CPU и дисковый джиттер. Без внутреннего baseline «симуляторов на ядро performance» любой SLO в вики остаётся декларацией.
  2. Копировать release-матрицу в каждый PR: перед выкладкой в Store это уместно, на каждом коммите — дорогой шум. Не разделив блокирующие и информационные destination, вы взрываете глубину очереди в пиковые часы.
  3. DerivedData и вложения как мягкий бюджет: записи экрана, скриншоты падений и трассы по умолчанию съедают десятки гигабайт за часы. Если чистка только по выходным, среда падает из-за диска, а не продукта. Наш материал про очередь и DerivedData описывает сборочную сторону; здесь — короткие высокочастотные PR job’ы.

Сначала зафиксируйте лимиты конкурентности, уровни destination и GC, потом спорьте о минорных Xcode. Инструментированный парк runner’ов чаще снижает хвост очереди дисциплинированной уборкой, чем погоней за бетой на общих столах. Гистограммы «до/после» помогают финансам увидеть, почему почасовая Mac cloud предсказуемее займа ноутбуков.

2. Таблица: пул Mac mini против Mac cloud PR runner’ов

Матрица для первой архитектурной ревью: требование, офисный пул, предсказуемые Mac cloud runner’ы, доминирующий риск.

ТребованиеОфисный пул Mac miniMac cloud PR runner’ыЗаметки
Предсказуемый пик параллелизмаЛомается десктопами, обновлениями, интерактивными логинамиКласс инстанса фиксирован; конкурентность становится кодомСравните hosted vs self-hosted
Дисковые метки«Все думали, что кэш удалит кто-то другой»Тома на job или жёсткие prune-hook’иУдалять поддерево DerivedData в конце job
Видимость очередиЧасто устноСтык с CI-лейблами и API-автоскейломWebhook: чеклист наблюдаемости
Сетевой RTTLAN низкий, топология хаотичнаРегионы ближе к Git и артефактамСочетается с гибридом Linux+Mac
Совет: раздельно тегируйте PR и release runner’ы. PR — быстрый fail и узкие destination; release-трейны несут широкую матрицу, не отбирая симуляторы у ревьюеров.

3. Семь шагов: конкурентность, destination, уборка

  1. Таблица baseline: двадцать PR-длины job’ов на целевом профиле; фиксируйте P95, пик RSS, CPU, чтобы получить верхнюю границу симуляторов на физическое ядро.
  2. Разделить блокирующий и расширенный набор destination: две последние мажорные iOS и доминирующие размеры экрана — в блокирующий; остальное nightly или release-ветки.
  3. Жёсткие таймауты и слоистые ретраи: отделяйте инфраструктурные таймауты от провалов assert; для flaky UI не больше одного retry на коммит с меткой.
  4. Хуки уборки: всегда xcrun simctl shutdown all, удалить поддерево DerivedData workspace, обрезать тяжёлые вложения до загрузки.
  5. Глубина очереди как метрика: гистограмма ожидания macOS executor’ов; при пороге — скейл или авто-откат к блокирующему набору.
  6. Граница артефактов с Linux pre-job: передавать выход компилятора и индексы, не целые кэши монорепозитория без доказанного подписанного попадания.
  7. Runbook на страницу: исполняемые формулировки («свободный диск < 12 % — отключить расширенные destination») без импровизации в Slack.
# Пример блокирующего набора; замените устройства на свои профили xcodebuild test \ -scheme YourApp \ -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.4' \ -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.5' \ -parallel-testing-enabled YES \ -maximum-parallel-testing-workers 3

4. Опорные цифры: CPU, диск, глубина очереди

Эти значения — стартовые якоря для ревью, но их нужно калибровать на ваших трассах. Во-первых, на профиле класса Apple M4 с десятью–двенадцатью видимыми performance-ядрами и 32 ГБ памяти начинайте потребительские приложения с трёх–четырёх параллельных тест-воркеров и не более четырёх «горячих» симуляторов, повышая только пока UI-сьюты упираются в CPU, а не в диск. Во-вторых, закладывайте на PR job примерно в 1,8–2,4 раза больший пик диска, чем последний успешный DerivedData, и при глобально свободном месте ниже 12 % автоматически переходите только к блокирующему набору destination — в той же терминологии, что и статья про очередь сборки. В-третьих, если глубина очереди тридцать минут подряд выше четырёх кратного числа доступных macOS executor’ов, сначала отключайте расширенные destination, а не покупайте железо: иначе flaky-тесты маскируются под нехватку мощности. В-четвёртых, записи экрана и perf-трассы по умолчанию выключены на PR (только ручные или nightly job’ы), что обычно сжимает вложения с гигабайт до сотен мегабайт. В-пятых, после merge в default храните JSON полной матрицы 24–72 часа, чтобы объяснять регрессии, которые проходят узкий PR-набор, но ломают широкую матрицу. Когда эти пять рычагов попадают в план ёмкости, появляется зеркало реальной стоимости; отсутствие цифры почти всегда означает технический долг без перевода в часы и валюту, и тогда ни продукт, ни финансы не могут ответить, сколько стоит один зелёный merge.

Дополнительно полезно вести отдельный журнал «инцидентов очереди» с короткими полями: время ожидания executor’а, число активных симуляторов, свободный диск до и после job’а, версия Xcode и флаг «расширенный набор был включён». Такой журнал за две-три недели показывает, где узкое место — в неправильных лимитах, в сетевых задержках до репозитория артефактов или в неожиданно тяжёлом UI-сьюте. Команды, которые один раз в квартал пересматривают эти записи вместе с SRE, реже покупают лишние узлы и чаще находят конкретную строку в runbook, которую достаточно изменить на одно число. Наконец, если вы уже используете лейблы для разделения Linux и Mac job’ов, добавьте лейбл уровня «pr-sim-narrow» и «pr-sim-wide», чтобы визуально видеть, какой набор destination реально едет на каждой ветке; это дешёвый сигнал для дашборда и для онбординга новых инженеров, которым иначе приходится читать половину репозитория, чтобы понять, почему их PR ждёт двадцать минут.

Ещё один практический приём — заранее договориться о «красной зоне» для диска на уровне всего пула: например, если любой узел опускается ниже пятнадцати процентов свободного пространства, автоматически запрещаются любые job’ы с широким набором симуляторов до ручного подтверждения дежурного. Это резко снижает вероятность каскадного отказа, когда несколько PR одновременно запускают тяжёлые UI-сьюты и превращают весь пул в лавину красных билдов без ясной первопричины.

5. Частые вопросы

Нужна ли полная сетка iPad и минорных OS на каждом PR?

Нет. Блокирующий набор для форм-факторов с высоким трафиком; комбинаторный взрыв — в nightly или release-пайплайны.

Параллельные тесты зависают случайно — с чего начать?

Половина воркеров, отключить записи, проверить, что job’ы не делят одну интерактивную пользовательскую сессию и не создают блокировки Simulator.

Связь с гайдом на 90 секунд?

Там — вывод runner’ов в онлайн; здесь — что делать после SSH, чтобы симуляторы и диск оставались продакшен-уровня.

6. Возврат к предсказуемой Mac-среде исполнения

Несколько Mac mini хватает на раннюю стадию, но когда растут частота PR и параллельный веер, ручная чистка дисков и договорённости в коридоре тихо становятся SPOF. Хвостовая задержка не объяснима post-mortem, глубина очереди не видна в дашбордах, ночные merge’и всё ещё играют в рулетку свободного места. Ноутбуки для CI хуже: питание, uplink и изоляция не тянут сравнение с настоящим VPS. Если нужны измеримые, деградируемые и эластичные PR-ворота, аренда Mac cloud M4 у VPSMAC как выделенный PR-пул обычно спокойнее борьбы с перегруженными столами: привычный SSH, зафиксированные классы железа, политики уборки и конкурентности в одном runbook, прямая связка с гайдами по API, очереди DerivedData и сравнению runner’ов.