Это гостевой пост от Оскара Квасьневского (Oskar Kwaśniewski), технического директора и соучредителя TesterArmy, где агенты тестируют мобильные приложения, веб-приложения и сайты так же, как реальные пользователи.
Используйте возможности рабочих процессов EAS, чтобы за считанные минуты собрать и запустить агентские тесты для вашего Expo-приложения с помощью TesterArmy.
На прошлой неделе Expo показала, что происходит, когда агент помещается внутрь EAS Workflows: проблема на GitHub с меткой «repro» превращается в пулл-реквест с исправлением и видеозаписями, доказывающими его работоспособность. Это половина истории, касающаяся исправления. Этот пост посвящен второй половине — пулл-реквесту, который еще не объединен, и тому, что я начал называть агентным CI: конвейеру, который решает, что собирать и что тестировать для каждого изменения, вместо того чтобы запускать один и тот же список каждый раз.
Когда я общаюсь с разработчиками об их процессе разработки, я часто слышу, что проблема смещается с написания кода на его фактическое рецензирование и нажатие кнопки слияния. Агенты могут создавать тонны пулл-реквестов, но они по-прежнему упираются в узкие места процесса ревью и неуверенность в том, что PR можно объединять.
Пулл-реквесты простаивают в очереди, потому что ни у кого нет времени сидеть, открывать приложение и кликать по измененному экрану… В итоге изменение объединяется, а первым пользователем, который нажимает на него, оказывается реальный пользователь.
Решение заключается в использовании того, что мы называем «агентным CI»: представьте себе агента, который при каждом пулл-реквесте анализирует описание и дифф для глубокого понимания изменений, а затем открывает приложение и кликает по измененному месту так, как это сделал бы реальный пользователь, оставляя вам видеозапись того, как оно работает и что оно делает с приложением.
Что здесь означает агентный CI
CI всегда был фиксированным списком. Каждый пулл-реквест запускает одни и те же задачи в одном и том же порядке, будь то переименование переменной или переписывание экранов приветствия. Агентный CI означает, что список адаптируется под каждый пулл-реквест. EAS Workflows собирает приложение и повторно использует последнюю нативную сборку, если изменился только JavaScript. Агент TesterArmy читает пулл-реквест и решает, на что нужно нажать в симуляторе.
В настоящее время TesterArmy работает в облачных симуляторах iOS и эмуляторах Android, а не на физических устройствах (хотя мы работаем над добавлением поддержки реальных устройств). Вы можете использовать нашего агента вместе с вашими существующими e2e-тестами и фреймворками.
Часть первая: агент пишет рабочий процесс
На странице документации TesterArmy для Expo EAS есть раздел «Инструкции для ИИ-агентов». Это промпт. Вставьте его в используемый вами в репозитории агент кодинга — Claude Code, Codex или Cursor — и он выполнит настройку за вас: изучит eas.json и .eas/workflows, добавит два профиля сборки, запишет новый файл рабочего процесса, не затрагивая существующий, и никогда не закоммитит секретные данные.
Эти два профиля — все требования со стороны Expo. TesterArmy требует .app для симулятора iOS, а не .ipa, и единственный .apk для Android, а не .aab.
Рабочий процесс считывает три значения из вашего окружения EAS: TESTERARMY_API_KEY, TESTERARMY_PROJECT_ID и TESTERARMY_GROUP_ID. Сохраняйте ключ API в качестве секрета EAS, но никогда — в виде переменной EXPO_PUBLIC. Четвертая переменная, TESTERARMY_DYNAMIC_AGENT_ENABLED, является необязательной и по умолчанию имеет значение true.
Перед запуском вам понадобится мобильный проект в TesterArmy хотя бы с одним сохраненным тестом. Запустите этот тест один раз из панели управления на загруженной сборке, чтобы убедиться, что выгрузка и сценарий работают до того, как от них станет зависеть CI. Вы можете получить дополнительную информацию об этом в docs.
Часть вторая: EAS собирает приложение и повторно использует все, что может
Базовый рабочий процесс срабатывает при пуше в ветку main, пулл-реквестах в main и при вызове workflow_dispatch. Он собирает приложение для симулятора iOS и APK для Android, скачивает каждый артефакт с помощью eas/download_build, выгружает его в TesterArmy и запускает вашу сохраненную группу тестов один раз для каждой платформы. Начните с этого. Полноценная нативная сборка при каждом запуске работает медленнее, но она исключает лишние переменные, пока вы все настраиваете.
Как только все станет стабильным, позвольте EAS пропускать нативную сборку, когда это возможно. Задача fingerprint в Expo вычисляет хэш нативной среды выполнения. Задача get-build ищет существующую сборку с этим хэшем. Задача repack переупаковывает метаданные приложения и JavaScript-бандл поверх нее без полной нативной пересборки. Если подходящая сборка не найдена, рабочий процесс переключается на обычную сборку.
Аналогичным образом для Android используется профиль APK. Задача upload запускается после того, как repack или build генерирует build_id. Одно предостережение из собственной документации Expo: задача fingerprint предназначена для проектов CNG. Если вы коммитите свои директории android или ios, это работать не будет, поэтому оставайтесь на базовом рабочем процессе.
Это та часть, которая сокращает цикл обратной связи. Нативная сборка — это медленный шаг в любом рабочем процессе EAS, а большинство пулл-реквестов для зрелого приложения на Expo затрагивают только JavaScript. Благодаря repack нативная сборка происходит один раз за изменение среды выполнения, а любой другой пулл-реквест идет прямо от repack к выгрузке и тестированию.
Часть третья: агент тестирует то, что изменилось
Запуск регрессионных тестов для каждого PR гарантирует, что вы не сломали ничего из того, что работало раньше. Новая часть — это задача, которая запускается только для пулл-реквестов на основе той же выгруженной сборки и самостоятельно разрабатывает план тестирования.
Она глубоко понимает суть изменений в пулл-реквесте, читая файлы и диффы. На основе этого она пишет упорядоченный список шагов на естественном языке для данного изменения, запускает их в симуляторе и публикует проверку GitHub и комментарий к пулл-реквесту. В комментарии сначала отображаются запланированные шаги в виде таблицы, а затем они обновляются результатами по каждому шагу в реальном времени. Кждому запуску прилагается видео.
Перед включением этой функции полезно знать о двух нюансах.
Во-первых, судья пропуска (skip judge) считывает диффы до запуска чего-либо. Если пулл-реквест не меняет ничего видимого для пользователя (например, правка документации или обновление конфига), запуск отмечается как пропущенный, проверка показывает «Tests skipped» с указанием причины, а задача завершается успешно. На мобильных устройствах решение принимается для каждой платформы отдельно, поэтому изменение, касающееся только iOS, все равно будет протестировано на iOS, в то время как запуск для Android будет пропущен. Как только судья принимает решение тестировать, запуск выполняется в обязательном порядке.
Во-вторых, реальная ошибка приводит к сбою задачи EAS, но проверка GitHub по умолчанию носит рекомендательный характер. Завершившиеся сбоем тесты получают нейтральный статус, а GitHub считает нейтральный статус успешным. Если вы хотите, чтобы неудачный тест блокировал слияние, включите опцию «Block merges on failed tests» на вкладке PR Testing проекта и отметьте проверку «TesterArmy / Exploration Test» как обязательную в настройках защиты ветки.
Замкните цикл с помощью вашего агента кодинга
Если Claude Code, Cursor или Codex пишут ваши пулл-реквесты, вы можете сделать так, чтобы каждый из них был готов к планированию. Добавьте выдержку из документации в AGENTS.md или CLAUDE.md один раз. С этого момента описание каждого пулл-реквеста будет заканчиваться разделом инструкций по тестированию, который агент сможет выполнить.
Вот и весь цикл. Агент кодинга пишет изменения и инструкции. EAS собирает или переупаковывает приложение. Агент тестирования планирует работу на основе инструкций и диффа, кликает по приложению и оставляет видео в пулл-реквесте. Нет необходимости писать тестовый скрипт.
Вот как это выглядит при пятидесяти пулл-реквестах в день
Juno создает помощник по здоровью для людей с хроническими заболеваниями на iOS и андроид с использованием React Native и Expo. Команда состоит из семи человек и выпускает один-два обновления в неделю, что с их стороны означает от пятидесяти до ста пулл-реквестов в день.
Каждый пулл-реквест проходит около шести запусков TesterArmy продолжительностью примерно по пять минут на обеих платформах, охватывая онбординг, ведение дневника симптомов, прием лекарств, уведомления, пейвол и сценарии работы с аккаунтом. Сценарии написаны в виде пользовательских путей на обычном языке, а не с использованием селекторов. В июле 2026 года команда объединила 501 пулл-реквест. В августе они объединили 791. Маршалл Гулд, соучредитель и генеральный директор Juno, формулирует это более прямолинейно, чем сделал бы я: «Мы выпускаем ПР в десять раз быстрее».
С чего начать
Начните с репозитория-примера. В нем есть файл рабочего процесса, оба профиля и задание динамического агента, и он работает как есть. Когда сохраненный тест проходит успешно на панели управления, включите динамический агент, затем добавьте создание отпечатка (fingerprint) и перепаковку. Все остальное, включая промпт агента и раздел устранения неполадок, находится в документации Expo EAS.
Если в вашем приложении возникнут трудности, откройте тикет в репозитории-примере и расскажите нам, где именно.











