A codificação e o teste de unidade violam o princípio DRY

8

O princípio seco afirma:

"Todo conhecimento deve ter uma representação única, inequívoca e autoritária dentro de um sistema".

No entanto, ao escrever testes para o código, você está descrevendo o comportamento esperado para o sistema duas vezes (uma vez no código e outra no teste). Eu sei que ambas as descrições são de uma perspectiva diferente, mas compartilham grande parte da ideia subjacente.

Alguma idéia sobre isso?

Em geral, acho que os testes de unidade e o princípio DRY são boas idéias e tento aplicá-los o máximo possível. Essa questão é mais em um nível filosófico, mas eu me perguntava se alguém também havia pensado nisso.

refro
fonte
4
1. Código não é o comportamento esperado, é o comportamento real. 2. O teste não pertence ao sistema, portanto o DRY ainda permanece.
Mouviciel 18/10/11

Respostas:

12

Você está operando com uma premissa defeituosa.

O código não é uma descrição do comportamento esperado, apenas os requisitos e casos de teste. E mesmo assim, os requisitos e testes definem dois lados do comportamento. Os requisitos definem as características e a funcionalidade do sistema de software como um todo e o teste define quais devem ser os resultados esperados e se compara aos requisitos. O código é a interpretação do desenvolvedor desses requisitos e da arquitetura do sistema.

Thomas Owens
fonte
Estou pensando na mesma linha, porém com uma nota de diferença: os testes de unidade também são baseados na interpretação do desenvolvedor dos requisitos e da arquitetura, para que não haja nenhum mal-entendido nesse nível entre testes de unidade e código (pelo menos com TDD greenfield) - código legado é uma questão diferente). São os testes de aceitação que são / devem basear-se na definição de requisitos do cliente.
Péter Török
@ PéterTörök Para testes de unidade, depende de quem os escreve. Isso é absolutamente verdade se o mesmo desenvolvedor escrever os testes e o código. Se um desenvolvedor escreve os testes e o código, você tem as interpretações de dois desenvolvedores e pode ver os problemas mais cedo. Quanto aos diferentes níveis de teste, estou usando o termo "teste" para me referir a testes de unidade, integração, sistema e aceitação, cada um escrito por uma pessoa ou grupo apropriado para o objetivo especificado. Se as pessoas erradas escrevem um teste (um desenvolvedor que escreve um teste de aceitação, por exemplo), o teste não é tão útil.
Thomas Owens
6

Não, isso não viola o princípio DRY, porque os testes de unidade não reproduzem a funcionalidade, eles apenas garantem que a funcionalidade (responsabilidade:) funcione corretamente. No caso de um teste de unidade, o método que você está testando ainda mantém authoritative representation. Seu código de teste pode parecer muito semelhante ao código que implementa o método na versão de produção, mas tem seu próprio objetivo inequívoco (afirmar o teste).

Joel Etherton
fonte
3

Mais ou menos. Se eles são muito parecidos, então sim, isso é uma coisa ruim. Seu teste não deve ser codificado da mesma maneira que o código que está testando. Portanto, você deve definir (1) uma expectativa e (2) uma implementação.

Eu gosto de pensar que é semelhante à contabilidade de entrada dupla . Um sistema de contabilidade sempre faz pelo menos 2 entradas (um débito e um crédito). Esta é uma medida de verificação de erro. No final do dia, os débitos e os créditos precisam ser equilibrados, caso contrário, ocorreu um erro. Você não pode ter um sistema de detecção de erros sem alguma forma de redundância.

Considere um CRC, por exemplo. Seu byte CRC é uma forma de redundância. É o suficiente para detectar qualquer pequeno erro no sinal. Da mesma forma, os CD de áudio têm muitas informações redundantes, portanto ainda tocam perfeitamente se forem arranhadas. Isso viola o princípio DRY? Provavelmente, mas é assim que você obtém confiabilidade.

Há outra maneira de ver também:

Seu teste é a resposta oficial. O código testado é gerado automaticamente por você, o macaco do código. Se pudéssemos gerar automaticamente código com base em testes de unidade (como geramos automaticamente camadas de acesso a dados com base em um esquema de banco de dados), não estaríamos violando o princípio DRY (ou pelo menos não o princípio OAOO).

Scott Whitlock
fonte
3

No entanto, ao escrever testes para o código, você está descrevendo o comportamento esperado para o sistema duas vezes (uma vez no código e outra no teste).

Não é bem assim. O código não é a descrição do comportamento esperado, mas sua implementação . Que pode conter erros, é por isso que precisamos dos testes.

Implementar até mesmo um algoritmo ou abstração bastante simples é muito mais complicado do que descrevê-lo. Qualquer programador decente pode descrever em poucas frases como a pesquisa binária funciona - ainda assim, Jon Bentley relatou que em seus experimentos, mais de 70% dos programadores experientes que participaram de seu curso falharam em implementá-la corretamente.

É por isso que precisamos de testes de unidade. Ninguém gosta de trabalhar duas vezes mais para alcançar os mesmos resultados, mas todos os desenvolvedores que formularam e evangelizaram essa prática perceberam, a partir de sua própria experiência adquirida com muito esforço, que precisavam deles. Eles eram pessoas inteligentes que queriam desenvolver software o mais rápido possível - o que requer a remoção de todas as tarefas duplicadas e inúteis do processo de desenvolvimento. Os testes de unidade não são um trabalho duplicado.

Péter Török
fonte