Tipos de testes e como usá-los

Concluído

Quando você está desenvolvendo uma estratégia de teste, os diferentes tipos de teste podem confundir um pouco. Saber o que são esses tipos de teste e como eles são diferentes uns dos outros é uma maneira sólida de implementar uma estratégia de teste robusta.

Observação

A diferença entre teste de unidade, de integração e funcional pode ser controversa. Essas descrições servem como diretrizes. O mais importante é ser consistente com o projeto e outros desenvolvedores.

Teste de unidade

O foco principal do teste de unidade é testar a menor parte da lógica de código possível. O efeito colateral desse tipo de teste é a velocidade. Os testes de unidade geralmente são executados rapidamente, pois (idealmente) não são necessários recursos externos, como bancos de dados, sites ou chamadas de rede.

Será difícil empregar testes de unidade em funções de teste e métodos que são longos e complexos, com várias condições lógicas. O teste de unidade força os desenvolvedores a pensar na complexidade do código e mantê-la no mínimo. Em geral, quanto mais curta for a função ou o método, mais fácil será testá-la.

Não há regras rígidas sobre testes de unidade, mas em geral as seguintes são normas comumente aceitas sobre testes de unidade:

  • Eles testam a menor parte da lógica possível.
  • Funções, métodos ou classes são testados o mais isolado possível, evitando a necessidade de configurar outras funções, métodos ou classes como um requisito.
  • Nenhum serviço externo, como bancos de dados ou serviços de rede, é necessário para sua execução.

Teste de integração

O teste de integração geralmente se concentra em testar a lógica que interagirá com outras partes da lógica em um projeto de código. Às vezes, esses testes exigirão a conexão com um banco de dados ou outro serviço externo.

Por exemplo, uma função que verifica um nome de usuário e senha provavelmente precisará se conectar a um banco de dados para verificar os dados existentes. Um teste para essa função pode exigir um banco de dados com informações existentes. Esses tipos de testes exigirão configurações um pouco mais complexas do que os testes de unidade e podem levar mais tempo para serem executados.

Aqui estão algumas normas geralmente aceitas sobre testes de integração:

  • Não são tão rápidos quanto os testes de unidade e tendem a exigir mais configuração inicial antes de serem executados.
  • Funções, métodos ou classes são testados com funcionalidade em outras funções, métodos ou classes.
  • Um serviço externo pode ser usado, mas nem todos os serviços do aplicativo.

Testes funcionais

Testes funcionais geralmente exigem a execução de um aplicativo como um todo. Para um site, um teste funcional pode precisar de um servidor Web, um banco de dados e qualquer outro serviço necessário para que o aplicativo seja executado. A ideia é replicar o aplicativo o mais próximo possível do ambiente de produção.

Como nem sempre é possível replicar com precisão um ambiente de produção, é preciso ter cuidado especial com as desvantagens da configuração. Por exemplo, se um site tiver um terabyte de dados em produção, provavelmente não há problema em testar com um subconjunto dos dados de produção. No entanto, não seria aconselhável usar um banco de dados embutido como o SQLite em vez do mesmo banco de dados PostgreSQL usado na produção. As diferenças de versão de serviços externos, como bancos de dados, podem fazer com que um teste seja aprovado, mas falhe na produção.

O teste funcional tem alguns dos seguintes aspectos:

  • Não são tão rápidos quanto os testes de unidade e tendem a exigir mais configuração inicial antes de serem executados.
  • Funções, métodos ou classes são testados com funcionalidade em outras funções, métodos ou classes.
  • Um serviço externo pode ser usado, mas nem todos os serviços do aplicativo.

Como os testes funcionais exigem mais serviços, uma reprodução do ambiente de produção e a configuração mais complexa dos tipos de teste, geralmente consumirão tempo e muitos recursos.

Um único teste funcional para uma loja de varejo online pode envolver as seguintes etapas a serem concluídas:

  1. Inscrever-se para um novo usuário.
  2. Selecionar um determinado produto e adicioná-lo ao carrinho de compras virtual.
  3. Concluir as informações de envio e cobrança.
  4. Selecionar o botão "comprar" para concluir a compra.
  5. Verificar se a nova conta existe, se as informações de cobrança e envio estão corretas e se o inventário foi atualizado.

Integração contínua

Embora a CI (Integração Contínua) não seja um tipo de teste, é uma parte importante que tem a ver com cada tipo de teste. Quando um plano de teste é implementado, é essencial ter algo que execute os testes de forma automatizada. Um ambiente de CI é o lugar certo para executar testes automaticamente. Esses testes podem ser executados em um agendamento, disparados por um evento ou executados manualmente. Esse ambiente geralmente será consistente com o local em que o código ou o projeto precisa ser executado.

A base para um bom processo de CI é a automação. A automação é o que definirá um ambiente consistente (e bem conhecido). Sem um ambiente de teste repetitivo e conhecido, problemas de depuração e testes com falha seriam demorados ou até impossíveis.

Disparado por um evento

Por exemplo, se um desenvolvedor deseja mesclar suas alterações na ramificação principal, o ideal é garantir que as alterações não causem interrupções. Um sistema de CI pode executar testes automaticamente da ramificação de um desenvolvedor e alertar quando houver uma falha. Impedir que código com falha de CI seja mesclado é uma boa maneira de aumentar a confiança e a robustez em um projeto.

Executar em um agendamento

Como já mencionado, a automação é uma parte crucial de um processo de CI. Normalmente, com a configuração de qualquer tipo de teste, as dependências devem ser instaladas para que os testes funcionem. Usar um agendamento para uma execução de teste (por exemplo, uma execução noturna) garante que um projeto seja compilado corretamente mesmo quando as dependências mudam.

Uma execução de teste agendada recorrente também pode ser útil na execução de testes que levam muito tempo para serem concluídos. Se um projeto de software tiver testes funcionais que levam algumas horas para serem concluídos, seria mais eficiente executar esses testes à noite, para que a equipe possa trabalhar em falhas logo pela manhã.

Gatilho manual

Por fim, embora as execuções de teste agendadas e orientadas a eventos sejam úteis, é bom poder executar um conjunto de testes manualmente. Por exemplo, quando se sabe que um conjunto de testes tem um problema, um desenvolvedor pode tentar uma correção ao executar novamente uma anteriormente com falha. Esse loop de comentários permite que as correções sejam testadas sem a necessidade de um evento ou agendamento específico. Além disso, uma execução de CI pode permitir alterações de configuração para a execução de um teste, e elas podem ser alteradas ad hoc para garantir que determinadas condições sejam atendidas.