Testing In The Toilet
Una buena prueba unitaria debería exhibir otra serie de propiedades a parte de la de comprobar nuestro código para considerarse leíble y mantenible.
El código debe ser legible como documentación, que describa el código que se está testeando. Un test completo y breve contiene toda la información necesaria para entenderlo. Y otra propiedad es la resistencia y adaptabilidad, una vez escrito, un test resistente no necesita cambiar a no ser que el propósito de la clase que es testeada cambie.
Change detector Tests
Las pruebas no detectan ningún defecto y el costo de mantenimiento agregado ralentiza el desarrollo.
Don t Put Logic in Tests
Añadir lógica a un test, es aumentar la probabilidad de crear algún tipo de bug en el test, ya se hace que el test no funcione.
Cuando las pruebas necesitan su propia lógica, dicha lógica a menudo debe moverse fuera de los cuerpos de prueba hacia las utilidades y funciones auxiliares.
Dado que estos ayudantes pueden ser bastante complejos, generalmente es una buena idea que cualquier utilidad de prueba no trivial, a su vez tenga sus propias pruebas.
Effective testing
Existen 3 cualidades que hay que tratar de maximizar a la hora de diseñar pruebas para nuestro código.
Fidelidad: una prueba de alta fidelidad ayuda a evitar que los errores se introduzcan en el código. Se debe cubrir todos las posibles rutas y esperar el estado final.
Resistencia: una prueba resistente es aquella que solo falla cuando hay un cambio de ruptura en el código. Se puede realizar refactorización y otros cambios sin que afecte a la prueba y sin necesidad de modificarla.
Precisión: cuando una prueba de alta precisión falla, se indica exactamente dónde está el fallo. Se maximiza la precisión manteniendo pruebas pequeñas y bien enfocadas. Para las pruebas de integración, hay que validar el estado en cada límite.
Prefer Testing Public APIs Over Implementation
Todos los caminos se pueden probar a través de interface. Una API que puede pasar cualquier combinación posible a los métodos.
Probar con frecuencia implementation-detail class lleva a dos fallos:
- El código es más difícil de mantener, ya que necesita actualizar las pruebas con mayor frecuencia.
- Si prueba un comportamiento solo a través de ella, puede resultar en falsa confianza en el código, ya que la ruta de acceso puede no funcionar de manera correcta cuando accede a través de la API pública.
Printer Friendly
CLARIDAD: esto significa que el código sea legible como documentación, que describa el código que se está testeando.
COMPLETITUD: Un test completo contiene toda la información necesaria para entenderlo, pero nada extra que pueda distraer.
RESISTENCIA: Una vez escrito, un test resistente no necesita cambiar a no ser que el propósito/comportamiento de la clase que es testeada cambie
Descriptive Test Names
Nos permite comprender que se está testeando solo con leer el nombre, sin tener la necesidad de pasar por el cuerpo del método. También, dar nombres específicos te fuerza a dividir los tests sobre diferentes comportamientos.
Risk-Driven Testing
Hacer al principio del proyecto una brainstorm de los riesgos clave y de las mejores opciones para reducirlos nos ayudará a no malgastar esfuerzo y a adaptar el diseño.