Testes de software — Boas Práticas

Falaremos aqui especificamente de testes de unitários, eles normalmente são mais comuns e devem ser feitos em maiores quantidades.

Benefícios da criação de testes

Começaremos falando dos benefícios para criar testes unitários, afinal de contas, o usuário final não precisa do código gerado pelos testes.

  • Garantir maior segurança em manutenções e evoluções.
  • Garantir um código mais conciso.
  • Serve como uma documentação para os desenvolvedores.

Esses são dois objetivos que justificam a necessidade de criação de testes.

“Código legado é aquele sem testes.”
Michel Feathers

Boas práticas na criação de testes

Para entendermos como os testes devem ser comportar, vamos entender dois acrônimos, o FIRST e o CORRECT.

Os praticantes do TDD, seguem o princípio de começar com os testes, fazer com que ele falhe, depois escrever o código para fazer o teste passar e seguir esse fluxo até finalizar a demanda.

Entretanto, mesmo não seguindo o TDD, é preciso escrever os testes respeitando o FIRST:

Fast: Quanto mais rápido melhor, então o ideal é não depender de integrações externas, como acesso a arquivos, internet, banco de dados…

Independent: Um teste não pode depender de outro, deve poder ser executado independente da ordem da execução.

Repeatable: Independente da quantidade de vezes que ele for executado, a saída dele deve ser a mesma.

Self-validating: Cada teste precisa ter pelo menos uma assertiva para validar a execução.

Thorough/Timely: Os testes precisam realizar uma cobertura de forma inteligente, buscando identificar todos os possíveis cenários, para garantir que o software funcionará em todos eles.
E eles também precisam ser feitos no momento correto, a criação dos testes ajudam a deixar o código mais limpo, então eles devem ser feitos antes de ir para produção.

Além dos testes serem FIRST, é necessário também pensar que ele deve ser CORRECT.

Esse acrónimo é útil para validar se o seu teste está adequado. Para isso é necessário responder as seguintes perguntas:

Conformity: O dado representa o tipo esperado?

Order: A ordem dos resultados está conforme esperado?

Range: O tamanho do dado está validado?

Reference: O código faz referência a algo em um contexto externo?

Existence: O valor pode ser negativo, nulo, vazio?

Cardinality: Há valores suficientes?

Time: Está tudo sendo executado na ordem correta, está seguro contra concorrência?
Exemplo: Está consultando o registro e depois realizado o update.

Nomenclatura dos testes

Além desses acrónimos é muito importante você criar testes com nomes significativos. Os testes podem ser executados por novos integrantes para entender melhor o objetivo de determinada classe.

Para dar nomes aos testes, existem algumas abordagens mais famosas:

“Given-When-Then”: De acordo com determinado contexto, quando acontecer determinado acontecimento, deve gerar determinado resultado.

Por exemplo: dadoUsuarioEstaLogadoQuandoClicarSairDeveraRemoverSessao();

“When-Then”: É comum também utilizar sem o contexto.

Por exemplo: quandoUsuarioLogarDeveExibirTermosUso();

“Should-When”: Deve ocorrer determinado acontecimento quando acontecer determinada ação.

Por exemplo: deveHaverDescontoAoComprarMuito();

Essa foi uma introdução na importância dos testes e o que deve ser pensando quando for cria-los. Para finalizar, lembre-se que se os seus testes de degradarem, o seu código também irá, então mantenha limpos os seus testes.

Referências:

Pragmatic Unit Testing in Java 8 With JUnit
- Jeff Langr, Andy Hunt, Dave Thomas

Clean code
- Robert Cecil Martin

I'm a happy developer, trying to help the world and peoples with technologic

I'm a happy developer, trying to help the world and peoples with technologic