Automação

Testes mobile com Appium: o que muda quando o alvo é um app

Quem vem da automação web costuma achar que testar um app é "Selenium com tela menor". Não é. O alvo deixa de ser um DOM num navegador e passa a ser uma árvore de elementos nativos rodando num sistema operacional que controla permissões, ciclo de vida e rede — em centenas de aparelhos diferentes. O Appium é a ponte para esse mundo, e entender o que ele faz por baixo evita a maior parte da frustração de quem está começando.

Por que app é um alvo diferente

Num teste web você tem um padrão (HTML/DOM) e basicamente dois ou três motores de renderização. No mobile, cada plataforma tem sua própria árvore de UI: no Android são Views expostas pelo UiAutomator; no iOS são elementos XCUIElement do XCUITest. São APIs de automação diferentes, mantidas por Google e Apple, com vocabulários próprios. Some a isso permissões em tempo de execução, o app indo para segundo plano, rotação de tela, teclado virtual cobrindo campos e redes que caem — situações que no navegador raramente importam e no celular são o dia a dia.

Como o Appium funciona por baixo

O Appium é um servidor que fala o protocolo WebDriver (o mesmo do Selenium). Seu teste envia comandos HTTP padronizados ("encontre esse elemento", "toque aqui") e o Appium os traduz para o framework nativo da plataforma via um driver: UiAutomator2 no Android, XCUITest no iOS. É isso que dá o grande trunfo — você escreve o teste quase igual para as duas plataformas, em qualquer linguagem com client WebDriver (Java, JavaScript, Python).

  Seu teste (Java/JS/Python)
        │  comandos WebDriver (HTTP/JSON)
        ▼
  ┌──────────────┐
  │ Appium Server│  ── traduz ──▶  driver da plataforma
  └──────────────┘
        │                              │
   UiAutomator2 (Android)        XCUITest (iOS)
        │                              │
        ▼                              ▼
     App no device / emulador / simulador

Essa tradução tem um custo: cada comando dá uma volta pela rede até o device. Por isso testes Appium são mais lentos que testes web — e por isso vale manter a suíte E2E mobile enxuta, empurrando o máximo de cobertura para níveis mais baratos, exatamente como prega a pirâmide de testes.

Encontrar elementos: nada de CSS

O maior choque para quem vem da web: não existe seletor CSS. Você localiza por atributos de acessibilidade e por estratégias específicas da plataforma. A regra de ouro é a mesma do bom design de locators — prefira identificadores estáveis a posição ou texto visível.

EstratégiaQuando usar
accessibility idPrimeira escolha: estável e multiplataforma (mapeia contentDescription no Android e accessibilityIdentifier no iOS)
id (resource-id)Bom no Android; não existe igual no iOS
XPathÚltimo recurso: frágil e lento, varre a árvore inteira
Peça ao time de dev um accessibility id em cada elemento testável. Além de tornar a automação estável, é o mesmo atributo que o leitor de tela usa — você ganha testabilidade e acessibilidade no mesmo commit.

Gestos, esperas e o que só existe no mobile

Tocar não é clicar. Apps vivem de gestos — swipe, scroll até um elemento, long press, pinch — que no Appium são expressos por ações de ponteiro (W3C Actions), não por um simples click(). E como a UI nativa anima e carrega de forma assíncrona, nunca use sleep fixo: use esperas explícitas que aguardam o elemento ficar visível ou clicável. Sleep fixo é a receita number um para os testes flaky que assombram suítes mobile.

Há ainda o que não tem paralelo no navegador e precisa entrar no roteiro de teste:

  • Permissões em tempo de execução (câmera, localização, notificações) — o diálogo do SO aparece por cima do app e precisa ser tratado.
  • Ciclo de vida: mandar o app para segundo plano e trazer de volta, e garantir que o estado sobrevive.
  • Condições de rede: modo avião, 3G lento, perda de conexão no meio de uma ação.
  • Interrupções: uma ligação ou notificação chegando durante o fluxo.

A fragmentação: onde você roda importa

Escrever o teste é metade do trabalho; a outra metade é onde ele roda. Emulador (Android) e simulador (iOS) são rápidos e ótimos para o desenvolvimento, mas não reproduzem GPU real, sensores, câmera nem o comportamento de bateria e rede de um aparelho físico. Dispositivos reais pegam bugs que o emulador esconde — ao custo de manutenção e lentidão.

E há a fragmentação: dezenas de tamanhos de tela, versões de SO e fabricantes que customizam o Android. Testar em tudo é impossível; testar só no seu aparelho é ingênuo. A saída prática é uma device matrix baseada em dados reais de quem usa o app (os 5–10 pares aparelho+SO mais comuns da sua base), rodada numa device farm na nuvem — BrowserStack, Sauce Labs — para cobrir o resto sob demanda.

Conclusão

Testar mobile com Appium reaproveita o que você já sabe de WebDriver, mas o terreno muda: árvore nativa em vez de DOM, accessibility ids em vez de CSS, gestos e esperas explícitas em vez de cliques, e um ecossistema fragmentado que obriga a escolher onde rodar com critério. Mantenha a suíte E2E enxuta no topo da pirâmide, ataque o flaky com esperas de verdade e ancore a cobertura numa matriz de dispositivos guiada pelos seus usuários reais.

People coming from web automation tend to think testing an app is "Selenium with a smaller screen". It isn't. The target stops being a DOM in a browser and becomes a tree of native elements running on an operating system that controls permissions, lifecycle and network — across hundreds of different devices. Appium is the bridge to that world, and understanding what it does under the hood avoids most of the frustration for beginners.

Why an app is a different target

In a web test you have one standard (HTML/DOM) and basically two or three rendering engines. On mobile, each platform has its own UI tree: on Android they are Views exposed by UiAutomator; on iOS they are XCUITest's XCUIElements. These are different automation APIs, maintained by Google and Apple, with their own vocabularies. Add runtime permissions, the app going to the background, screen rotation, the virtual keyboard covering fields and networks that drop — situations that rarely matter in the browser and are everyday life on a phone.

How Appium works under the hood

Appium is a server that speaks the WebDriver protocol (the same as Selenium). Your test sends standardized HTTP commands ("find this element", "tap here") and Appium translates them to the platform's native framework through a driver: UiAutomator2 on Android, XCUITest on iOS. That is the big advantage — you write the test almost the same for both platforms, in any language with a WebDriver client (Java, JavaScript, Python).

  Your test (Java/JS/Python)
        │  WebDriver commands (HTTP/JSON)
        ▼
  ┌──────────────┐
  │ Appium Server│  ── translates ──▶  platform driver
  └──────────────┘
        │                              │
   UiAutomator2 (Android)        XCUITest (iOS)
        │                              │
        ▼                              ▼
     App on device / emulator / simulator

This translation has a cost: each command makes a trip over the network to the device. That's why Appium tests are slower than web tests — and why it's worth keeping the mobile E2E suite lean, pushing as much coverage as possible to cheaper levels, exactly as the test pyramid preaches.

Finding elements: no CSS here

The biggest shock for people coming from the web: there is no CSS selector. You locate by accessibility attributes and by platform-specific strategies. The golden rule is the same as in good locator design — prefer stable identifiers over position or visible text.

StrategyWhen to use
accessibility idFirst choice: stable and cross-platform (maps to contentDescription on Android and accessibilityIdentifier on iOS)
id (resource-id)Good on Android; there's no equivalent on iOS
XPathLast resort: fragile and slow, it walks the entire tree
Ask the dev team for an accessibility id on every testable element. Besides making automation stable, it's the same attribute the screen reader uses — you get testability and accessibility in the same commit.

Gestures, waits and what only exists on mobile

Tapping isn't clicking. Apps live on gestures — swipe, scroll to an element, long press, pinch — which in Appium are expressed through pointer actions (W3C Actions), not a simple click(). And since native UI animates and loads asynchronously, never use a fixed sleep: use explicit waits that wait for the element to become visible or clickable. A fixed sleep is the number one recipe for the flaky tests that haunt mobile suites.

There is also what has no parallel in the browser and needs to be in the test plan:

  • Runtime permissions (camera, location, notifications) — the OS dialog appears on top of the app and has to be handled.
  • Lifecycle: sending the app to the background and bringing it back, and making sure state survives.
  • Network conditions: airplane mode, slow 3G, connection loss in the middle of an action.
  • Interruptions: a call or notification arriving during the flow.

Fragmentation: where you run matters

Writing the test is half the work; the other half is where it runs. Emulators (Android) and simulators (iOS) are fast and great for development, but they don't reproduce real GPU, sensors, camera or the battery and network behavior of a physical device. Real devices catch bugs the emulator hides — at the cost of maintenance and slowness.

And then there is fragmentation: dozens of screen sizes, OS versions and manufacturers that customize Android. Testing on everything is impossible; testing only on your own device is naive. The practical way out is a device matrix based on real data from the people who use the app (the 5–10 most common device+OS pairs in your user base), run on a cloud device farm — BrowserStack, Sauce Labs — to cover the rest on demand.

Conclusion

Testing mobile with Appium reuses what you already know about WebDriver, but the terrain changes: a native tree instead of the DOM, accessibility ids instead of CSS, gestures and explicit waits instead of clicks, and a fragmented ecosystem that forces you to choose where to run with care. Keep the E2E suite lean at the top of the pyramid, attack flakiness with real waits and anchor coverage in a device matrix driven by your real users.

Leia também

Voltar ao blog