Как разделить Swift Testing Linux и macOS CI? Руководство 2026
📋 Содержание
Если тесту не нужны Apple API, оставьте его в Linux CI; если ему требуются Apple SDK, Xcode, Simulator или подпись — запускайте соответствующую проверку в macOS. Такое разделение подходит командам, которые хотят сохранить общие тесты в существующем Linux-контуре, не принимая его за замену проверок Apple-приложения.
Для разработчиков Swift Package, которым нужно запускать общую логику в Linux CI.
Для инженеров Apple-проектов, разделяющих кроссплатформенные тесты и проверки Xcode.
Для DevOps-инженеров, оценивающих необходимость отдельного macOS-узла.
Swift Testing в Linux и macOS CI: граница по зависимостям
Решайте, где запускать тест, не по имени фреймворка, а по тому, что тест компилирует, импортирует и проверяет. Swift Testing — средство описания и запуска тестов. Его поддержка Linux сама по себе не делает Linux совместимым со всеми API, которые использует ваш проект. В официальном репозитории Swift Testing среди поддерживаемых платформ указаны Linux и платформы Apple, но результат для конкретного проекта зависит от его кода и зависимостей (официальный список платформ Swift Testing).
Для CI это два разных вопроса:
- Может ли этот тестовый target собраться и выполниться в данной операционной системе?
- Подтверждает ли результат то, что вы собираетесь выпускать?
Положительный ответ на первый вопрос не означает положительного ответа на второй. Тесты общей модели могут пройти в Linux, хотя приложение всё ещё нуждается в сборке с Apple SDK и проверке на целевой платформе. Поэтому разделяйте задачи по фактическим targets, графу зависимостей и проверяемому сценарию, а не по тому, в каком репозитории находится код.
На 13 октября 2026 года официальные материалы Swift Testing указывают поддержку Linux и платформ Apple; Swift.org публикует сведения о поддержке платформ Swift отдельно (таблица платформ Swift). Эти страницы описывают поддержку языка и инструментов. Они не гарантируют, что любой сторонний пакет, тестовый target или приложение соберётся на каждой перечисленной системе.
Полезно также отделять поддержку компилятора от доступности API. Если компилятор принимает синтаксис Swift, это ещё не означает, что для текущей операционной системы существует нужный фреймворк, реализация зависимости или поведение приложения. В CI итог зависит от всего пути — от манифеста пакета и выбранного target до фактически исполняемого теста.
Swift Package с общей логикой: Linux против Apple API
Linux CI подходит для Swift Package, если тестируемый код не требует Apple-фреймворков, а все его зависимости поддерживают Linux. Это могут быть проверки алгоритмов, правил валидации, преобразования данных и другой логики, не привязанной к поведению конкретной операционной системы.
Перед переносом тестов проверьте весь путь компиляции:
- исходники тестового target;
- продукционный target, который тест импортирует;
- зависимости обоих targets и их платформенные ограничения;
- условную компиляцию, меняющую состав кода;
- фактический набор тестов, запускаемый задачей CI.
Swift Package Manager описывает структуру пакета, targets и зависимости через PackageDescription (документация PackageDescription). Используйте её, чтобы понять конфигурацию пакета, но не трактуйте объявленную платформу как гарантию совместимости каждой зависимости с Linux. Учитывайте также, какой код включается при сборке на конкретной системе.
Если тест импортирует UIKit, он зависит от платформенного фреймворка. Apple описывает UIKit как фреймворк для пользовательских интерфейсов приложений Apple (документация UIKit). Поддержка Swift Testing в Linux не добавляет UIKit в Linux-среду. Не переносите такой тест в Linux только потому, что он находится внутри Swift Package или использует общий тестовый API.
Для первичной оценки применяйте три уровня соответствия:
- Подходит для Linux: тест не использует Apple SDK, а код и весь граф зависимостей собираются на Linux.
- Требует разделения: часть реализации общая, но условная компиляция или зависимости меняют код между платформами. Назначьте каждой ветви отдельную проверку.
- Требует macOS: тест зависит от Apple API или подтверждает поведение Apple-платформы. Запускайте его там, где доступны соответствующие инструменты и SDK.
Такое деление помогает не спутать «код можно собрать» с «проверен нужный сценарий». Если общий пакет содержит платформенные адаптеры, имеет смысл явно выделить общую логику и адаптеры в разные targets либо назначить им разные группы тестов. В противном случае Linux job может проверить только часть реализации, но итоговый статус этого не покажет.
Apple-приложение и Xcode: логика против поставки
В приложении отделяйте тесты переносимой логики от подтверждения того, что Apple-проект собирается и работает в предусмотренной среде. Linux может проверять независимую библиотеку или общий модуль, но не заменяет сборку проекта в Xcode, проверку Apple SDK, запуск в Simulator или UI-автоматизацию.
Apple описывает в документации Xcode несколько видов тестирования, а не только тесты изолированной логики (документация по тестированию в Xcode). Xcode также позволяет добавлять в проект тестовые targets (руководство по тестовым targets). Для CI важно видеть, какая проверка выполнена и какое утверждение она подтверждает, а не только общий зелёный статус.
Разделяйте задания по цели:
- Проверка общей логики: оставляйте в Linux, если тестируемые модули и зависимости там собираются.
- Сборка Apple-приложения: выполняйте в macOS с необходимым Xcode и Apple SDK.
- Проверка в Simulator: планируйте в macOS, где можно запускать приложение в симуляторе или на физическом устройстве (документация Apple о запуске приложения на симуляторе или устройстве).
- Проверка подписи и подготовки к поставке: относите к контуру, в котором доступны необходимые Apple-инструменты и учётные данные.
Если проект состоит из библиотеки и приложения, не переводите все задания в одну систему ради простоты конфигурации. Отдельная Linux-задача может быстро выявлять ошибки общей логики, а macOS-задача — подтверждать сборку и платформенные сценарии. Названия заданий должны отражать их цель: например, общие тесты, сборка приложения или проверка Simulator. Название «тесты» без уточнения не помогает понять, что именно CI проверил.
Успешная Linux-сборка доказывает только то, что соответствующий код собрался в Linux-конфигурации. Она не доказывает, что тот же код с теми же условными ветвями соберётся в Xcode. Обратное тоже верно: успешная Apple-сборка не означает, что пакет корректно поддерживает Linux, если проект заявляет кроссплатформенность. Оставьте каждому контуру собственную проверяемую цель.
Один target на разных платформах: матрица вместо статуса
Один и тот же тестовый target может собираться в разных условиях. Условные ветви исходников, доступность зависимостей и платформенное поведение меняют код, который реально попадёт в тестирование. Поэтому два успешных задания не обязательно проверили один и тот же набор assertions.
Зафиксируйте для каждого задания:
- коммит и конфигурацию сборки;
- платформу и выбранный тестовый target;
- тесты и ветви кода, которые включены или исключены;
- результат сборки отдельно от результата выполнения;
- отчёт, позволяющий установить фактический состав проверок.
При необходимости разделите тесты на группы: переносимая логика, платформенные адаптеры и Apple-интеграция. Не создавайте искусственное соответствие между заданиями ради одинакового количества тестов. Если условная компиляция исключает тест или ветвь на Linux, укажите, какой macOS job её проверяет. Если платформенная реализация различается, результат должен позволять увидеть, какая именно реализация была покрыта.
Используйте Swift Package Manager как источник сведений о структуре пакета, но сверяйте манифест с фактическим графом сборки и запуском CI. В документации Swift Package Manager описаны средства организации и использования пакетов (руководство Swift Package Manager). Для диагностики смотрите не только итоговый статус: проверьте логи компиляции, список запущенных тестов, пропуски и сохранённые отчёты.
Если общий статус не показывает, какие targets и платформенные ветви выполнялись, он не даёт достаточных оснований считать платформенную проверку завершённой.
Выбор исполнителя: список решений для Linux и macOS
Пройдите условия по порядку и назначьте каждой проверке исполнителя. Если ответ на пункт требует macOS, не считайте успешное прохождение Linux job заменой этого результата.
- [ ] Тест не импортирует Apple SDK, а его target и все зависимости собираются в Linux? Оставьте эту проверку в Linux CI.
- [ ] В пакете есть общая логика и отдельные Apple-зависимые компоненты? Разделите targets или тестовые группы: переносимую часть запускайте в Linux, платформенную — в macOS.
- [ ] Задача собирает проект в Xcode, запускает Simulator или проверяет Apple API? Выполняйте её в macOS job.
- [ ] В коде есть условная компиляция или отличающиеся реализации для платформ? Укажите, какие ветви реально покрывает каждое задание; непроверенную ветвь не засчитывайте по общему зелёному статусу.
- [ ] Проекту нужны только проверки общей логики, а Apple-платформенная поставка не входит в цель? Не добавляйте macOS-контур без конкретной проверки, которую он должен выполнять.
- [ ] macOS требуется лишь отдельным этапам? Сначала выполните одну реальную задачу проекта на подходящем исполнителе; постоянную macOS-среду оценивайте после проверки результата.
Итог выбора можно зафиксировать так: Linux подтверждает работу переносимого набора на Linux, macOS подтверждает выполнение задач с Apple-инструментами. Оба статуса полезны, если относятся к одной ревизии, имеют обозначенные targets и не подменяют друг друга.
При добавлении второго контура установите общие правила передачи результатов:
- Зафиксируйте один коммит: Linux и macOS должны проверять одну ревизию, а не изменения, попавшие в очередь в разное время.
- Запишите для каждого задания платформу, target и ожидаемый результат: общая логика, Apple-сборка или проверка в Simulator.
- Проверьте зависимости: Linux job не должен случайно собирать Apple-only target, а macOS job должен включать нужный платформенный код.
- Сохраняйте отчёты раздельно: логи сборки, список тестов и результат каждого контура должны быть доступны для проверки.
- Сверьте пропуски: условно скомпилированная ветвь или исключённый тест должны иметь назначенный контур проверки.
- Убедитесь, что итоговый статус требует все обязательные результаты, а сбой или отсутствие macOS-задачи не скрывается успешным Linux job.
Для управления проверками в Xcode можно использовать тест-планы. Apple описывает организацию тестов и улучшение обратной связи в соответствующей документации (руководство по организации тестов). Планируйте группы по назначению тестов, а не пытайтесь сделать Linux и macOS идентичными, если доступные платформенные возможности различаются.
Удалённый Mac для CI: проверка перед постоянным использованием
Если проекту нужны Apple SDK, Xcode или Simulator, начните не с переноса всего CI, а с одной реальной задачи. Возьмите коммит из обычного рабочего процесса и выполните именно ту сборку или тестирование, ради которых рассматриваете macOS-узел. Подтвердите, что выбранный target запускается, тестовый отчёт сохраняется, а полученный артефакт соответствует ожиданиям проекта.
Затем сопоставьте результаты двух платформ. Убедитесь, что Linux и macOS задания относятся к одной ревизии и что ни один отчёт не трактуется как замена другому. Если macOS job нужен только для сборки или платформенных тестов, оставьте общие тесты в Linux. Если проекту нужны регулярные Apple-проверки, уже после пробного прогона оценивайте постоянство и порядок исполнения этих задач.
При сравнении исполнителей учитывайте не только надпись «облачный». Физический Mac и виртуализированная macOS-среда могут иметь разные границы применимости, поэтому сверяйте выбранный вариант с требованиями проекта. Для такого сопоставления используйте разбор физического Mac и виртуализации macOS. Если пробная задача подтвердила потребность в отдельной macOS-среде, изучите условия аренды выделенного macOS-узла и сопоставьте их с фактическими требованиями своей CI-задачи. Не делайте вывод о пригодности узла по одной только возможности удалённого подключения: CI важны воспроизводимый запуск и доступность требуемых средств разработки.
Частые вопросы
Можно ли запускать Swift Testing в Linux CI?
Да, если тестовый код, его target и зависимости совместимы с Linux. В официальном репозитории Swift Testing Linux указан среди поддерживаемых платформ, однако поддержка фреймворка не гарантирует совместимость каждого пакета. Проверьте граф зависимостей и выполните нужный target в реальной Linux-задаче.
Какие тесты Swift Package нужно запускать в macOS Runner?
В macOS переносите проверки, которым нужны Apple SDK, Xcode, Simulator или поведение Apple-платформы. Это может быть тест отдельного пакета, если он использует UIKit или другой недоступный в Linux API. Ориентируйтесь на зависимости target и проверяемый сценарий, а не только на то, что код оформлен как Swift Package.
Заменяет ли результат Swift Testing в Linux проверку Xcode?
Нет. Успешное выполнение в Linux подтверждает только запуск выбранного набора тестов в этой конфигурации. Оно не доказывает, что проект собирается в Xcode, работает с Apple SDK без ошибок или проходит сценарий в Simulator. Для Apple-приложения оставьте отдельный macOS-результат по тем требованиям, которые Linux проверить не может.
Как разделить Linux и macOS CI в кроссплатформенном Swift-проекте?
Назначьте Linux переносимые проверки, а macOS — сборку Xcode и тесты, требующие Apple-фреймворки или Simulator. Зафиксируйте один коммит, targets и отчёты для обоих заданий. Отдельно документируйте тесты, исключённые условной компиляцией: иначе зелёные статусы не покажут, осталась ли непроверенная платформенная ветвь.
Если вы подтвердили, что проекту нужны Apple-платформенные задачи, сначала проверьте на удалённом Mac реальную сборку или тест и сопоставьте её отчёт с результатом Linux job. Без macOS-исполнителя сборка Xcode и проверки Simulator могут оставаться за пределами CI; покупка собственного Mac, в свою очередь, означает, что вам нужно самостоятельно выделить и обслуживать оборудование под эти задачи. Если macOS нужна для отдельных запусков или вы ещё проверяете, подходит ли такой контур проекту, аренда Mac у MacDate позволит оценить выполнение на реальной macOS-среде до решения о постоянном узле.