Por que eu devo ler este artigo:Na prática, o desenvolvimento Guiado por Testes nada mais é do que escrever um teste antes de escrever qualquer código. Mas como assim? Vamos testar o que se não tem código? Quando escrevemos um método, esperamos que esse método faça alguma coisa, em outras palavras, temos uma expectativa do que precisa ser feito antes de criar o método. Então vamos levar essa expectativa para os testes e criar um teste que inicialmente falha e em seguida o fazemos ter sucesso ao receber o resultado de um método de produção.

O Test Driven Development é uma prática que tem se tornando cada vez mais comum no mundo do desenvolvimento devido a vantagem de garantir que você está entregando um software consistente. Porém TDD é uma forma de trabalhar, e como toda forma pode ser feita do jeito errado, do jeito certo ou qualquer coisa entre os dois. Nesse artigo você vai aprender como melhorar o seu desenvolvimento guiado por testes utilizando de práticas habituais e pequenos macetes.

Boas práticas na prática

Quando falamos em TDD é bom destacar que estamos falando em utilizar o Teste Unitário diretamente como ferramenta de desenvolvimento, portanto algumas práticas citadas aqui são aplicáveis como boas práticas direcionadas ao uso do teste unitário.

Para escrever testes de qualidade, precisamos ter em mente três ideias centrais:

  1. Testes precisam ser confiáveis

    Seus testes precisam dar a certeza de que eles não possuem bugs

  2. Testes precisam ser legíveis

    Os testes devem indicar claramente o que está acontecendo à primeira vista. Um teste que não dá pra saber o que está sendo testado não serve para nada.

  3. Testes precisam ser sustentáveis

    Os testes precisam seguir a escalabilidade do software que eles testam. Idealmente os testes devem ser imutáveis, portanto é importante garantir que eles se comportem da forma intencionada conforme o código é escalado

É importante ter sempre esse tripé em mente quando estiver escrevendo testes unitários, especialmente no caso do Desenvolvimento Guiado por Testes.

1 - Apenas escrever código em resposta a um teste falhando

Isso é a base de trabalhar com Desenvolvimento Guiado por Testes: escrever um teste que falha e fazê-lo ter sucesso com o código de produção, então os seus testes sempre devem ser escritos antes dos métodos de produção. Pode parecer um pouco óbvio, mas é muito comum perder o foco e "furar" o TDD quando a implementação é algo muito simples ou que o programador tem certeza que "não tem como dar errado". Mas a verdade é que "furar" o TDD é uma má prática e acaba deixando o software vulnerável a erros bobos que poderiam ter sido evitados. Isso auxilia a criação de testes confiáveis já que você sempre vai ver seu teste falhar e ter sucesso

2 - Nomeie os seus testes de forma autoexplicativa

Código de testes deve ser mais legível que código de produção, então não há necessidade de nomear os métodos de teste de forma minimalista. Prefira nomear os testes da forma que fique o mais claro possível o que o teste está fazendo, mesmo que o nome fique grande e/ou não siga convenções nominais de métodos.

Ao invés disso:

<?php
public function testCelsiusParaFahrenheit()
{
    $this->assertEquals(32, ConversorUnidades::celsiusParaFahrenheit(0));
}
Listagem 1. Não recomendado

Prefira algo assim:

<?php

public function testConverteZeroCelsiusParaTrintaEDoisFahrenheit() 
{
    $this->assertEquals(32, ConversorUnidades::celsiusParaFahrenheit(0));
}
Listagem 2. Recomendado

3 - Rodar os testes diversas vezes

Teste antes de codificar, após codificar e teste mais uma vez após refatorar o código, não importa o quão pequena for a alteração. Adotando esse tipo de prática, você assegura que seu código não vai quebrar em nenhum momento e passar despercebido.

4 - Teste apenas uma coisa por vez

Existem ferramentas de Teste Unitário que permitem que os métodos de teste tenham mais de um assert em si, como por exemplo o PHPUnit. Apesar de ser permitido pela ferramenta, isso é considerado uma má prática porque prejudica a clareza do teste sendo feito, aumenta a chance de ter bugs nos seus testes e torna debugar mais trabalhoso. Teste uma coisa só por vez.

5 - Não ponha lógica nos seus testes

Testes não devem conter lógica. Se o seu teste possui um if ou switch é porque você, provavelmente, está testando mais de uma coisa, e aumenta muito a chance de ter bugs no seu código de teste.

6 - Testes existentes devem passar antes de criar um novo teste

As vezes é tentador ignorar um teste que falha e partir pra criação do outro. Ou ainda escrever múltiplos testes de uma vez antes de implementar o código de produção. Isso deve ser evitado porque prejudica a clareza dos seus testes. Um dos objetivos do TDD é que a implementação do código de produção deve funcionar como o esperado sempre e quebrar essa regra geralmente se torna adiar o inevitável, já que o programador terá que implementar o código de produção eventualmente.

7 - Faça o teste passar da forma mais simples possível

A ideia é que quanto mais simples for a implementação mais fácil e melhor será de manter em produção ela será. Isso quer dizer que a maioria das aplicações funcionam melhor quando são mantidas simples ao invés de desnecessariamente complexas.

8 - Não use dependência entre testes

Cada teste deve executar independentemente de outros, portanto, programadores devem ser capazes de executar cada teste individualmente, grupos de teste ou todos os testes de uma vez. Haver dependências entre os testes os tornam mais propícios a bugs com a introdução de novos testes.

9 - Não remova nem altere testes antigos

Evite ao máximo possível alterar ou remover qualquer teste que já esteja passando. A grande vantagem de utilizar o Teste Unitário, e por consequência o TDD, é a manutenção do código de testes que é executado após cada alteração no código de produção. Alterar ou remover testes que funcionam faz perder totalmente o propósito dos testes que foram construídos.

As únicas exceções seriam no caso da implementação ser removida ou ter seu propósito alterado.

Saiba mais Veja a Série Receitas caseiras para teste unitário