Conceitos básicos para testes de apps Android

Esta página descreve os princípios básicos de teste de apps Android, incluindo as práticas recomendadas centrais e os benefícios deles.

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 manualmente o app 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ários.

No entanto, o teste manual não é bem dimensionado, e é fácil ignorar regressões no comportamento do app. O teste automatizado envolve o uso de ferramentas que executam testes para você, o que é mais rápido, mais repetível e geralmente oferece feedback mais acionável sobre o app mais cedo no 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: o app faz o que deveria?
  • Teste de desempenho: ele é rápido e eficiente?
  • Teste de acessibilidade: o app funciona bem com os serviços de acessibilidade?
  • Teste de compatibilidade: o aplicativo 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 pequenos verificam apenas uma parte muito pequena do app, como um método ou uma classe.
  • Os testes de ponta a ponta ou grandes testes verificam partes maiores do app ao mesmo tempo, como uma tela inteira ou o fluxo de usuários.
  • Os testes médios são intermediários e verificam a integração entre duas ou mais unidades.
Os testes podem ser pequenos, médios ou grandes.
Figura 1: escopos de teste em um aplicativo típico.

Há muitas maneiras de classificar testes. No entanto, a distinção mais importante para os desenvolvedores de apps é onde os testes são executados.

Testes instrumentados e 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 com um app de teste que injeta comandos e lê o estado. Os testes instrumentados geralmente são testes de interface, que iniciam um app e interagem com ele.
  • Os testes locais são executados na máquina de desenvolvimento ou em um servidor. Por isso, eles 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.
Os testes podem ser executados como testes instrumentados em um dispositivo ou testes locais na máquina de desenvolvimento.
Figura 2: diferentes tipos de testes, dependendo de onde são executados.

Nem todos os testes de unidade são locais e nem todos os testes completos são executados em um dispositivo. Por exemplo:

  • Teste local grande: é possível usar um simulador do Android executado localmente, como o Robolectric (link em inglês).
  • Teste de instrumentação pequeno: você pode verificar se seu código funciona bem com um recurso de framework, como um banco de dados SQLite. Você pode executar esse teste em vários dispositivos para verificar a integração com várias versões do SQLite.

Exemplos

Os snippets abaixo demonstram como interagir com a interface em um teste de interface instrumentado que clica em um elemento e verifica se outro é mostrado.

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 testável de app, 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, facilidade 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 em unidades podem precisar ser cobertas por testes de integração ou de interface maiores.
  • Menos oportunidades para testar cenários diferentes. Testes maiores são mais lentos, então testar todos os estados possíveis de um app pode ser irrealístico.

Para saber mais sobre as diretrizes de arquitetura, consulte o guia para arquitetura de apps.

Abordagens de desacoplamento

Se você puder extrair parte de uma função, classe ou módulo do restante, o teste será mais fácil e eficaz. Essa prática é conhecida como desacoplamento e é o conceito mais importante para a arquitetura testável.

Técnicas de desacoplamento comuns incluem:

  • 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 dependências grandes, 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 uma camada combinável, ViewModel ou 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 das 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 um framework de DI.

Próximas etapas

Agora que você sabe por que testar e quais são os dois tipos principais de testes, leia O que testar ou saiba mais sobre Estratégias de teste.

Se você quiser criar seu primeiro teste e aprender na prática, confira os codelabs de teste.