Qualidade do código em testes de unidade?

23

Ao escrever testes de unidade, vale a pena gastar tempo extra para tornar o código com boa qualidade e legibilidade?

Ao escrever testes, muitas vezes viole a Lei de Demeter , para escrever mais rapidamente e evitar o uso de tantas variáveis. Tecnicamente, os testes de unidade não são reutilizados diretamente - eles são estritamente vinculados ao código, portanto não vejo motivo para gastar muito tempo com eles; eles só precisam ser funcionais.

m3th0dman
fonte
5
A legibilidade e a manutenção precisam ser o foco principal dos testes de unidade.
precisa
2
Testes também são códigos!
Grant Palin
Ainda faz parte do seu projeto, mesmo que não seja enviado aos clientes. Trate-o adequadamente.

Respostas:

11

Você definitivamente deve cuidar da mesma forma, se não melhor, dos seus testes de unidade do que do seu código de produção em termos de qualidade e legibilidade. Os testes de unidade costumam ser a primeira coisa que você olha ao tentar entender o que algum código faz, e o leitor deve entender rapidamente o que está em jogo ao analisar o teste. Os testes de unidade também tendem a mudar muito e quebram muito se seu design não for robusto, o que meio que anula os benefícios de ter testes.

A violação da lei de Deméter é definitivamente um problema em seus testes de unidade por esse motivo, assim como em outros 2 que vêm à minha mente:

  • Se seus testes violam a Lei de Deméter nas seções Organizar ou Atuar , é provavelmente um sinal de que seu código de produção também o faz, já que seus testes de unidade são apenas mais um consumidor do seu código e provavelmente chamarão e operarão a classe sob teste da mesma forma. da maneira que qualquer outro código de produção faria.

  • Se seus testes violam a Lei de Demeter em suas seções Assert (ou seja, você verifica o valor de algo profundamente aninhado no gráfico de dependências do objeto em teste), pode ser que esses sejam realmente testes de integração em vez de testes de unidade. Em outras palavras, se no Teste A você afirmar que ABCD é igual a algo, pode ser que você esteja realmente tentando testar D e A em vez de apenas A.

A propósito, quando você diz

Eu quebro muitas vezes a Lei de Demeter, para escrever mais rápido e não usar tantas variáveis.

você deve estar ciente de que escrever

var grab = myDependency.Grab;
var something = grab.Something;
var very = something.Very;

very.Deep();

na verdade não é melhor Demeter sábio do que

myDependency.Grab.Something.Very.Deep();

se é isso que você quis dizer.

guillaume31
fonte
47

Vale absolutamente a pena gastar tempo escrevendo código de boa qualidade para testes de unidade:

  • Eles exigirão manutenção como qualquer outro código.
  • Os testes de unidade são uma das melhores fontes de documentação para o seu sistema e, sem dúvida, a forma mais confiável. Eles realmente devem mostrar:
    • Intenção: "qual é o comportamento esperado?".
    • Uso: "como devo usar esta API?".
  • Eles exigirão a depuração como qualquer outro código.

O único fator a favor de uma abordagem um pouco mais ad-hoc é que seus testes de unidade nunca serão uma API pública, portanto você não precisa se preocupar com quais interfaces / etc. você está expondo.

vaughandroid
fonte
22

Sim, isso importa. Há várias razões pelas quais os testes de unidade devem ser mantidos com um padrão comparável como outro código:

  • Cada teste de unidade também serve como documentação para o testado. Quando os testes são abrangentes e cobrem o maior número possível de casos extremos e condições de erro, eles geralmente podem substituir a documentação de comentários de uma classe ou função. Eles também podem servir como ponto de partida para pessoas novas na base de códigos.

  • Os testes de unidade também podem ser de buggy. E os erros são mais visíveis quando o código está bem escrito.

  • Se, por algum motivo, mais tarde você precisar dividir um módulo, provavelmente também precisará dividir seus testes de unidade. Isso é mais fácil se os testes forem escritos de forma que eles tenham dependências facilmente discerníveis.

Dito isto, sempre há a questão da praticidade. Dependendo do idioma e da natureza do seu código, pode ser difícil escrever testes de unidade "limpos" sem gastar muito mais tempo nos testes do que no código que eles deveriam testar. Nesse caso, costumo voltar a testar as coisas fáceis, rápidas e as funcionalidades mais críticas, sem me preocupar muito com a cobertura completa. Sempre que um bug surge mais tarde, escrevo um teste para ele e verifico se posso refatorar o novo teste e os existentes para torná-los mais agradáveis.

Benjamin Kloster
fonte
12

se você não conseguir ler um ponto mais unívoco e descobrir o que está testando na próxima vez que falhar, gastará o dobro do tempo de depuração (uma vez para descobrir do que se trata o teste e outra para corrigir o código que está testando)

honestamente, os unittests devem ter um resultado esperado; faça procedimento; obter resultado real; teste esperado em relação ao tipo real de estrutura que é fácil de escrever e entender

catraca arrepiante
fonte
1

O código de teste deve receber tanto amor quanto o seu código de produção. Para facilitar a leitura, talvez até mais. Se alguém que não seja você (incluindo você duas semanas depois de deixar o código) deve entender o que está acontecendo, você deve tornar o código agradável.

Isso significa:

  • Extraia a construção de dados de teste em classes de construtores.
  • Extraia asserções multible em métodos separados de assertion.
  • Seja muito preciso em sua nomeação. Assert.That(x4, Is.EqualTo(y16*2*SOME_VALUE), ASS_ERR_TXT_56)faz muito pouco sentido para a maioria dos leitores.

Levados ao extremo, os testes podem ser escritos para que sejam quase tão fáceis de ler e entender quanto a prosa. O testador extremo provavelmente diria que um teste de unidade com mais de 10 linhas de comprimento é ruim.

Morten
fonte
1

A razão prática mais importante é que toda vez que você altera o código, altera os testes de unidade. E se você está fazendo TDD, está alterando os testes de unidade primeiro.

Faça uma destas ações nos seus testes:

  • Código duplicado
  • Diminuir a legibilidade
  • Acoplamento apertado
  • Acoplamento temporal
  • Alta complexidade ciclomática (muitas dependências)

E você trabalha bastante quando é necessária uma mudança.

Trate seus testes como sugeriu e você acabará se arrependendo. Você provavelmente chegará à falsa conclusão de que "o TDD não funciona".

Yam Marcovic
fonte
0

Depende se esses testes de unidade são "temporários" ou não. E se

  1. O teste será usado com frequência;

  2. Os desenvolvedores precisam trabalhar com testes de unidade escritos por outros desenvolvedores;

  3. A maioria dos testes é feita por testes de unidade

então os testes devem ser escritos corretamente. Caso exista um erro no próprio teste, será difícil encontrá-lo e corrigi-lo, especialmente se tiver passado algum tempo desde que o teste foi escrito.

Por outro lado, se esses testes forem usados ​​apenas pelos próprios desenvolvedores, acho que está tudo bem. Ainda assim, é mais preferível escrever código 'legível'. Como o catraca disse, você gastará mais tempo consertando seus testes do que gastaria em escrevê-los corretamente.

superM
fonte
(1) testes de unidade não são temporários (2) mesmo que sejam para o seu auto, em um mês (ou mais), você não vai lembrar de todos os detalhes, portanto, é importante fazê-lo corretamente - mesmo para si mesmo
BЈовић