Escreva Testes Melhores em 5 Passos
Os pontos que vou discutir aqui me ajudaram bastante a ter mais consciência dos meus testes e o que eu poderia melhorar neles. Se você tem experiência em escrever testes, provavelmente sabe do que eu vou falar, mas ainda assim será bom refrescar a memória e adicionar mais referências ao assunto. Se você começou a escrever testes a pouco tempo e está procurando maneiras de melhorar, então veio ao lugar certo!
Antes de começar, gostaria de avisá-lo que está não é uma lista extensiva com tudo o que você precisa saber para se tornar um especialista em escrever testes, mas eu tentei ao máximo colocar referências para permitir um aprofundamento maior em cada tópico. Adicione essa página aos favoritos e volte de tempos em tempos para investir em aprender um pouco mais sobre cada área específica.
#1 Trate Código de Teste como Código de Produção
Geralmente escutamos pessoas falando sobre a importância de ter código limpo. O mesmo pricípio deve ser aplicado para código de testes. O feedback fraco que você recebe de uma suíte de teste "suja" não lhe permite saber quando você quebrou algum teste ou se basta executar a suíte novamente.
Este Artigo de Robert Martin (Uncle Bob) apresenta uma boa discussão sobre tratar código de teste como código de produção. Ele também dedicou um capítulo inteiro do livro “Clean Code” para falar sobre Testes Unitários. Testes são uma das ferramentas mais poderosas para alcançar flexibilidade, então devem ser robustos e limpos. Mudanças acontecem todos os dias e precisamos estar preparados.
A melhor característica para testes limpos é a legibilidade. Se você pode ler e entender um caso de teste, você sabe como o código funciona, como as regras de negócios são aplicadas e consegue achar o que está quebrado. Eu prefiro ter códigos de teste que sejam claros do que códigos sem repetição, conhecidos como DRY - Don't Repeat Yourself (no entanto as ferramentas atuais permitem alcançar ambos). Ter código legível é o objetivo principal.
#2 Utilize Padrões de Testes Para Ótima Legibilidade
Padrões melhoram código de teste da mesma forma que melhoram código de produção. Um padrão que eu gosto bastante é o Arrange Act Assert (Organizar, Agir e Verificar), ou apenas 3-As. Ele basicamente diz que:
-
Arrange (Organizar): Configure suas informações e qualquer outro dado necessário ao teste;
-
Act (Agir): Execute a ação que o teste vai validar;
-
Assert (Verificar): Veja que o que era esperado realmente aconteceu - ou não;
Outro padrão sobre organização dos testes é o clássico do BDD - Given, When, Then. Martin Fowler faz uma boa descrição desta técnica. Também existem padrões que vão além de organizar o código. O livro XUnit Test Patterns de Gerard Meszaros tem vários Padrões, Técnicas e Heurísticas (Code Smells) para testes e pode ser lido online.
#3 Evite Testes Instáveis
O teste realmente quebrou ou basta executá-lo novamente? Se você chegar ao ponto de escutar alguém falando isso ou até mesmo você fazer essa pergunta, provavelmente você tem um problema. Neil Craven tem um ótimo post sobre o assunto, com algumas dicas de como se livrar de testes não determinísticos, por exemplo reescrevendo o teste um um nível mais baixo, entre outras.
Martin Fowler também tem um ótimo post sobre testes não determinísticos explicando em detalhes o dano que eles podem causar e como melhorá-los, por exemplo colocar testes em quarentena e outras ideias.
O livro XUnit Test Patterns também inclui uma profunda discussão sobre testes frágeis e as possíveis causas, como falta de isolamento, ou alta sensibilidade da interface.
#4 Teste no Nível Apropriado
Todo teste que você escreve tem um custo. E não é apenas o custo de escrever que é apontado logo de cara, mas também o custo de executá-lo. Pode ser que seja bem pequeno, como testes de JavaScript que rodam em 10 segundos, bem como testes que utilizam Selenium e são executados em paralelo demorando 1 hora para terminar.
Martin Fowler faz uma simples divisão de testes em 3 grupos, Unitários, Serviço e Aceitação, e os organiza em um modelo de Pirâmide de Testes. A Pirâmide sugere que você tenha uma grande número de Testes Unitários com uma boa cobertura e feedback rápido, menos testes de Serviço e uma porção bem pequena de testes de Aceitação. Fabio Pereira escreveu um bom caso de estudo da Pirâmide de Testes.
Alguns anti padrões são fáceis de identificar, como a casquinha de sorvete de Alister Scott, que parece com uma pirâmide invertida, com muitos testes de aceitação ou manual, e o cupcake de teste que parece um quadrado onde se busca o máximo de cobertura em todos os níveis.
Uma boa metáfora, feita por Fabio Pereira, descrevendo a importância de focar no que é importante para o teste é descrita neste post.
#5 Utilize Dublês de Teste
Dublês de Teste, ou Mocks como são mais conhecidos, ajudam a reduzir o custo dos teste ignorando comportamentos desnecessários. Então eu acho que você deve sim utilizar Dublês de Testes para conseguir testar no nível apropriado. O problema aparece quando so Dublês são muito utilizados e você acaba por não utilizar o que você deveria testar!
Uncle Bob publicou um excelente artigo sobre os vários tipos de Dublês de Testes e os seus objetivos. Com certeza conhecer qual tipo de Dublê utilizar em cada situação vai te ajudar bastante a evitar atirar no próprio pé.
Outros artigos que discutem o isolamento de testes e os prós e contras do uso de Dublês de Testes são apresentados e discutidos em mais detalhes por Gary Bernhardt e Fabio Pereira. Eles devem de dar ideias sobre como utilizar a dose certa.
Conclusão
Além dos pontos discutidos aqui, tem muito mais informação sobre TDD (a série recente de Google Hangouts por Martin, DHH e Kent sobre as vantagens e desvantagens do TDD, chamada de "Is TDD Dead" é bem esclarecedora), BDD, ADD e várias outras maneiras de abordar design de software e testes automatizados. Eu realmente gosto do fluxo de desenvolver testes, pensando sobre design e implementação que TDD e BDD dão, bem como mantendo a atenção na qualidade do código de teste. Mas depende de você achar qual funciona melhor no seu contexto.
Como dito antes, mesmo não sendo uma lista completa, ela vai prover informações suficientes para continuar a ler e aprender mais sobre testes. E, não importa qual caminho siga, vai ser uma experiência de aprendizado útil.
Se você tem feedback sobre os passos discutidos ou quer adicionar mais, sinta-se à vontade de comentar ou me fale comigo diretamente em @marcosbrizeno.
Aviso: As afirmações e opiniões expressas neste artigo são de responsabilidade de quem o assina, e não necessariamente refletem as posições da Thoughtworks.