Escribimos pruebas para verificar la corrección del comportamiento de un programa.
La verificación de la corrección del comportamiento de un programa mediante la inspección del contenido de las declaraciones de salida utilizando sus ojos es un proceso manual , o más específicamente, visual .
Podrías argumentar que
la inspección visual funciona , verifico que el código hace lo que debe hacer, para estos escenarios y una vez que puedo ver que es correcto, estamos listos para comenzar.
Ahora, en primer lugar, es genial que estés interesado en saber si el código funciona correctamente o no. Eso es bueno. Estás por delante de la curva! Lamentablemente, hay problemas con esto como un enfoque.
El primer problema con la inspección visual es que eres un mal accidente de soldadura lejos de nunca poder verificar la corrección de tu código nuevamente.
El segundo problema es que el par de ojos utilizados está estrechamente acoplado con el cerebro del dueño de los ojos. Si el autor del código también posee los ojos utilizados en el proceso de inspección visual, el proceso de verificar la corrección depende del conocimiento sobre el programa internalizado en el cerebro del inspector visual.
Es difícil que un nuevo par de ojos entren y verifiquen la corrección del código simplemente porque no están asociados con el cerebro del codificador original. El propietario del segundo par de ojos tendrá que conversar con el autor original del código para comprender completamente el código en cuestión. La conversación como un medio para compartir conocimiento es notoriamente poco confiable. Un punto que es discutible si el codificador original no está disponible para el nuevo par de ojos. En ese caso, el nuevo par de ojos tiene que leer el código original.
Leer el código de otras personas que no está cubierto por las pruebas unitarias es más difícil que leer el código que tiene pruebas unitarias asociadas. En el mejor de los casos, leer el código de otras personas es un trabajo complicado, en el peor de los casos, esta es la tarea más difícil en la ingeniería de software. Hay una razón por la cual los empleadores, cuando anuncian ofertas de trabajo, enfatizan que un proyecto es nuevo (o completamente nuevo). Escribir código desde cero es más fácil que modificar el código existente y, por lo tanto, hace que el trabajo anunciado parezca más atractivo para los empleados potenciales.
Con las pruebas unitarias dividimos el código en sus componentes. Para cada componente, establecemos nuestro puesto indicando cómo debe comportarse el programa . Cada prueba unitaria cuenta una historia de cómo esa parte del programa debe actuar en un escenario específico. Cada prueba unitaria es como una cláusula en un contrato que describe lo que debería suceder desde el punto de vista del código del cliente.
Esto significa que un nuevo par de ojos tiene dos hilos de documentación en vivo y precisa sobre el código en cuestión.
Primero tienen el código en sí, la implementación, cómo se hizo el código ; segundo, tienen todo el conocimiento que el codificador original describió en un conjunto de declaraciones formales que cuentan la historia de cómo se supone que debe comportarse este código .
Las pruebas unitarias capturan y describen formalmente el conocimiento que poseía el autor original cuando implementaron la clase. Proporcionan una descripción de cómo se comporta esa clase cuando la usa un cliente.
Tiene razón al cuestionar la utilidad de hacer esto porque es posible escribir pruebas unitarias que son inútiles, no cubren todo el código en cuestión, se vuelven obsoletas o desactualizadas, etc. ¿Cómo nos aseguramos de que las pruebas unitarias no solo imiten, sino que mejoren el proceso de un autor concienzudo y concienzudo que inspeccione visualmente las declaraciones de salida de su código en tiempo de ejecución? Escriba la prueba de la unidad primero y luego escriba el código para hacer que la prueba pase. Cuando haya terminado, deje que las computadoras ejecuten las pruebas, son rápidas, son excelentes para realizar tareas repetitivas y son ideales para el trabajo.
Asegure la calidad de la prueba revisándolas cada vez que toque el código que prueban y ejecute las pruebas para cada compilación. Si una prueba falla, corríjala de inmediato.
Automatizamos el proceso de ejecución de pruebas para que se ejecuten cada vez que realizamos una compilación del proyecto. También automatizamos la generación de informes de cobertura de código que detalla qué porcentaje de código está cubierto y ejercido por las pruebas. Nos esforzamos por altos porcentajes. Algunas compañías evitarán que los cambios de código se registren en el control del código fuente si no tienen suficientes pruebas unitarias escritas para describir cualquier cambio en el comportamiento del código. Por lo general, un segundo par de ojos revisará los cambios de código junto con el autor de los cambios. El revisor realizará los cambios para garantizar que los cambios sean comprensibles y estén suficientemente cubiertos por las pruebas. Entonces el proceso de revisión es manual, pero cuando las pruebas (pruebas de unidad e integración y posiblemente pruebas de aceptación del usuario) pasan este proceso de revisión manual, pasan a formar parte del proceso de compilación automática. Se ejecutan cada vez que se registra un cambio. Aintegración continua El servidor lleva a cabo esta tarea como parte del proceso de compilación.
Las pruebas que se ejecutan automáticamente, mantienen la integridad del comportamiento del código y ayudan a evitar que futuros cambios en la base del código rompan el código .
Finalmente, proporcionar pruebas le permite volver a factorizar agresivamente el código porque puede hacer que las mejoras de código grandes sean seguras sabiendo que sus cambios no rompen las pruebas existentes.
Hay una advertencia para Test Driven Development y es que tienes que escribir código con el objetivo de hacerlo comprobable. Esto implica la codificación de interfaces y el uso de técnicas como la inyección de dependencias para crear instancias de objetos de colaboración. Echa un vistazo al trabajo de Kent Beck, que describe muy bien el TDD. Busque codificación de interfaces y estudiepatrones de diseño