O que significa "DAMP not DRY" quando se fala em testes de unidade?

345

Ouvi alguém dizer que os testes de unidade (por exemplo, nUnit, jUnit, xUnit) devem ser

DAMP não SECO

(Por exemplo, testes de unidade devem conter "código úmido" e não "código seco")

Sobre o que eles estão falando?

Ian Ringrose
fonte
2
Não há nada de especial nos testes de unidade que justificam códigos não DRY. Escrever testes não-DRY é uma desculpa dos programadores preguiçosos para tentar criar território por sua preguiça. Simplificando, DRYness e legibilidade são preocupações ortogonais.
Acumenus
2
O DRYness aumenta a distância de navegação do código, o que, por sua vez, resulta em maior carga mental para entender. Isso ocorre em um ambiente baseado em texto "normal". Um editor de projeção pode reduzir a ortogonalidade do código, mas não em todos os casos.
Peter

Respostas:

595

É um equilíbrio, não uma contradição

DAMP e DRY não são contraditórios; eles equilibram dois aspectos diferentes da capacidade de manutenção de um código . O código de manutenção (código fácil de alterar) é o objetivo final aqui.

DAMP (frases descritivas e significativas) promove a legibilidade do código.

Para manter o código, primeiro você precisa entender o código. Para entender, você precisa ler. Considere por um momento quanto tempo você gasta lendo o código. Isso é muito. O DAMP aumenta a capacidade de manutenção, reduzindo o tempo necessário para ler e entender o código.

DRY (não se repita) promove a ortogonalidade do código.

A remoção da duplicação garante que todo conceito no sistema tenha uma única representação autorizada no código. Uma alteração em um único conceito de negócio resulta em uma única alteração no código. O DRY aumenta a capacidade de manutenção isolando as alterações (riscos) apenas nas partes do sistema que precisam ser alteradas.

Então, por que a duplicação é mais aceitável nos testes?

Os testes geralmente contêm duplicação inerente porque estão testando a mesma coisa repetidamente, apenas com valores de entrada ou código de configuração ligeiramente diferentes. No entanto, diferentemente do código de produção, essa duplicação geralmente é isolada apenas para os cenários em um único dispositivo / arquivo de teste. Por esse motivo, a duplicação é mínima e óbvia, o que significa que representa menos risco para o projeto do que outros tipos de duplicação.

Além disso, a remoção desse tipo de duplicação reduz a legibilidade dos testes. Os detalhes que foram duplicados anteriormente em cada teste agora estão ocultos em algum novo método ou classe. Para ter uma visão completa do teste, você agora precisa reunir todas essas peças mentalmente.

Portanto, como a duplicação do código de teste geralmente apresenta menos riscos e promove a legibilidade, é fácil ver como é considerado aceitável.

Como princípio, favorece o DRY no código de produção, favorece o DAMP no código de teste. Embora ambos sejam igualmente importantes, com um pouco de sabedoria, você pode equilibrar a sua favor.

Chris Edwards
fonte
18
Este é um excelente resumo conciso. Também gosto de salientar que um teste DAMP é mais resistente diante de requisitos em mudança, e a medição da obviedade de um teste é um tremendo benefício quando alguém é encarregado de reescrever seus testes para atender aos novos requisitos. Jesper Lundberg também tem um bom tratado sobre esse assunto.
31414 Jason
3
@ Jason, Btw existe um link para "Jesper Lundberg também tem um bom tratado sobre esse assunto" ?
Pacerier 03/12/2015
2
@JohnSaunders, você pode evitar alguns dos que a duplicação usando o padrão do construtor de dados de teste: natpryce.com/articles/000714.html
si618
2
Secar código de teste tem o potencial para criar um teste obscura através da introdução de um convidado mistério
jayeff
11
Eu também acrescentaria que testes bem escritos são essencialmente a documentação / comentários para o seu aplicativo. Portanto, ser mais descritivo ajuda a explicar sua intenção para outros desenvolvedores. E como o OP diz, eles são independentes em cada teste, portanto o risco para a sua aplicação é mínimo. O pior cenário é que você tem um teste ou configuração de teste redundante e leva mais tempo para executar o conjunto de testes. Prefiro errar ao lado de uma boa cobertura de teste.
Lee McAlilly
60

DAMP - Frases descritivas e significativas.

"DAMP not DRY" valoriza a legibilidade sobre a reutilização do código. A idéia do DAMP não DRY nos casos de teste é que os testes devem ser fáceis de entender, mesmo que isso signifique que os casos de teste às vezes tenham código repetido.

Consulte também O código duplicado é mais tolerável em testes de unidade? para alguma discussão sobre os méritos desse ponto de vista.

Pode ter sido cunhado por Jay Fields , em relação aos idiomas específicos do domínio.

Dominic Rodger
fonte
11
Boa resposta e link para a pergunta relacionada. Não existe uma escolha perfeita de DAMP vs DRY. Queremos um código o mais seco possível e em testes que não sejam tão secos que o teste se torne difícil de entender. Quando um teste falha, quero que o motivo seja óbvio para que o desenvolvedor possa começar a corrigir o SUT, o que significa que eu me inclino para o código DAMP nos testes. Como a maioria dos conceitos de programação, sempre é possível levar algo muito longe. Se o código do seu teste de unidade é tão seco que leva um longo tempo para determinar como e por que o teste falhou, ele pode estar "muito seco".
Gerald Davis
29

"SECO" é "Não se repita"

Este é um termo usado para instruir as pessoas a escreverem códigos reutilizáveis, para que você não escreva códigos semelhantes repetidamente.

"DAMP" é "Frases descritivas e significativas".

Este termo tem como objetivo informar que você escreva um código que possa ser facilmente entendido por alguém que esteja olhando para ele. Se você seguir este princípio, terá nomes de variáveis ​​e funções longos e descritivos, etc.

Spudley
fonte
15
AIUI, DRY não é apenas uma questão de economizar tempo através da reutilização - também evita que diferentes caminhos de código fiquem "fora de sincronia". Se você copiar e colar a mesma lógica em várias classes, todas as instâncias desse código precisarão ser atualizadas quando uma alteração for necessária. (E, inevitavelmente, um deles não vai, e vai explodir quando exercido.)
Andrzej Doyle
20

Damp = 'Frases descritivas e significativas' - seus testes de unidade devem poder ser 'lidos':

A legibilidade é mais importante do que evitar código redundante.

Do artigo:

DAMP significa "frases descritivas e significativas" e é o oposto de DRY, não no sentido em que diz "tudo deve parecer uma pilha de lixo e ser impossível de ler", em que a legibilidade é mais importante do que evitar código redundante.

O que isso significa e onde usá-lo?

O DAMP se aplica principalmente ao escrever o código de teste. O código de teste deve ser muito fácil de entender, a ponto de que alguma redundância seja aceitável.

stuartd
fonte
11

Já existem várias respostas aqui, mas eu queria adicionar outra, pois não achei que elas necessariamente explicassem o melhor possível.

A idéia de DRY (não se repita) é que, no código do aplicativo , você deseja evitar código redundante ou repetitivo. Se você tem algo que seu código precisa fazer várias vezes, você deve ter uma função ou classe para ele, em vez de repetir código semelhante em vários lugares.

Este é um conceito de programação bastante conhecido.

DAMP (Frases Descritivas e Significativas) é para seus testes de unidade. A idéia aqui é que os nomes dos métodos de teste de unidade sejam longos e descritivos - efetivamente frases curtas que descrevam o que você está testando.

por exemplo: testWhenIAddOneAndOneIShouldGetTwo() { .... }

Ao ler um nome de método DAMP assim, você deve entender exatamente o que o gravador de testes estava tentando obter, sem precisar ler o código de teste (embora o código de teste também possa seguir esse conceito, é claro, com nomes de variáveis ​​com palavras, etc).

Isso é possível porque um método de teste de unidade tem entrada muito específica e saída esperada, de modo que o princípio DAMP funciona bem para eles. É improvável que os métodos no código principal do aplicativo sejam específicos o suficiente para garantir nomes como esse, especialmente se você o tiver escrito com o princípio DRY em mente.

DAMP e DRY não se contradizem - eles abrangem diferentes aspectos de como o código é escrito - mas, no entanto, eles normalmente não são usados ​​juntos porque os métodos escritos com o princípio DRY em mente seriam de uso geral e dificilmente adequados. ao nome do método altamente específico. Portanto, em geral, como explicado acima, o código do seu aplicativo deve estar SECO e o código do teste de unidade DAMP.

Espero que isso ajude a explicar um pouco melhor.

SDC
fonte
5

Concordo com Chris Edwards no sentido de que você precisa encontrar um equilíbrio entre os dois. Outra coisa a ser observada é que, se, na tentativa de remover a duplicação, você acaba adicionando muita estrutura adicional ao seu código de teste de unidade (ou seja, ao levar o DRY a extremos), você corre o risco de introduzir bugs nele. Em tal situação, você teria que testar sua unidade ou deixar pedaços de estrutura não testados.

Philip Atz
fonte
0

Não desejo duplicar o esforço aqui, mas você pode fazer testes que são DAMP, mas que têm o benefício de DRY. Por outro lado, os testes DRY não satisfazem os testes DAMP em alguns casos.

Eu escrevi sobre DRY vs DAMP, que inclui alguns exemplos.

Nenhuma das abordagens deve ser sua única solução; às vezes, o DAMP é um exagero; outras, uma adição muito agradável.

Como regra geral, você deve aplicar a regra de três. Se você encontrar a duplicação pela terceira vez, pode valer a pena tentar escrever testes no estilo DAMP, mas mesmo assim nem toda duplicação é ruim . O contexto é importante.

Finglas
fonte