¿Qué significa "DAMP not DRY" cuando se habla de pruebas unitarias?

345

Escuché a alguien decir que las pruebas unitarias (por ejemplo, nUnit, jUnit, xUnit) deberían ser

DAMP no SECO

(Por ejemplo, las pruebas unitarias deben contener "código húmedo" no "código seco")

De qué están hablando?

Ian Ringrose
fuente
2
No hay nada especial sobre las pruebas unitarias que garanticen el código que no sea DRY. Escribir pruebas que no sean DRY es una excusa de los programadores perezosos para intentar forjar el territorio para su pereza. En pocas palabras, el SECADO y la legibilidad son preocupaciones ortogonales.
Acumenus
2
DRYness aumenta la distancia de navegación del código, lo que a su vez resulta en una mayor carga mental para comprender. Esto se mantiene en un entorno de texto "normal". Un editor de proyección podría reducir la ortogonalidad del código, pero no en todos los casos.
Peter

Respuestas:

595

Es un equilibrio, no una contradicción.

DAMP y DRY no son contradictorios, sino que equilibran dos aspectos diferentes de la capacidad de mantenimiento de un código . El código mantenible (código que es fácil de cambiar) es el objetivo final aquí.

DAMP (frases descriptivas y significativas) promueve la legibilidad del código.

Para mantener el código, primero debe comprender el código. Para entenderlo, tienes que leerlo. Considere por un momento cuánto tiempo pasa leyendo el código. Es mucho. DAMP aumenta la capacidad de mantenimiento al reducir el tiempo necesario para leer y comprender el código.

DRY (no se repita) promueve la ortogonalidad del código.

Eliminar la duplicación asegura que cada concepto en el sistema tenga una única representación autorizada en el código. Un cambio en un solo concepto de negocio da como resultado un solo cambio en el código. DRY aumenta la capacidad de mantenimiento al aislar el cambio (riesgo) solo en aquellas partes del sistema que deben cambiar.

Entonces, ¿por qué la duplicación es más aceptable en las pruebas?

Las pruebas a menudo contienen duplicación inherente porque están probando lo mismo una y otra vez, solo con valores de entrada o código de configuración ligeramente diferentes. Sin embargo, a diferencia del código de producción, esta duplicación generalmente está aislada solo de los escenarios dentro de un único dispositivo / archivo de prueba. Debido a esto, la duplicación es mínima y obvia, lo que significa que representa menos riesgo para el proyecto que otros tipos de duplicación.

Además, eliminar este tipo de duplicación reduce la legibilidad de las pruebas. Los detalles que se duplicaron previamente en cada prueba ahora están ocultos en algún nuevo método o clase. Para obtener una imagen completa de la prueba, ahora tiene que juntar mentalmente todas estas piezas.

Por lo tanto, dado que la duplicación del código de prueba a menudo conlleva menos riesgos y promueve la legibilidad, es fácil ver cómo se considera aceptable.

Como principio, favorezca DRY en el código de producción, favorezca DAMP en el código de prueba. Si bien ambos son igualmente importantes, con un poco de sabiduría puede inclinar la balanza a su favor.

Chris Edwards
fuente
18
Este es un gran resumen conciso. También me gusta señalar que una prueba DAMP es más resistente frente a los requisitos cambiantes, y medir la evidencia de una prueba es un gran beneficio cuando otra persona tiene la tarea de reescribir sus pruebas para que se ajusten a los nuevos requisitos. Jesper Lundberg también tiene un buen tratado sobre este tema.
Jason
3
@ Jason, por cierto, ¿hay un enlace a "Jesper Lundberg también tiene un buen tratado sobre este tema" ?
Pacerier
2
@JohnSaunders, puede evitar parte de esa duplicación utilizando el patrón del generador de datos de prueba: natpryce.com/articles/000714.html
si618
2
SECAR el código de prueba tiene el potencial de crear una prueba oscura al presentar un invitado misterioso
jayeff
1
También agregaría que las pruebas bien escritas son esencialmente la documentación / comentarios para su aplicación. Por lo tanto, ser más descriptivo ayuda a explicar su intención a otros desarrolladores. Y como dice el OP, son independientes en cada prueba, por lo que el peligro para su aplicación es mínimo. En el peor de los casos, tiene una prueba redundante o una configuración de prueba y lleva más tiempo ejecutar el conjunto de pruebas. Prefiero equivocarme del lado de una buena cobertura de prueba.
Lee McAlilly el
60

DAMP - Frases descriptivas y significativas.

"DAMP not DRY" valora la legibilidad sobre la reutilización del código. La idea de DAMP not DRY en casos de prueba es que las pruebas deben ser fáciles de entender, incluso si eso significa que los casos de prueba a veces tienen código repetido.

Consulte también ¿Es el código duplicado más tolerable en las pruebas unitarias? para alguna discusión sobre los méritos de este punto de vista.

Pudo haber sido acuñado por Jay Fields , en relación con los lenguajes específicos de dominio.

Dominic Rodger
fuente
1
Buena respuesta y enlace a la pregunta relacionada. No hay una opción perfecta de DAMP vs DRY. Queremos un código lo más seco posible y en las pruebas eso significa que no es tan seco que la prueba se vuelve difícil de entender. Cuando una prueba falla, quiero que la razón sea obvia para que el desarrollador pueda comenzar a arreglar el SUT, lo que significa que me inclino hacia el código DAMP en las pruebas. Como la mayoría de los conceptos de programación, siempre es posible llevar algo demasiado lejos. Si el código de prueba de su unidad es tan seco que toma mucho tiempo determinar cómo y por qué falló la prueba, podría estar "demasiado seco".
Gerald Davis
29

"SECO" es "No te repitas"

Este es un término que se usa para decirle a las personas que escriban código que sea reutilizable, para que no termines escribiendo código similar una y otra vez.

"DAMP" es "Frases descriptivas y significativas".

Este término tiene la intención de decirle que escriba un código que pueda entender fácilmente alguien que lo esté mirando. Si sigue este principio, tendrá nombres largos y descriptivos de variables y funciones, etc.

Spudley
fuente
15
AIUI, DRY no es solo una cuestión de ahorrar tiempo mediante la reutilización, sino que también evita que las diferentes rutas de código se "desincronicen". Si copia y pega la misma lógica en varias clases, cada instancia de ese código deberá actualizarse cuando se requiera un cambio. (Y, inevitablemente, uno de ellos no lo hará, y explotará cuando se haga ejercicio.)
Andrzej Doyle
20

Damp = 'Frases descriptivas y significativas' - sus pruebas unitarias deberían poder 'leerse':

La legibilidad es más importante que evitar el código redundante.

Del artículo:

DAMP significa "frases descriptivas y significativas" y es lo opuesto a DRY, no en el sentido de que dice "todo debería verse como un montón de basura y ser imposible de leer", ya que la legibilidad es más importante que evitar el código redundante.

¿Qué significa esto y dónde usarlo?

DAMP se aplica principalmente al escribir código de prueba. El código de prueba debe ser muy fácil de entender hasta el punto de que es aceptable cierta redundancia.

Stuartd
fuente
11

Ya hay varias respuestas aquí, pero quería agregar otra ya que no pensé que necesariamente lo explicaran tan bien como pudieran.

La idea de DRY (no se repita) es que en el código de su aplicación desea evitar el código redundante o repetitivo. Si tiene algo que su código necesita hacer varias veces, debe tener una función o clase para ello, en lugar de repetir un código similar en varios lugares.

Este es un concepto de programación bastante conocido.

DAMP (Frases descriptivas y significativas) es para sus pruebas unitarias. La idea aquí es que los nombres de sus métodos de prueba de unidad deben ser largos y descriptivos, oraciones cortas que describan lo que está probando.

p.ej: testWhenIAddOneAndOneIShouldGetTwo() { .... }

Cuando lee un nombre de método DAMP como este, debe comprender exactamente lo que el escritor de prueba estaba tratando de lograr, sin siquiera tener que leer el código de prueba (aunque el código de prueba también puede seguir este concepto también, por supuesto, con nombres de variables verbales, etc)

Esto es posible porque un método de prueba unitaria tiene una entrada muy específica y una salida esperada, por lo que el principio DAMP funciona bien para ellos. Es poco probable que los métodos en su código de aplicación principal sean lo suficientemente específicos como para garantizar nombres como este, especialmente si lo ha escrito teniendo en cuenta el principio DRY.

DAMP y DRY no se contradicen entre sí: cubren diferentes aspectos de cómo se escribe su código, pero no obstante, generalmente no se usan juntos porque los métodos escritos con el principio DRY en mente serían de propósito general y es poco probable que sean adecuados a nombre de método altamente específico. Por lo tanto, en general, como se explicó anteriormente, su código de aplicación debe estar SECO y su código de prueba de unidad DAMP.

Espero que eso ayude a explicarlo un poco mejor.

SDC
fuente
5

Estoy de acuerdo con Chris Edwards en que debes lograr un equilibrio entre los dos. Otra cosa a tener en cuenta es que si, en un intento de eliminar la duplicación, terminas agregando una gran cantidad de estructura adicional en el código de prueba de tu unidad (es decir, al llevar DRY a los extremos), corres el riesgo de introducir errores allí. En tal situación, tendría que hacer una prueba unitaria de sus pruebas unitarias o dejar fragmentos de estructura sin probar.

Philip Atz
fuente
0

No deseo duplicar el esfuerzo aquí, pero puede tener pruebas que son DAMP pero tienen el beneficio de DRY. Por otro lado, las pruebas DRY no satisfarán las pruebas DAMP en algunos casos.

He blogueado sobre DRY vs DAMP que incluye algunos ejemplos.

Ningún enfoque debería ser su única solución, a veces DAMP es excesivo, otras veces una muy buena adición.

Como regla general, debe aplicar la regla de tres. Si ve la duplicación por tercera vez, puede valer la pena estudiar cómo escribir pruebas de estilo DAMP, pero aun así no toda la duplicación es mala . El contexto importa.

Finglas
fuente