Tengo solo más de 2 años de experiencia en el desarrollo de aplicaciones. En esos dos años mi enfoque hacia el desarrollo fue el siguiente
- Analizar requisitos
- Componentes / objetos de Identity Core, funciones requeridas, comportamiento, proceso y sus restricciones
- Crear clases, relación entre ellas, restricciones en el comportamiento y estados de los objetos.
- Crear funciones, procesar con restricciones de comportamiento según los requisitos
- Aplicación de prueba manual
- Si los cambios en los requisitos modifican componentes / funciones, pruebe manualmente la aplicación
Recientemente me presentaron a TDD y siento que esta es una muy buena manera de hacer el desarrollo, ya que el código desarrollado tiene una fuerte razón para existir y se mitigan muchos problemas posteriores a la implementación.
Pero mi problema es que no puedo crear pruebas primero, sino que estoy identificando componentes y simplemente escribiendo pruebas para ellos antes de escribir los componentes. mi pregunta es
- ¿Lo estoy haciendo bien? Si no es exactamente lo que tengo que cambiar
- ¿Hay alguna forma de identificar si la prueba que ha escrito es suficiente?
- ¿Es una buena práctica escribir una prueba para una funcionalidad muy simple que podría ser equivalente a 1 + 1 = 2 o es solo una exageración?
- ¿Es bueno cambiar la funcionalidad y probar si los requisitos cambian?
Respuestas:
Es difícil decir a partir de ese breve descripción, pero sospecho que no, usted está no haciendo bien. Nota: No estoy diciendo que lo que está haciendo no funciona o de alguna manera es malo, pero no está haciendo TDD. La "D" central significa "Impulsado", las pruebas conducen todo, el proceso de desarrollo, el código, el diseño, la arquitectura, todo .
Las pruebas le dicen qué escribir, cuándo escribirlo, qué escribir a continuación, cuándo dejar de escribir. Te cuentan el diseño y la arquitectura. (El diseño y la arquitectura emergen del código a través de la refactorización). TDD no se trata de pruebas. Ni siquiera se trata de escribir pruebas primero: TDD se trata de dejar que las pruebas lo conduzcan, escribirlas primero es solo un requisito previo necesario para eso.
No importa si realmente escribe el código o si está completamente desarrollado: está escribiendo (esqueletos de) código en su cabeza, luego escribe pruebas para ese código. Eso no es TDD.
Dejar ese hábito es difícil . Muy, muy duro. Parece ser especialmente difícil para programadores experimentados.
Keith Braithwaite ha creado un ejercicio que llama TDD como si lo quisieras decir . Consiste en un conjunto de reglas (basadas en las Tres Reglas de TDD del Tío Bob Martin , pero mucho más estrictas) que debe seguir estrictamente y que están diseñadas para guiarlo hacia la aplicación de TDD de manera más rigurosa. Funciona mejor con la programación de pares (para que tu pareja pueda asegurarse de que no estás rompiendo las reglas) y un instructor.
Las reglas son:
Por lo general, esto conducirá a diseños muy diferentes que el "método pseudo-TDD" que se practica con frecuencia de "imaginar en su cabeza cuál debería ser el diseño, luego escribir pruebas para forzar ese diseño, implementar el diseño que ya había imaginado antes de escribir su pruebas ".
Cuando un grupo de personas implementa algo como un juego de tic tac toe usando pseudo-TDD, generalmente terminan con diseños muy similares que involucran algún tipo de
Board
clase con una matriz de 3 × 3 deInteger
s. Y al menos una parte de los programadores habrá escrito esta clase sin pruebas porque "saben que la van a necesitar" o "necesitan algo contra lo que escribir sus pruebas". Sin embargo, cuando obligas a ese mismo grupo a aplicar TDD como si lo quisieras, a menudo terminarán con una amplia diversidad de diseños muy diferentes, a menudo sin emplear nada ni remotamente similar a aBoard
.Cuando cubren todos los requisitos comerciales. Las pruebas son una codificación de los requisitos del sistema.
Una vez más, lo tienes al revés: no escribes pruebas de funcionalidad. Escribes funcionalidad para pruebas. Si la funcionalidad para aprobar la prueba resulta trivial, ¡genial! ¡Acaba de cumplir un requisito del sistema y ni siquiera tuvo que trabajar duro para cumplirlo!
No. Al revés. Si un requisito cambia, usted cambia la prueba que corresponde a ese requisito, observa cómo falla y luego cambia el código para que se apruebe. Las pruebas siempre son lo primero.
Es dificil hacer esto. Necesitas docenas, tal vez cientos de horas de práctica deliberada para construir algún tipo de "memoria muscular" para llegar a un punto, donde cuando se acerca la fecha límite y estás bajo presión, ni siquiera tienes que pensar en ello. , y hacerlo se convierte en la forma más rápida y natural de trabajar.
fuente
Board
clase con un Matriz 3x3 deint
s (o algo así). Mientras que, si los obliga a hacer TDDAIYMI, a menudo terminan creando un mini-DSL para capturar el conocimiento del dominio. Eso es anecdótico, por supuesto. Un estudio estadísticamente y científicamente sólido sería bueno, pero como suele ser el caso con estudios como este, son demasiado pequeños o demasiado caros.Describes tu enfoque de desarrollo como un proceso "de arriba abajo": comienzas desde un nivel de abstracción más alto y profundizas cada vez más en los detalles. TDD, al menos en la forma en que es popular, es una técnica "de abajo hacia arriba". Y para alguien que trabaja principalmente "de arriba hacia abajo", puede ser muy inusual trabajar "de abajo hacia arriba".
Entonces, ¿cómo puede aportar más "TDD" a su proceso de desarrollo? Primero, supongo que su proceso de desarrollo real no siempre es tan "de arriba abajo" como lo describió anteriormente. Después del paso 2, probablemente habrá identificado algunos componentes que son independientes de otros componentes. A veces decides implementar esos componentes primero. Los detalles de la API pública de esos componentes probablemente no sigan solo sus requisitos, los detalles también siguen sus decisiones de diseño. Este es el punto donde puede comenzar con TDD: imagine cómo va a usar el componente y cómo va a usar la API. Y cuando comienza a codificar un uso de API de este tipo en forma de prueba, acaba de comenzar con TDD.
En segundo lugar, puede hacer TDD incluso cuando va a codificar más "de arriba hacia abajo", comenzando con componentes que dependen primero de otros componentes no existentes. Lo que tiene que aprender es cómo "burlarse" de estas otras dependencias primero. Eso le permitirá crear y probar componentes de alto nivel antes de pasar a los componentes de nivel inferior. Un ejemplo muy detallado sobre cómo hacer TDD de arriba a abajo se puede encontrar en esta publicación de blog de Ralf Westphal .
fuente
Lo estás haciendo bien.
Sí, use una herramienta de prueba / cobertura de código . Martin Fowler ofrece algunos buenos consejos sobre la cobertura de pruebas.
En general, cualquier función, método, componente, etc. que espera obtener algún resultado dadas algunas entradas es un buen candidato para una prueba unitaria. Sin embargo, como con la mayoría de las cosas en la vida (de ingeniería), debe considerar sus compensaciones: ¿se compensa el esfuerzo al escribir la prueba de la unidad, lo que resulta en una base de código más estable a largo plazo? En general, opte por escribir el código de prueba para la funcionalidad crucial / crítica primero. Más adelante, si encuentra que hay errores asociados con alguna parte no probada del código, agregue más pruebas.
Lo bueno de tener pruebas automatizadas es que verá de inmediato si un cambio rompe las afirmaciones anteriores. Si espera esto debido a los requisitos modificados, sí, está bien cambiar el código de prueba (de hecho, en TDD puro, primero cambiaría las pruebas de acuerdo con los requisitos, luego adoptaría el código hasta que cumpla con los nuevos requisitos).
fuente
Escribir pruebas primero es un enfoque completamente diferente para escribir software. Las pruebas no son solo una herramienta de verificación adecuada de la funcionalidad del código (todas pasan) sino la fuerza que define el diseño. Si bien la cobertura de prueba puede ser una métrica útil, no debe ser el objetivo en sí mismo: el objetivo de TDD no es llegar a un buen% de cobertura de código, sino pensar en la capacidad de prueba de su código antes de escribirlo.
Si tiene problemas para escribir las pruebas primero, le recomiendo encarecidamente que haga una sesión de programación en pareja con alguien con experiencia en TDD, para que tenga una experiencia práctica de "la forma de pensar" sobre el enfoque completo.
Otra buena cosa que hacer es mirar videos en línea donde el software se está desarrollando usando TDD desde la primera línea. Uno bueno que solía presentarme a TDD fue Let's Play TDD de James Shore. Eche un vistazo, ilustrará cómo funciona el diseño emergente, qué preguntas debe hacerse mientras escribe las pruebas y cómo se crean, refactorizan e iteran nuevas clases y métodos.
Creo que esta es la pregunta incorrecta que hacer. Cuando hace TDD, elige hacer TDD y el diseño emergente como la forma de escribir software. Si alguna funcionalidad nueva que necesita agregar siempre comienza con una prueba, siempre estará allí.
Obviamente depende, usa tu juicio. Prefiero no escribir pruebas en las comprobaciones nulas de parámetros, si el método no es parte de una API pública, pero de lo contrario, ¿por qué no confirmaría que el método Add (a, b) devuelve a + b?
Nuevamente, cuando cambia o agrega una nueva funcionalidad a su código, comienza con una prueba, ya sea agregando una nueva prueba o cambiando una existente cuando cambian los requisitos.
fuente