> · 9 мин

Claude Code тестирует iOS-приложение — тапает кнопки, свайпит экраны, проверяет каждый элемент

Claude Code тестирует iOS-приложение — тапает кнопки, свайпит экраны, проверяет каждый элемент

Claude Code тестирует iOS-приложение — тапает кнопки, свайпит экраны, проверяет каждый элемент

Claude Code живёт в терминале. У него нет глаз, чтобы увидеть ваш UI, и нет рук, чтобы потыкать кнопки в симуляторе. Но три инструмента это исправляют — и превращают текстового агента в полноценного QA-инженера для iOS.

TL;DR: XcodeBuildMCP даёт Claude Code 76 инструментов для сборки и тестирования iOS-приложений. AXe CLI добавляет тапы, свайпы и чтение accessibility tree. Swift Testing Agent Skill учит писать качественные тесты. Вместе они замыкают цикл: собрать → запустить → протыкать каждый экран → проверить скриншот → починить → повторить.

Проблема: Claude Code слеп к вашему приложению

Когда вы просите Claude Code «протестируй UI», он может написать XCUITest-код. Но он не видит, что получилось. Не знает, билдится ли проект. Не может нажать кнопку в симуляторе и посмотреть, что произойдёт.

Чтобы замкнуть этот цикл, нужны три вещи:

  • Сборка и запуск — без открытия Xcode
  • Взаимодействие с симулятором — тапы, свайпы, ввод текста
  • Обратная связь — скриншоты, accessibility tree, логи консоли

Инструмент 1: XcodeBuildMCP — Xcode без Xcode

XcodeBuildMCP — MCP-сервер от Sentry (они недавно его купили, 4000+ звёзд на GitHub). Даёт Claude Code 76 инструментов: билд, тесты, управление симуляторами, деплой на устройства, LLDB-дебаг.

Установка:

brew tap getsentry/xcodebuildmcp
brew install xcodebuildmcp

Для UI-автоматизации понадобится ещё Facebook IDB:

brew tap facebook/fb
brew install idb-companion

Что умеет для тестирования:

  • mcp__xcodebuildmcp__build_sim_name_proj — собрать проект под симулятор
  • mcp__xcodebuildmcp__test_sim_name_proj — запустить юнит-тесты
  • mcp__xcodebuildmcp__build_run_sim_name_proj — собрать и запустить
  • simulator/screenshot — сделать скриншот текущего состояния
  • ui-automation/tap — тапнуть по элементу
  • ui-automation/swipe — свайпнуть
  • describe_ui — получить дерево всех UI-элементов

Тулы для UI-автоматизации пока в бета-версии, но уже рабочие. Claude видит accessibility tree, находит нужную кнопку, тапает — и делает скриншот, чтобы проверить результат.

Инструмент 2: AXe — тапы и свайпы через Accessibility API

AXe — CLI-утилита, которая управляет iOS-симулятором через Apple Accessibility API. Никаких серверов, просто бинарник.

Установка:

brew tap cameroncooke/axe
brew install axe

Интеграция с Claude Code как skill:

axe init --client claude

Это создаст skill-файл в ~/.claude/skills, и Claude Code сразу получит инструкции по использованию AXe.

Главная суперсила — describe-ui:

axe describe-ui --udid SIMULATOR_UDID

Возвращает полное дерево accessibility-элементов на экране в JSON. Claude читает его и понимает, что на экране: какие кнопки, поля ввода, лейблы, их accessibility identifier'ы.

Тапы — три способа:

# По accessibility ID (самый надёжный)
axe tap --id "loginButton" --udid $UDID

# По тексту label
axe tap --label "Войти" --udid $UDID

# По координатам (последний выбор)
axe tap -x 200 -y 400 --udid $UDID

Свайпы и жесты:

# Скролл вниз
axe gesture scroll-down --udid $UDID

# Свайп от левого края (назад в навигации)
axe gesture swipe-from-left-edge --udid $UDID

# Произвольный свайп
axe swipe --start-x 100 --start-y 300 --end-x 300 --end-y 100 --udid $UDID

Ввод текста:

axe type 'test@example.com' --udid $UDID

Скриншоты:

axe screenshot --output ~/Desktop/current-state.png --udid $UDID

Batch-режим — несколько действий за один вызов:

axe batch --udid $UDID \
  --step "tap --id SearchField" \
  --step "type 'hello world'" \
  --step "key 40"

Batch снижает latency — вместо трёх отдельных вызовов Claude делает один.

Инструмент 3: Swift Testing Agent Skill — пишем тесты правильно

Swift Testing Agent Skill от Antoine van der Lee (автора SwiftLee) — agent skill, который учит Claude Code писать тесты на Swift Testing framework вместо устаревшего XCTest.

Зачем нужен отдельный skill? Без него Claude Code допускает типичные ошибки: добавляет @MainActor без причины, ставит .serialized где не нужно, путает #expect и #require. Skill кодифицирует best practices из документации Apple и WWDC-сессий.

Что покрывает:

  • Миграция XCTest → Swift Testing — инкрементальный рефакторинг без поломки существующих тестов
  • Параллельное выполнение — тесты по умолчанию параллельные, skill учит не ломать это без причины
  • Параметризованные тесты — один тест, много входных данных
  • Traits и Tags — условное выполнение, фильтрация по тест-планам

Установка:

Клонируете репозиторий и копируете skill-файл в .claude/skills/ вашего проекта или в глобальные ~/.claude/skills/.

Полный цикл: как Claude Code тестирует каждый экран

Вот как выглядит реальный workflow, когда все три инструмента подключены.

Шаг 1 — Сборка и запуск:

Claude вызывает XcodeBuildMCP для сборки. Если есть ошибки компиляции — видит их сразу и фиксит.

xcodebuild -project MyApp.xcodeproj -scheme "MyApp" \
  -destination "platform=iphonesimulator,id=$UDID" \
  -derivedDataPath DerivedData build 2>&1 | head -50

Шаг 2 — Запуск в симуляторе:

xcrun simctl install $UDID "DerivedData/Build/Products/Debug-iphonesimulator/MyApp.app"
xcrun simctl launch $UDID com.myapp.bundle

Шаг 3 — Считываем accessibility tree:

axe describe-ui --udid $UDID

Claude получает JSON со всеми элементами на экране. Видит кнопки, поля, навигацию.

Шаг 4 — Обходим экраны:

Claude читает accessibility tree, тапает по каждому навигационному элементу, делает скриншот, анализирует:

axe tap --label "Профиль" --udid $UDID
axe screenshot --output /tmp/profile-screen.png --udid $UDID

Шаг 5 — Заполняем формы:

axe tap --id "emailField" --udid $UDID
axe type 'test@example.com' --udid $UDID
axe tap --id "submitButton" --udid $UDID
axe screenshot --output /tmp/after-submit.png --udid $UDID

Шаг 6 — Проверяем результат:

Claude анализирует скриншот мультимодально. Видит, что форма отправилась, или что появилась ошибка валидации. Может сравнить с предыдущим скриншотом через ImageMagick:

magick compare -metric RMSE before.png after.png null:

Шаг 7 — Пишем тесты на то, что проверили:

На основе ручного прохода Claude генерирует XCUITest или Swift Testing код, который автоматизирует эту проверку навсегда.

Настройка CLAUDE.md для iOS-тестирования

Чтобы Claude Code не тратил токены на переоткрытие одного и того же, пропишите в CLAUDE.md:

# iOS Project

- **Scheme:** MyApp
- **Simulator UDID:** `XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX`
- **Bundle ID:** com.myapp.bundle
- **App binary:** DerivedData/Build/Products/Debug-iphonesimulator/MyApp.app

## Testing rules
- Always use XcodeBuildMCP tools, never raw xcodebuild
- For UI interaction use AXe CLI with --udid flag
- After each tap/swipe, take a screenshot to verify result
- Prefer accessibility ID over coordinates for taps
- Run `axe describe-ui` before interacting with new screen

Кешируйте UDID симулятора — Claude не будет каждый раз искать его через xcrun simctl list.

Deep links: навигация без тапов

Если ваше приложение поддерживает deep links, Claude может прыгать на нужный экран напрямую:

xcrun simctl openurl $UDID "myapp://settings/notifications"

Это экономит 3-5 тапов на каждый переход и делает тестирование конкретного экрана быстрым.

Snapshot-тестирование: Claude видит то, что рисует

Для SwiftUI-вью есть отдельный подход через Swift Snapshot Testing. Claude рендерит вью в изолированном тесте, получает PNG, анализирует визуально и итерирует.

import SnapshotTesting
import SwiftUI
@testable import MyApp
import Testing

@Suite("ViewVerificationTests")
@MainActor
struct ViewVerificationTests {
    @Test("Verify ProfileView")
    func profileView() {
        let view = ProfileView(user: .mock)
        assertSnapshot(
            of: view,
            as: .image(layout: .fixed(width: 390, height: 844)),
            record: true
        )
    }
}

Claude запускает тест, читает сгенерированный PNG, сравнивает с референсом. По опыту Christopher Ney из twocentstudios, больше 3 итераций до вмешательства человека делать не стоит — Claude пока плохо чувствует отступы и цвета на уровне пикселей.

Подводные камни

idb_companion конфликтует с Xcode. После обновления Xcode Facebook IDB может сломаться. Лечение — brew reinstall idb-companion. Иногда нужно полностью удалить и поставить заново.

describe-ui не видит кастомные компоненты без accessibility. Если вы не проставили accessibilityIdentifier и accessibilityLabel на своих вью, AXe вернёт пустое дерево или generic-описания. Claude не поймёт, куда тапать. Совет: перед тестированием пройдитесь по ключевым элементам и добавьте .accessibilityIdentifier("loginButton").

Скриншоты симулятора идут в 3x scale. Координаты на скриншоте не совпадают с координатами тапа. Если Claude тапает по координатам со скриншота — промахнётся. Решение из блога twocentstudios: ресайзить скриншот до 1x через magick screenshot.png -resize 33.333% screenshot_1x.png или использовать accessibility ID вместо координат.

UI-автоматизация XcodeBuildMCP в бета. Тулы ui-automation/tap и ui-automation/swipe работают, но могут меняться между версиями. AXe стабильнее для продакшен-использования — у него собственный skill и подробная документация.

Claude бросает неудачные тесты. По наблюдениям из сообщества, если XCUITest падает, Claude иногда удаляет его и пишет новый вместо того, чтобы починить. Пропишите в CLAUDE.md: "Never delete failing tests — fix them."

Snapshot testing не даёт pixel-perfect результат. Claude плохо различает отступы в 8pt и 12pt на скриншоте. Для проверки layout лучше подходит accessibility tree (элемент есть / элемента нет), а snapshot — для общего визуального контроля.

Вердикт

Из трёх инструментов самую большую отдачу даёт связка AXe + describe-ui. Она позволяет Claude Code обойти все экраны приложения, тапнуть по каждому элементу и проверить результат — без единой строчки тестового кода. XcodeBuildMCP нужен для сборки и запуска в симуляторе (без него не обойтись), а Swift Testing Agent Skill окупается, когда вы хотите генерировать тесты, а не просто проводить ручной прогон.

Реалистичные ожидания: Claude Code сможет автоматически пройти по 5-10 экранам, найти очевидные проблемы (сломанная навигация, пустой экран, краш), но не заменит опытного QA с пониманием бизнес-логики. Лучший паттерн — Claude проходит smoke test, вы проверяете edge cases.

Как попробовать

  1. Установите XcodeBuildMCP и AXe:
brew tap getsentry/xcodebuildmcp && brew install xcodebuildmcp
brew tap facebook/fb && brew install idb-companion
brew tap cameroncooke/axe && brew install axe
  1. Подключите AXe skill к Claude Code:
axe init --client claude
  1. Добавьте UDID симулятора в CLAUDE.md (получите через xcrun simctl list devices | grep Booted)

  2. Попросите Claude Code протестировать:

Собери проект, запусти в симуляторе, пройди по всем табам,
на каждом экране сделай describe-ui и скриншот.
Если видишь кнопки — тапни и проверь, что происходит.
  1. Для генерации тестов добавьте Swift Testing Agent Skill в .claude/skills/ и попросите: "Напиши Swift Testing тесты для каждого экрана, который ты проверил."
$ ls ./related/

Похожие статьи

subscribe.sh

$ cat /dev/blog/updates

> Свежие заметки о программировании,

> DevOps и AI — прямо в мессенджер

./subscribe