Test Behaviors, Not Methods! Detecting Tests Obsessed by Methods
Este artigo propõe um novo "test smell" chamado "Test Obsessed by Method", que identifica testes que cobrem múltiplos caminhos de execução de um único método de produção, e valida sua detecção por meio de um estudo empírico na Biblioteca Padrão do Python, mostrando que tais testes frequentemente verificam múltiplos comportamentos e podem ser refatorados em unidades mais focadas.
Artigo original sob licença CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/). Esta é uma explicação gerada por IA do artigo abaixo. Não foi escrita nem endossada pelos autores. Para precisão técnica, consulte o artigo original. Ler aviso legal completo
Imagine que você é um chef preparando um menu degustação para um crítico gastronômico. A regra de ouro de uma boa culinária é: sirva um sabor distinto por prato. Se você servir um único prato contendo um bife, uma fatia de bolo e uma bola de sorvete tudo misturados, o crítico ficará confuso. Ele não conseguirá dizer se o bife está malpassado, se o bolo está doce demais ou se o sorvete está derretendo. Se algo der errado, ele não saberá a qual parte da refeição culpar.
No mundo do software, "pratos" são testes e "sabores" são comportamentos (o que o software deve fazer).
Este artigo, intitulado "Test Behaviors, Not Methods!" (Teste Comportamentos, Não Métodos!), argumenta que muitos testes de software estão sendo servidos atualmente como esse prato misturado e bagunçado. Os autores, Andre Hora e Andy Zaidman, introduzem uma nova maneira de identificar esses testes confusos, que eles chamam de "Tests Obsessed by Methods" (Testes Obcecados por Métodos).
Aqui está a divisão da descoberta deles usando analogias simples:
1. O Jeito Antigo: Contando os Ingredientes
Anteriormente, especialistas tentavam encontrar esses testes bagunçados simplesmente contando quantas vezes um teste "tocava" o código. Eles pensavam: "Se um teste chama o código de produção 3 ou mais vezes, é provável que esteja fazendo coisa demais".
Os autores chamam isso de um "cheiro" de "Eager Test" (Teste Ansioso). No entanto, eles descobriram que este método é como julgar uma refeição apenas contando quantos talheres foram usados. É impreciso. Um teste pode chamar uma função muitas vezes apenas para preparar o cenário, sem estar realmente testando diferentes sabores. É uma forma desajeitada de encontrar o problema.
2. A Nova Ideia: Assistindo ao Filme (Análise de Tempo de Execução)
Em vez de apenas contar colheradas, os autores sugerem assistir ao filme do teste enquanto ele é reproduzido. Eles propõem uma nova regra: Se um único teste força um pedaço de código a percorrer múltiplas "estradas" (caminhos) diferentes para chegar à linha de chegada, esse teste está "obsessivo".
Pense em um método de produção (um pedaço de código) como um labirinto.
- Bom Teste: Você envia um explorador para o labirinto para verificar se a porta da esquerda funciona. Então, você envia um segundo explorador para verificar se a porta da direita funciona. Claro e focado.
- Teste Obsessivo: Você envia um explorador que passa pela porta da esquerda, depois volta pelo caminho de origem, passa pela porta da direita e depois tenta o túnel secreto, tudo de uma vez só.
Os autores chamam isso de "Test Obsessed by Method". O teste é "ganancioso" porque tenta cobrir todos os caminhos possíveis de um único labirinto de uma só vez, em vez de dividir o trabalho.
3. O Experimento: Verificando a Biblioteca Python
Para ver se essa "obsessão" é um problema real, os autores fizeram uma caça ao tesouro pela Biblioteca Padrão do Python (uma enorme coleção de código pré-escrito usada por milhões de desenvolvedores).
Eles analisaram 2.054 testes. Aqui está o que encontraram:
- A Caçada: Eles encontraram 44 testes que estavam "obsessivos". Esses testes estavam tentando verificar múltiplos resultados diferentes de uma única função de uma só vez.
- A Dispersão: Esses testes bagunçados foram encontrados em 11 de 12 bibliotecas diferentes que eles verificaram. Não é um erro raro; é um hábito comum.
- A Correção: Em média, cada um desses 44 testes bagunçados estava, na verdade, tentando fazer dois trabalhos diferentes. Se você os dividisse, esses 44 testes poderiam se tornar 118 testes limpos e focados.
- O Momento "Aha!": Em cerca de 23% desses testes bagunçados, os programadores haviam de fato escrito comentários admitindo: "Ei, estamos testando duas coisas diferentes aqui!". Eles sabiam que estava bagunçado, mas fizeram assim mesmo.
4. Por Que Isso Importa?
Os autores argumentam que quando um teste tenta cobrir muitos caminhos ao mesmo tempo:
- É difícil de entender: Como aquele prato misturado, você não consegue dizer qual sabor está provando.
- É frágil: Se você alterar o código da "porta da esquerda", pode acidentalmente quebrar o teste da "porta da direita", mesmo que eles não tenham relação entre si.
- É difícil de consertar: Quando um teste falha, você não sabe qual comportamento específico quebrou.
A Conclusão
O artigo não pretende resolver todos os problemas de teste. Em vez disso, oferece uma ferramenta nova e mais afiada (usando análise de tempo de execução em vez de apenas contagem) para identificar testes que estão tentando fazer coisas demais com um único pedaço de código.
Eles sugerem que, se um teste força uma função a percorrer múltiplos caminhos diferentes, ele deve ser dividido. Assim como um chef deve servir o bife, o bolo e o sorvete em pratos separados, um desenvolvedor deve escrever testes separados para cada comportamento distinto.
Em resumo: Não seja ganancioso com seus testes. Teste um comportamento, um caminho, um sabor de cada vez.
Afogado em artigos na sua área?
Receba digests diários dos artigos mais recentes que correspondam às suas palavras-chave de pesquisa — com resumos técnicos, no seu idioma.