Такие функции, как выбор адреса доставки, проверка зоны обслуживания магазина или уведомления по геозонам, на машине разработчика часто проходят проверку после нескольких нажатий, но в автоматической сборочной линии начинают время от времени давать сбои. Обычно проблема не в алгоритме геолокации, а в том, что симулятор унаследовал координаты или разрешения от предыдущего запуска либо продолжает воспроизводить маршрут. Чтобы тесты геолокации на облачном Mac были воспроизводимыми, местоположение нужно считать тестовыми входными данными, которые явно создаются и удаляются, а не фоновым состоянием среды симулятора.
Разделите проверку на три уровня
Не следует заставлять один UI-тест одновременно проверять расчёт координат, интеграцию с системной геолокацией и состояние интерфейса. Надёжнее разделить проверку на три уровня:
- Проверять расстояния, области и переходы между состояниями обычными модульными тестами, напрямую передавая подготовленные координаты.
- С помощью небольшого числа тестов на симуляторе убеждаться, что системные данные геолокации действительно поступают в приложение и открывают ожидаемый экран.
- На реальных устройствах проверять пробуждение в фоне, дрейф сигнала, энергопотребление и поведение, связанное с датчиками.
Для бизнес-логики сначала стоит определить максимально узкую границу входных данных. Например, сервис геолокации может возвращать только координаты, время и статус разрешения. Логику проверки геозон не следует распределять непосредственно по контроллерам представлений. Тогда большинство граничных условий можно проверять без запуска симулятора, а от simctl location будет зависеть только интеграция с системой.
Смоделированные координаты показывают, как приложение обрабатывает конкретное местоположение, но не доказывают, что в реальной беспроводной среде события геолокации будут поступать с той же периодичностью.
Создавайте отдельный симулятор для каждой задачи
Сначала зафиксируйте путь к Xcode, затем выведите список типов устройств и сред выполнения, фактически установленных на текущей машине. Не закрепляйте идентификатор среды выполнения из примера навсегда: после обновления Xcode он может измениться.
sudo xcode-select -s /Applications/Xcode.app
xcrun simctl list devicetypes
xcrun simctl list runtimes
Сборочная линия должна создавать отдельный набор устройств CoreSimulator и сохранять полученный UDID в рамках текущей задачи. Тип устройства и идентификатор среды выполнения в следующем примере нужно заменить значениями, которые действительно вернула предыдущая команда.
set -euo pipefail
DEVICE_SET="$PWD/.simulator-location-tests"
DEVICE_TYPE="com.apple.CoreSimulator.SimDeviceType.iPhone-16"
RUNTIME="com.apple.CoreSimulator.SimRuntime.iOS-18-0"
rm -rf "$DEVICE_SET"
UDID="$(xcrun simctl --set "$DEVICE_SET" create GeoTest "$DEVICE_TYPE" "$RUNTIME")"
xcrun simctl --set "$DEVICE_SET" boot "$UDID"
xcrun simctl --set "$DEVICE_SET" bootstatus "$UDID" -b
Отдельный набор устройств упрощает диагностику по сравнению с постоянной очисткой общего симулятора. Каталог устройства из завершившейся с ошибкой задачи можно временно сохранить, а после успешной задачи — сразу удалить. Параллельные задачи также не будут конкурировать за одно и то же уже запущенное устройство.
Задавайте фиксированные координаты и разрешения
Фиксированные координаты подходят для проверки детерминированных условий: «внутри области», «пересечение границы» или «далеко от целевой точки». Сначала следует установить приложение, предварительно настроить разрешение и задать координаты, а уже затем запускать тестовую цель. Если изменить разрешение после запуска приложения, первый экран может уже сохранить состояние без доступа к геолокации.
BUNDLE_ID="com.example.LocationDemo"
xcrun simctl --set "$DEVICE_SET" privacy "$UDID" grant location "$BUNDLE_ID"
xcrun simctl --set "$DEVICE_SET" location "$UDID" set 1.290270,103.851959
xcodebuild test \
-workspace LocationDemo.xcworkspace \
-scheme LocationDemo \
-destination "platform=iOS Simulator,id=$UDID" \
-resultBundlePath "$PWD/TestResults/LocationTests.xcresult"
Для проверки границ недостаточно одной точки. Подготовьте как минимум три группы координат: внутри области, рядом с границей и за пределами области. Тестовые данные должны описывать ожидаемый результат, а не скрывать смысл за названиями вроде case1 и case2.
| Сценарий | Входные данные | Рекомендуемая проверка |
|---|---|---|
| Внутри области | Расстояние до центра значительно меньше порогового значения | Состояние стабильно остаётся «внутри области» |
| Рядом с границей | По одной точке с каждой стороны порогового значения | Правила сравнения и округления согласованы |
| За пределами области | Расстояние до центра значительно больше порогового значения | Действие для нахождения внутри области не запускается |
| Разрешение отключено | Отозвать разрешение на геолокацию | Отображается состояние с подсказкой, позволяющей восстановить доступ |
Если приложение кеширует последнее местоположение, перед каждым тестовым сценарием необходимо очищать данные приложения или отключать постоянный кеш с помощью параметров тестового запуска. Иначе старое значение может переопределить новые координаты.
Проверяйте последовательность перемещения с помощью GPX
Для непрерывного перемещения следует использовать короткие и понятные GPX-файлы. Оставляйте в маршруте только путевые точки, необходимые для ключевых изменений состояния, вместо копирования полного реального трека. Следующий файл описывает перемещение из-за пределов области внутрь неё:
<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="location-ci">
<wpt lat="1.320000" lon="103.820000">
<name>outside</name>
</wpt>
<wpt lat="1.290270" lon="103.851959">
<name>inside</name>
</wpt>
</gpx>
При выполнении маршрута проверки должны опираться на порядок событий, а не на время ожидания с точностью до секунды.
xcrun simctl --set "$DEVICE_SET" location "$UDID" start "$PWD/Fixtures/enter-region.gpx"
xcodebuild test \
-workspace LocationDemo.xcworkspace \
-scheme LocationRouteTests \
-destination "platform=iOS Simulator,id=$UDID"
xcrun simctl --set "$DEVICE_SET" location "$UDID" stop
Приложение может записывать обезличенную последовательность состояний, например outside → approaching → inside, добавляя к каждому изменению монотонно возрастающую отметку времени. Не сохраняйте полные координаты в долгосрочных журналах. Для анализа сбоя достаточно имени тестового сценария, ожидаемой области, фактического состояния и ограниченного числа знаков после запятой.
Очищайте состояние и сохраняйте данные о сбоях
Очистка не должна выполняться только при успешном завершении. Сразу после запуска скрипта зарегистрируйте обработчик выхода, который остановит маршрут, очистит местоположение и выключит устройство. Удалять ли набор устройств, следует решать по результату теста.
cleanup() {
xcrun simctl --set "$DEVICE_SET" location "$UDID" stop 2>/dev/null || true
xcrun simctl --set "$DEVICE_SET" location "$UDID" clear 2>/dev/null || true
xcrun simctl --set "$DEVICE_SET" shutdown "$UDID" 2>/dev/null || true
}
trap cleanup EXIT
При сбое следует архивировать xcresult, журналы приложения, использованный GPX-файл, идентификаторы устройства и среды выполнения, а также состояние разрешений до начала теста. Снимки экрана помогают при диагностике, но не заменяют структурированные проверки. Если одни и те же координаты многократно приводят к сбою, сначала убедитесь, что набор устройств действительно изолирован, Bundle ID указан правильно, а разрешение предоставлено до запуска приложения. Только после этого проверяйте вычисления бизнес-логики.
Стабильная сборочная линия для тестов геолокации в итоге должна обеспечивать понятные входные данные, одноразовое состояние симулятора, обязательную остановку маршрута и возможность модульно тестировать бизнес-логику отдельно от системной геолокации. Тогда при сбое команда увидит конкретное расхождение состояний, а не невоспроизводимое сообщение о том, что «геолокация иногда работает неточно».
Часто задаваемые вопросы
Может ли simctl полностью заменить проверку геолокации на реальном устройстве?
Нет. Он подходит для проверки логики и интерфейса, но фоновое пробуждение, реальный дрейф сигнала, энергопотребление и поведение датчиков нужно проверять на устройстве.
Почему тест проходит отдельно, но нестабилен в полной CI-последовательности?
Общий симулятор может сохранять прежние координаты, разрешения или активный GPX-маршрут. Выделяйте отдельный набор устройств на задачу и явно очищайте состояние.
Как разделить проверки с фиксированной точкой и GPX-маршрутом?
Фиксированная точка нужна для детерминированной проверки региона и границ. GPX подходит для последовательности перемещений, но тест не должен ожидать прибытие с точностью до секунды.
Перенесите проверенный рабочий процесс в облачный Mac, работающий онлайн 365 дней в году
Выберите BookaMac M4 или BookaMac M4 Pro под свои задачи и при оформлении заказа проверьте регион, срок аренды и дополнительные варианты хранилища.