Quando um teste precisa tocar em um botão, ele deve encontrar o botão primeiro. Existem duas maneiras de fazer isso. Ele pode perguntar ao aplicativo pela sua árvore de elementos e procurá-lo lá. Ou pode tirar uma captura de tela e olhar para ela.
Até alguns anos atrás, apenas a primeira opção funcionava.
Por que os testes baseados em localizadores ganharam
O Selenium foi lançado em 2004. Foi construído para a web, onde o DOM é a página: um botão é um elemento, ele tem um id, você o procura e clica nele.
A testagem de aplicativos móveis copiou esse modelo. O Appium roda no protocolo WebDriver, o mesmo usado pelo Selenium, então os testes móveis eram escritos da mesma maneira que os testes web. Espresso, XCUITest e Detox fazem a mesma coisa por baixo: encontram o elemento na árvore, depois agem sobre ele.
Havia uma boa razão para construí-lo dessa forma. Em 2004 um computador não podia olhar para uma tela. A visão computacional poderia corresponder a um modelo ou ler texto com OCR. Não conseguia dizer que o retângulo arredondado com "Login" escrito nele é um botão que você pode tocar. A árvore de elementos era a única descrição da IU que o software podia ler.
E funciona bem. Uma consulta à árvore leva menos de um milissegundo e não custa nada. Retorna sempre o mesmo elemento, ou falha. Não há chutes. Milhões desses testes estão rodando em CI agora e capturam bugs reais. Se sua árvore é estável, essa é a ferramenta certa e não há razão para mudar.
Por que os localizadores falham
Localizadores são instáveis
Um localizador identifica um elemento por sua posição na estrutura do aplicativo: um resource id no Android, um accessibility identifier no iOS. O teste procura o elemento por esse identificador e age sobre ele. Esses identificadores vivem no código do aplicativo, então quando o código muda (um id renomeado em uma refatoração, uma view movida) o localizador deixa de corresponder e o teste falha mesmo que o aplicativo funcione. iOS e Android expõem estruturas diferentes, então a mesma lógica precisa de um conjunto separado de localizadores em cada.
Modais alteram a estrutura em tempo real também. Um diálogo de permissão, uma solicitação ATT ou um popup para avaliar o aplicativo aparecem sobre a tela atual e o elemento que o teste está procurando não está lá naquele rodada. Porque eles aparecem condicionalmente, o mesmo teste pode passar em uma execução e falhar na próxima. Agentes de codificação podem agora reescrever automaticamente um localizador falhado, o que torna a correção mais rápida, mas não muda quão frequentemente as falhas acontecem.
Algumas telas não têm árvore
No móvel, a árvore nunca foi a IU em si. É uma descrição da tela, gerada ao lado dela para ferramentas de acessibilidade. Geralmente está lá. Às vezes não.
Um jogo Unity ou Unreal desenha um texto que parece ser um botão e não há elemento por trás dele para procurar. Interfaces Canvas são a mesma coisa. E qualquer coisa fora do seu aplicativo nunca esteve na sua árvore no primeiro lugar: uma folha de pagamento, uma página OAuth, o teclado do sistema. Fluxos de login e checkout passam direto por essas telas. Não há nada para consultar, então uma ferramenta baseada em localizadores não pode rodar nessas telas.
Como funciona a testagem móvel baseada em visão
LLMs mudaram o que uma máquina pode ler. Um LLM pode agora olhar para uma captura de tela e dizer: isso é um formulário de login, aquilo é o botão principal, aquilo é o sistema perguntando por permissão da câmera. Não perfeitamente, mas bem o suficiente para agir sobre.
Então um teste baseado em visão executa um loop: tira uma captura de tela, decide a próxima ação, toca ou digita, tira outra captura de tela para verificar o que aconteceu.
Isto remove vários dos problemas acima de uma vez:
- Nenhum ID para adicionar. Qualquer build é testável como está; nenhum desenvolvedor precisa tornar uma tela testável primeiro.
- Um teste para ambas as plataformas. As capturas de tela do iOS e Android mostram um botão de login.
- Nenhuma janela pop-up para lidar. Um diálogo em cima da tela é apenas o que a próxima captura de tela mostra.
- Casos de teste em linguagem simples. Faça login com a conta salva e abra a guia Pedidos. Sem código, então um QA manual pode escrevê-los sem precisar de um programador.
Manual vs baseado em localização vs baseado em visão
Agora há três opções para testes de aplicativos móveis, não duas.
| QA Manual | Baseado em localização | Baseado em visão | |
|---|---|---|---|
| Quem escreve o teste | Qualquer pessoa que conheça a sequência de eventos | Um engenheiro de automação | Qualquer pessoa que conheça a sequência de eventos |
| Custo para escrever e manter | Baixo | Baixo por correção, mas nunca para de crescer | Baixo |
| Custo por execução | Uma hora de uma pessoa, toda vez | Perto de zero | Perto de zero (algumas chamadas LLM) |
| Velocidade por ação | Segundos | Milissegundos | Segundos |
| Rodando em paralelo | Hire mais pessoas | Sim | Sim |
| Jogos, diálogos do SO, canvas | Sim | Não | Sim |
| Repetível | Vai de caso a caso | Exatamente | Vai de caso a caso |
Manual: barato para escrever, caro para executar. Uma lista de verificação leva um minuto para ser escrita, e depois custa uma hora de trabalho de uma pessoa em cada execução. Não escala: vinte fluxos custam vinte vezes as horas, então equipes testam apenas os poucos fluxos que mais preocupam ao invés de todos.
Baseado em localização: barato agora para ambos. A manutenção costumava ser o imposto, e agentes que reescrevem locators reduziram isso. Mas só funciona onde há uma árvore de elementos estável. Sem árvore, sem teste.
Baseado em visão: também barato para ambos, e não precisa de árvore alguma, então alcança o que locators não podem: jogos, canvas, diálogos do SO, um fluxo em ambas as plataformas. Menos repetível que locators, e substitui a passagem manual, não o conjunto de locators.
Escolhendo uma abordagem para testes móveis
As duas abordagens automatizadas são complementares. O custo já não as separa, a cobertura sim. Use locators onde a árvore é estável; use visão onde ela não é, ou onde a alternativa é testar manualmente.
A partir do momento que um teste pode ler a tela, coisas que você só podia verificar manualmente se tornam automatizáveis: jogando por um nível, editando uma foto, seguindo um pin em um mapa, ou executando um cadastro de ponta a ponta através do código de email, da paywall e do popup de permissão. Cada um desses precisava de uma pessoa antes de cada lançamento; agora cada um é uma frase que roda sem acompanhamento.
A questão aberta é a última linha da tabela: reproduzibilidade. Uma consulta de locator retorna o mesmo elemento ou falha. Um LLM faz chamadas de julgamento, e pode alcançar o mesmo objetivo por um caminho diferente na próxima execução. Quanto isso importa, e como limitá-lo sem perder a flexibilidade que torna a visão útil, é um tópico em separado. Isso será abordado em uma postagem futura.

