Esta página descreve os princípios básicos dos testes de apps Android, incluindo as principais práticas recomendadas e os benefícios delas.
Benefícios dos testes
Os testes são uma parte importante do processo de desenvolvimento de apps. Executando testes no app de forma consistente, você pode verificar a precisão, o comportamento funcional e a usabilidade dele antes de o lançar publicamente.
É possível testar o app manualmente navegando por ele. Você pode usar diferentes dispositivos e emuladores, mudar o idioma do sistema e tentar gerar todos os erros do usuário ou percorrer todos os fluxos de usuário.
No entanto, o teste manual não é escalonável e pode ser fácil ignorar regressões no comportamento do app. Testes automatizados envolvem o uso de ferramentas que realizam testes para você. Isso é mais rápido, mais repetível e geralmente fornece feedback mais útil sobre seu app no início do processo de desenvolvimento.
Tipos de testes no Android
Os aplicativos para dispositivos móveis são complexos e precisam funcionar bem em vários ambientes. Por isso, há muitos tipos de testes.
Assunto
Por exemplo, há diferentes tipos de testes dependendo do assunto:
- Teste funcional: meu app faz o que deveria fazer?
- Teste de desempenho: ele faz isso de forma rápida e eficiente?
- Teste de acessibilidade: funciona bem com serviços de acessibilidade?
- Teste de compatibilidade: ele funciona bem em todos os dispositivos e níveis de API?
Escopo
Os testes também variam de acordo com o tamanho ou o grau de isolamento:
- Os testes de unidade ou testes pequenos verificam apenas uma pequena parte do app, como um método ou uma classe.
- Os testes de ponta a ponta ou grandes verificam partes maiores do app ao mesmo tempo, como uma tela inteira ou um fluxo de usuários.
- Os testes médios ficam entre os dois e verificam a integração entre duas ou mais unidades.

Há muitas maneiras de classificar testes. No entanto, a distinção mais importante para desenvolvedores de apps é onde os testes são executados.
Testes instrumentados x locais
É possível executar testes em um dispositivo Android ou em outro computador:
- Os testes instrumentados são executados em um dispositivo Android, físico ou emulado. O app é criado e instalado junto com um app de teste que injeta comandos e lê o estado. Os testes instrumentados geralmente são testes de interface do usuário, que iniciam um app e interagem com ele.
- Os testes locais são executados na sua máquina de desenvolvimento ou em um servidor. Por isso, também são chamados de testes do lado do host. Eles geralmente são pequenos e rápidos, isolando o assunto em teste do restante do app.

Nem todos os testes de unidade são locais, e nem todos os testes de ponta a ponta são executados em um dispositivo. Por exemplo:
- Teste local grande: você pode usar um simulador do Android executado localmente, como o Robolectric.
- Teste instrumentado pequeno: você pode verificar se o código funciona bem com um recurso de framework, como um banco de dados SQLite. É possível executar esse teste em vários dispositivos para verificar a integração com várias versões do SQLite.
Exemplos
Os snippets a seguir demonstram como interagir com a interface em um teste de UI instrumentado que clica em um elemento e verifica se outro elemento é exibido.
Espresso
// When the Continue button is clicked
onView(withText("Continue"))
.perform(click())
// Then the Welcome screen is displayed
onView(withText("Welcome"))
.check(matches(isDisplayed()))
IU do Compose
// When the Continue button is clicked
composeTestRule.onNodeWithText("Continue").performClick()
// Then the Welcome screen is displayed
composeTestRule.onNodeWithText("Welcome").assertIsDisplayed()
Este snippet mostra parte de um teste de unidade para um ViewModel (teste local do lado do host):
// Given an instance of MyViewModel
val viewModel = MyViewModel(myFakeDataRepository)
// When data is loaded
viewModel.loadData()
// Then it should be exposing data
assertTrue(viewModel.data != null)
Arquitetura testável
Com uma arquitetura de app testável, o código segue uma estrutura que permite testar facilmente diferentes partes dele de forma isolada. As arquiteturas testáveis têm outras vantagens, como melhor legibilidade, capacidade de manutenção, escalonabilidade e reutilização.
Uma arquitetura não testável produz o seguinte:
- Testes maiores, mais lentos e mais instáveis. As classes que não podem ser testadas por unidade podem precisar ser cobertas por testes de integração ou de interface maiores.
- Menos oportunidades para testar diferentes cenários. Testes maiores são mais lentos, então testar todos os estados possíveis de um app pode ser irrealista.
Para saber mais sobre as diretrizes de arquitetura, consulte o guia para arquitetura de apps.
Abordagens para desacoplamento
Se você puder extrair parte de uma função, classe ou módulo do restante, será mais fácil e eficaz testá-lo. Essa prática é conhecida como desacoplamento e é o conceito mais importante para uma arquitetura testável.
Confira algumas técnicas comuns de desacoplamento:
- Divida um app em camadas, como apresentação, domínio e dados. Você também pode dividir um app em módulos, um por recurso.
- Evite adicionar lógica a entidades com grandes dependências, como atividades e fragmentos. Use essas classes como pontos de entrada para o framework e mova a lógica de negócios e de interface para outro lugar, como um elemento combinável, um ViewModel ou uma camada de domínio.
- Evite dependências de framework diretas em classes que contêm lógica de negócios. Por exemplo, não use contextos do Android em ViewModels.
- Facilite a substituição de dependências. Por exemplo, use interfaces em vez de implementações concretas. Use a injeção de dependência, mesmo que você não use uma estrutura de DI.
Próximas etapas
Agora que você sabe por que deve testar e os dois principais tipos de testes, leia O que testar ou saiba mais sobre Estratégias de teste.
Se preferir criar seu primeiro teste e aprender na prática, confira os codelabs de teste.