Testowanie aplikacji mobilnych z agentami AI
Testowanie aplikacji mobilnych z agentami AI działa, gdy agent steruje prawdziwym symulatorem lub emulatorem, a nie tylko czyta kod źródłowy. Typowy układ to Maestro MCP jako dostęp do urządzenia, flow Maestro lub testy Detox oparte na stabilnych identyfikatorach dostępności oraz zasada, że test przyjmuje się dopiero, gdy zawiedzie na celowo zepsutym buildzie; mała macierz urządzeń jest bramką każdego pull requesta.
Twoja aplikacja React Native działa na iPhonie, który leży na biurku. Potem przychodzą raporty o crashach: starszy telefon z Androidem od producenta z własną nakładką systemową, mały iPhone, na którym przycisk płatności chowa się pod klawiaturą, i układ tabletowy z nachodzącymi na siebie etykietami. Miesiąc temu poprosiłeś agenta o „testy E2E” i dostałeś 40 zielonych testów. Żaden niczego z tego nie wyłapał. Ta strona jest dla programisty, który odpowiada za aplikację w React Native, Flutterze albo natywną, oraz dla tech leada, który decyduje, co uruchamia się przy każdym pull requeście.
Co znajdziesz w tym przewodniku
Dział zatytułowany „Co znajdziesz w tym przewodniku”- Tabelę decyzyjną: który framework ma pisać agent — Maestro, Detox, Flutter
integration_testlub Patrol, czy natywne XCUITest i Espresso - Maestro MCP i MobileBuildMCP skonfigurowane w Claude Code, Codeksie lub Cursorze, tak aby agent sprawdzał swoją pracę na urządzeniu
- Pięć promptów do skopiowania: smoke flow Maestro, zestaw Detox z uprawnieniami, audyt kontroli negatywnej, macierz urządzeń i testy offline
- Procedurę weryfikacji, która dowodzi, że wygenerowany test łapie błędy, bez czytania każdej jego linii
- Warstwową macierz urządzeń i polecenia CI, które ją uruchamiają
Który framework testów mobilnych powinien pisać agent?
Dział zatytułowany „Który framework testów mobilnych powinien pisać agent?”Wybierz framework, zanim napiszesz prompt. Agent poproszony o „testy mobilne” wybierze za ciebie — zwykle najbardziej znany framework, a nie ten, który pasuje do twojej aplikacji.
| Framework | Najlepszy do | Co pisze agent | Ograniczenia (sprawdzone 2026-09-26) |
|---|---|---|---|
| Maestro 2.11.0 | Smoke i regresja na dowolnym stosie: React Native, Flutter, natywne, hybrydowe | Płaski YAML (tapOn, assertVisible), czytelny dla QA i recenzentów | Brak obsługi fizycznych urządzeń iOS; setAirplaneMode działa tylko na Androidzie |
| Detox 20.51.4 (npm) | Aplikacje React Native, które potrzebują kontroli na poziomie kodu i synchronizacji z bezczynnością aplikacji | TypeScript na Jest | Tylko React Native; uprawnienia w launchApp tylko na iOS |
Flutter integration_test / Patrol 4.10.0 (pub.dev) | Aplikacje Flutter; Patrol dokłada natywne dialogi i systemowy UI | Dart | Sam integration_test nie kliknie natywnego dialogu uprawnień |
| XCUITest / Espresso | Aplikacje natywne i przebiegi na prawdziwych urządzeniach w farmach urządzeń | Swift / Kotlin | Dwa zestawy do utrzymania; najwolniejsza iteracja dla agenta |
Dla większości zespołów cross-platformowych odpowiedź brzmi: Maestro na zestaw smoke plus jeden framework na poziomie kodu dla ścieżek krytycznych. Przepływy w YAML są na tyle krótkie, że recenzent w minutę oceni, co weryfikują ich asercje — a gdy testy pisze agent, to ważniejsze niż jakakolwiek funkcja frameworka. Konfiguracja buildów dla konkretnych stosów jest w cookbooku: React Native, Flutter, Expo oraz natywne iOS i Android.
Daj agentowi urządzenie, a nie tylko kod źródłowy
Dział zatytułowany „Daj agentowi urządzenie, a nie tylko kod źródłowy”Agent, który czyta wyłącznie pliki nawigacji, zgaduje selektory, czasy oczekiwania i zawartość ekranu. Agent z urządzeniem może spojrzeć na ekran. Większość pracy wykonują dwa serwery MCP:
- Maestro MCP jest wbudowany w CLI Maestro (
maestro mcp, nic więcej nie trzeba instalować). Agent podgląda ekran, stuka, przewija i sprawdza asercje na emulatorze, symulatorze albo fizycznym urządzeniu z Androidem, a potem zapisuje kroki jako flow YAML. Maestro 2.5.0 usunął osiem zbędnych narzędzi i połączył narzędzia uruchamiania w jedno, więc lista narzędzi serwera pozostaje krótka (sprawdzone w Maestro 2.11.0). - MobileBuildMCP (dawniej XcodeBuildMCP, własność Sentry, npm
mobilebuildmcp2.7.1) buduje aplikacje na iOS i macOS, uruchamia symulatory i uruchamia testy XCTest. Wymaga macOS 14.5+ i Xcode 16+.
Najpierw zainstaluj Maestro (wymaga Javy 17 lub nowszej), a potem zarejestruj serwery:
curl -fsSL "https://get.maestro.mobile.dev" | bashclaude mcp add maestro -- maestro mcpclaude mcp add mobilebuild -- npx -y mobilebuildmcp@latest mcp # tylko macOSDodaj -s project, aby wpis trafił do .mcp.json i był dostępny dla całego zespołu.
codex mcp add maestro -- maestro mcpcodex mcp add mobilebuild -- npx -y mobilebuildmcp@latest mcp # tylko macOSDodaj oba serwery do .cursor/mcp.json w projekcie (albo do ~/.cursor/mcp.json, aby działały we wszystkich projektach). MobileBuildMCP działa tylko na macOS.
{ "mcpServers": { "maestro": { "command": "maestro", "args": ["mcp"] }, "mobilebuild": { "command": "npx", "args": ["-y", "mobilebuildmcp@latest", "mcp"] } }}Oba polecenia używają udokumentowanych poleceń startowych serwerów (maestro mcp, npx -y mobilebuildmcp@latest mcp). Po dodaniu uruchom /mcp w Claude Code albo codex mcp list, aby potwierdzić połączenie. Pełny katalog serwerów znajdziesz w artykule o serwerach MCP dla środowisk deweloperskich.
Przepływ pracy: eksploracja na urządzeniu, test, dowód, że test umie zawieść
Dział zatytułowany „Przepływ pracy: eksploracja na urządzeniu, test, dowód, że test umie zawieść”-
Najpierw dodaj stabilne selektory. Poproś agenta o
testID(React Native), identyfikatoryKeylubSemantics(Flutter) alboaccessibilityIdentifier/testTag(natywne) na każdym elemencie, którego dotyka flow. Testy dopasowujące widoczny tekst psują się przy pierwszej zmianie tekstów interfejsu albo tłumaczenia. -
Pozwól agentowi przejść flow na uruchomionym urządzeniu. Z podłączonym Maestro MCP agent przechodzi przez prawdziwą aplikację i notuje, co widzi. To zastępuje zgadywanie na podstawie
src/navigation/. -
Niech napisze test i uruchamia go, aż będzie zielony. Flow lub spec trafia do repozytorium, więc staje się deterministycznym testem w CI, a nie jednorazową sesją agenta.
-
Zepsuj aplikację i patrz, jak test zawodzi. To kontrola negatywna. Test, który pozostaje zielony po usunięciu przycisku, na którym robi asercję, niczego nie chroni. Pełną metodę opisuje artykuł jak silna jest twoja wyrocznia.
-
Podłącz zestaw do bramki pull requestów na jednym symulatorze iOS i jednym emulatorze Androida, z zapisem artefaktów przy błędach.
Pierwszy prompt obejmuje kroki od 1 do 3 dla smoke flow.
Dla przepływów React Native, które wymagają obsługi uprawnień i precyzyjnej synchronizacji, lepszy jest Detox. Jego device.launchApp({ permissions }) nadaje lub odbiera uprawnienia przed startem aplikacji, ale tylko na iOS, dlatego prompt osobno opisuje ścieżkę dla Androida.
Gdzie każde narzędzie uruchamia pętlę na urządzeniu
Dział zatytułowany „Gdzie każde narzędzie uruchamia pętlę na urządzeniu”Pętla na urządzeniu wymaga maszyny z symulatorami: symulatory iOS działają tylko na macOS z Xcode, a emulatory Androida potrzebują akceleracji sprzętowej. To przesądza, gdzie każdy agent wykonuje pracę.
Iteruj interaktywnie na Macu z podłączonym Maestro MCP. W CI zostaw uruchomienie testów deterministyczne i uruchamiaj agenta tylko do diagnozy błędu, z wąską listą dozwolonych narzędzi. claude -p startuje w trybie Manual i nie może pytać o zgodę, więc każde narzędzie spoza --allowedTools zostaje odrzucone:
claude -p "Read build/maestro/report.xml and the screenshots in build/maestro/. \Explain why each failed flow failed and propose the smallest fix. Do not edit files." \ --allowedTools "Read" "Glob" "Bash(maestro test *)" --output-format jsonIteruj w CLI albo rozszerzeniu IDE na maszynie z uruchomionym urządzeniem. Do nieinteraktywnej próby naprawy użyj codex exec z sandboksem workspace-write. Workspace-write domyślnie blokuje dostęp do sieci, co może odciąć agenta od adb lub symulatora. Zezwól na niego w tym uruchomieniu flagą -c sandbox_workspace_write.network_access=true albo uruchom krok na urządzeniu poza agentem i przekaż mu raport JUnit:
codex exec --sandbox workspace-write \ "Read build/maestro/report.xml, fix the failing Maestro flows under .maestro/, and list what you changed."Zadania w Codex cloud nadają się do pisania selektorów i flow na podstawie kodu, ale zanim poprosisz zadanie w chmurze o uruchomienie zestawu, sprawdź, czy twoje środowisko chmurowe w ogóle udostępnia symulator.
Uruchamiaj agenta lokalnie w edytorze z podłączonym Maestro MCP i otwartym obok symulatorem, żeby widzieć każde stuknięcie na bieżąco. Cloud Agents działają na zdalnych maszynach wirtualnych; używaj ich do pisania selektorów i flow, a przebiegi na urządzeniach zostaw swojemu Macowi lub runnerowi CI, chyba że środowisko Cloud Agenta ma skonfigurowany emulator.
Samo zadanie CI uruchamia Maestro bezpośrednio, z tagami i raportem:
# CI: bramka smoke dla pull requestówmaestro test --include-tags smoke --format junit --output build/maestro/report.xml \ --test-output-dir build/maestro .maestro/W Detoksie detox test -c android.emu.release --take-screenshots failing --record-videos failing zapisuje dowody tylko dla nieudanych testów. W bramce nie włączaj --retries: ponowienie ukrywa niestabilność, którą chcesz mierzyć.
Skąd wiesz, że testy mobilne napisane przez agenta łapią błędy?
Dział zatytułowany „Skąd wiesz, że testy mobilne napisane przez agenta łapią błędy?”Zielony przebieg dowodzi tylko, że test i aplikacja się zgadzają. Nie dowodzi, że test zauważy regresję. Zamiast czytać każdą asercję, sprawdź cztery rzeczy:
| Kontrola | Jak | Zaliczona, gdy |
|---|---|---|
| Kontrola negatywna | Zepsuj zachowanie, które test rzekomo pokrywa (ukryj przycisk, zwróć błąd z mocka API), i uruchom ponownie | Każdy test ze zmiany robi się czerwony z właściwego powodu |
| Higiena selektorów | grep po nowych flow i specach w poszukiwaniu selektorów tekstowych, stałych opóźnień i disableSynchronization | Żadnego wystąpienia bez komentarza z uzasadnieniem |
| Wskaźnik niestabilności | Uruchom nowy zestaw 10 razy na tym samym urządzeniu bez ponowień | 10 na 10 przechodzi; każdy gorszy wynik trafia do kwarantanny, nie do bramki |
| Dowody | Zrzuty ekranu i nagrania przy błędach, raport JUnit w PR | Recenzent widzi, co działo się na urządzeniu, bez ponownego uruchamiania |
Kto zatwierdza. Programista dołącza do pull requesta tabelę kontroli negatywnej i raport JUnit. Tech lead jest właścicielem dwóch list, których agent nie może zmieniać samodzielnie: tagów smoke blokujących merge i macierzy urządzeń. Umieść .maestro/, e2e/ i workflow CI w CODEOWNERS, żeby zmieniony lub usunięty test wymagał akceptacji człowieka; hooki i reguły, które to egzekwują, opisuje artykuł o ochronie wyroczni.
Na ilu urządzeniach trzeba testować?
Dział zatytułowany „Na ilu urządzeniach trzeba testować?”Nie przetestujesz na każdym urządzeniu, a każde kolejne urządzenie wydłuża przebieg szybciej, niż zwiększa pokrycie. Podziel macierz na warstwy według częstotliwości uruchamiania:
| Warstwa | Kiedy | Urządzenia | Cel |
|---|---|---|---|
| Bramka PR | Każdy pull request | 1 symulator iOS (aktualny iOS), 1 emulator Androida (najniższy wspierany poziom API) | Tylko flow smoke; minuty, nie godziny |
| Nocna | Raz dziennie | 3 do 6 symulatorów i emulatorów: najmniejszy i największy ekran, tablet, najstarszy wspierany system | Pełna regresja, układy, orientacja |
| Przed wydaniem | Przed każdym zgłoszeniem do sklepu | Prawdziwe urządzenia w farmie urządzeń (BrowserStack, AWS Device Farm), najczęstsi producenci z twojej analityki | Dialogi nakładek producentów, wydajność, prawdziwe iPhone’y |
Prawdziwe iPhone’y są potrzebne w ostatniej warstwie, bo Maestro 2.11.0 nie działa na fizycznych urządzeniach iOS; na farmie urządzeń użyj do nich XCUITest lub Appium (npm appium 3.8.0).
Jak testować tryb offline i wolną sieć?
Dział zatytułowany „Jak testować tryb offline i wolną sieć?”Żaden z frameworków nie ma jednego przełącznika warunków sieciowych działającego na obu platformach, więc steruj łącznością spoza testu:
- Tryb samolotowy na Androidzie: polecenia Maestro
setAirplaneModeitoggleAirplaneModedziałają tylko na Androidzie ze względu na ograniczenia symulatora iOS.adb shell svc wifi disableiadb shell svc data disablerobią to samo ze skryptu. - Zablokowane lub nieudane żądania: skieruj aplikację na serwer mockujący i wstrzykuj tam opóźnienia oraz odpowiedzi 5xx.
device.setURLBlacklist([...])w Detoksie sprawia, że test nie czeka na adresy analityki lub pollingu, które nigdy nie przechodzą w stan bezczynności. - Symulowany offline na iOS: przekaż argument startowy (
launchArgs: { offlineMode: true }w Detoksie albo zmienną środowiskową we flow Maestro), który aplikacja odczytuje, by udawać brak sieci — tylko w buildach debug.
Gesty, orientacja i układ działają według tego samego wzorca: Maestro ma swipe i setOrientation, Detox ma device.setOrientation(), swipe() na elementach i dostępne tylko na iOS pinch(). Dla regresji układu, których asercje dobrze nie opiszą, porównuj zrzuty ekranu i użyj kontroli ocenianej przez model z rubryką zamiast porównywania pikseli. Etykiety dostępności, VoiceOver i TalkBack opisuje artykuł o testach dostępności.
Kiedy testy mobilne pisane przez agenta zawodzą
Dział zatytułowany „Kiedy testy mobilne pisane przez agenta zawodzą”Testy przechodzą na symulatorze, a padają na prawdziwych urządzeniach. Symulatory nie odtwarzają dialogów uprawnień z nakładek producentów, prawdziwych klawiatur ani ubijania aplikacji przy braku pamięci. Wyjście: przenieś te flow do warstwy przed wydaniem na farmie urządzeń i dodaj dialog producenta jako krok opcjonalny (optional: true w Maestro), a nie twardą asercję.
Agent „naprawił” nieudany test, osłabiając go. Typowe objawy to usunięte assertVisible, selektor tekstowy zamieniony na stuknięcie we współrzędne albo dodane w Detoksie disableSynchronization(). Wyjście: odrzuć zmianę, uruchom na tym teście prompt kontroli negatywnej i dodaj katalog testów do CODEOWNERS, żeby kolejne osłabienie wymagało akceptacji.
Flow są niestabilne przez animacje. Wyłącz animacje w procesie aplikacji, nie w teście: plik konfiguracji przestrzeni roboczej Maestro (config.yaml) obsługuje disableAnimations dla Androida i iOS, a na emulatorach Androida możesz ustawić trzy skale animacji na 0. Jeśli test nadal jest niestabilny: odłóż go do kwarantanny tagiem wykluczającym i poproś agenta o znalezienie zapętlonej animacji lub timera, przez które aplikacja nie przechodzi w stan bezczynności.
Agent nie widzi urządzenia. maestro mcp nie wystartuje bez Javy 17, a MobileBuildMCP wymaga macOS 14.5+ z Xcode 16+. Wyjście: uruchom ręcznie maestro test na jednym flow, żeby potwierdzić połączenie z urządzeniem, a potem sprawdź stan serwera przez /mcp w Claude Code albo codex mcp list.
Bramka PR jest za wolna. Zestawy mobilne działają wolniej niż webowe, a wolna bramka bywa pomijana. Wyjście: ogranicz bramkę do flow z tagiem smoke (celuj w trzy do pięciu ścieżek krytycznych), resztę przenieś do przebiegu nocnego i zrównoleglij go przez --shard-split w Maestro albo farmę urządzeń.