Cada vez que escribo pruebas unitarias, siempre he intentado tener una sola afirmación por prueba para facilitar la depuración cuando las pruebas fallan. Sin embargo, a medida que sigo esta regla, siento que estoy copiando constantemente el mismo código en cada prueba y al tener más pruebas, es más difícil volver a leer y mantener.
Entonces, ¿las pruebas de afirmación única violan DRY?
¿ Y hay una buena regla a seguir para encontrar un buen equilibrio, como solo tener una prueba por método ? *
* Me doy cuenta de que probablemente no haya una solución única para todo esto, pero ¿hay alguna forma recomendada de abordarlo?
testing
unit-testing
dry
Korey Hinton
fuente
fuente
Respuestas:
Las pruebas unitarias adecuadas tienen una convención de nomenclatura que lo ayuda a identificar de inmediato lo que ha fallado:
Es por eso que tiene una afirmación por prueba, de modo que cada método (y su nombre) corresponde a la condición que está afirmando.
Como ha señalado correctamente, cada nueva prueba tendrá un código de configuración similar. Al igual que con cualquier código, puede refactorizar el código común en su propio método para reducir o eliminar la duplicación y hacer que su código sea más SECO. Algunos marcos de prueba están diseñados específicamente para permitirle colocar ese código de configuración en un solo lugar .
En TDD, ninguna prueba es YAGNI, porque escribe pruebas basadas solo en lo que necesita que haga su código. Si no lo necesita, no escribirá la prueba.
fuente
No, pero promueve la violación.
Dicho esto, un buen diseño orientado a objetos tiende a salir por la ventana para las pruebas unitarias, principalmente por una buena razón. Es más importante que las pruebas unitarias se aíslen unas de otras para que la prueba se pueda interrogar de forma aislada y, si es necesario, se repare con la confianza de que no se rompen otras pruebas. Básicamente, la exactitud y legibilidad de la prueba es más importante que su tamaño o facilidad de mantenimiento.
Francamente, nunca he sido fanático de la única afirmación por regla de prueba por las razones que usted describe: conduce a una gran cantidad de código repetitivo que es difícil de leer, fácil de errar y difícil de corregir si refactoriza (lo que te lleva a refactorizar menos).
Si se supone que una función devuelve una lista de "foo" y "bar" para una entrada dada, pero en cualquier orden, está perfectamente bien usar dos afirmaciones para verificar que ambos están en el conjunto de resultados. Cuando se mete en problemas es cuando una sola prueba está comprobando dos entradas o dos efectos secundarios y no sabe cuál de los dos causó la falla.
Lo veo como una variación del Principio de responsabilidad única: debe haber una sola cosa que puede hacer que una prueba falle, y en un mundo ideal ese cambio solo debe romper una prueba.
Pero al final es una compensación. ¿Es más probable que pase más tiempo manteniendo todo el código de copia pegado, o pasará más tiempo buscando las causas raíz cuando múltiples fuentes pueden romper las pruebas? Mientras escribas -algunas- pruebas, probablemente no importe demasiado. A pesar de mi desdén por las pruebas de una sola afirmación, tiendo a equivocarme con más pruebas. Su experiencia puede ser diferente.
fuente
No. Esto parece ser la forma en que lo estás haciendo. A menos que haya encontrado una referencia notable donde afirman que esta es una buena práctica.
Use un dispositivo de prueba (aunque en la terminología de XUnit el conjunto de pruebas, la configuración y el desmantelamiento es el dispositivo), es decir, una configuración o ejemplos que se aplican a todas sus pruebas.
Use métodos como lo haría normalmente para estructurar su código. Cuando se realicen pruebas de refactorización, el TDD Rojo-Verde-Refactor no se aplica, en su lugar, se aplica "Refactorización en Rojo". Es decir,
De esta manera, sabrá que las pruebas aún dan resultados positivos y negativos.
Existen varios formatos estándar para las pruebas. Por ejemplo, Arrange, Act, Assert o Given When, Then (BDD) . Considere usar una función separada para cada paso. Debería poder llamar a la función para reducir repetitivo.
fuente