Algo que noté recientemente es cuando estoy haciendo los siguientes tipos de proyectos:
- Al comenzar un proyecto
- Trabajando en un MVP / prototipo
- Agregar características que no están completamente definidas
- Trabajando en un proyecto de menor escala
Como referencia, ahora estoy trabajando en un proyecto de Python que actualmente tiene ~ 1k líneas de código, incluidos algunos comentarios y todos los espacios en blanco.
Me resulta inmensamente más fácil escribir primero las pruebas de integración, trabajar en el código y luego, una vez que la API se endurece, realmente funciona para agregar pruebas unitarias. Los tipos de pruebas que puedo ejecutar en mi main
función, por así decirlo, son más "de principio a fin" que cualquier otra cosa.
Esto se debe a que las pruebas unitarias son realmente molestas cuando una API está cambiando con bastante rapidez, que a menudo es el caso cuando se trabaja en un proyecto que coincide con alguno o la mayoría de los criterios anteriores.
¿Es este enfoque un buen enfoque y qué criterios deben considerarse al tomar la decisión de comenzar primero con pruebas unitarias o de integración para este tipo de proyectos? ¿Me falta el valor de las pruebas unitarias de este tipo de proyectos antes de que las API se solidifiquen más?
fuente
Respuestas:
No. Lo estás haciendo bien.
Los dos grandes objetivos de TDD son:
La cobertura de prueba se puede maximizar bastante bien en cualquier dirección. Es decir, independientemente de si primero prueba unidades pequeñas , aisladas o grandes , unidades "integradas", tiene la opción de escribir sus pruebas antes de sus implementaciones.
Lo que gana al escribir pruebas de nivel superior ("integración") primero, como lo está haciendo, es la seguridad de que sus interfaces e interacciones de nivel superior también se definen principalmente de acuerdo con su uso, en lugar de sus implementaciones internas.
El mismo efecto se puede lograr en gran medida con una buena "arquitectura" y diagramación. Pero, esas pruebas de alto nivel a menudo pueden revelar cosas que omitió en sus diagramas, o que simplemente se equivocó en su trabajo de "arquitectura".
Si no estás haciendo TDD (o algo similar), el orden en que escribes las pruebas no importa mucho. Las interfaces ya existen en el momento de la prueba, por lo que es mucho menos probable que sus pruebas cambien algo; solo servirán para proteger contra cambios de ruptura particulares.
Pero, si le preocupa construir la implementación de arriba hacia abajo frente a abajo, el primer punto todavía se aplica en gran medida. El código de alto nivel ayuda a definir interfaces de bajo nivel. Mientras que, si las interfaces de bajo nivel se escriben primero (o ya existen), el código de alto nivel está a su merced ...
1. Este también se aplica incluso si no está haciendo TDD completo. Incluso si solo está escribiendo 1 o 2 pruebas antes de su implementación, esas 1 o 2 pruebas pueden ayudarlo a definir o refinar sus interfaces antes de que sea demasiado tarde.
fuente
He trabajado como tú trabajas. Y no voy a decirte que no puedes. Te advertiré sobre algo con lo que te puedas encontrar.
Cuando cada prueba unitaria es simplemente una modificación, es difícil aprender a hacerlas flexibles. Tienden a ser nada más que pruebas de regresión. Como nunca los ha usado para ayudarlo a refactorizar, es muy fácil escribir los tipos de pruebas que realmente hacen que la refactorización sea más difícil. Esto tiende a salirse de control hasta que pierdes toda la fe en TDD.
Sin embargo, ya estás trabajando en algo. No te voy a decir que pares. Diré que valdría la pena comenzar algo más que tenga tiempo para explorar y seguir el ciclo de refactorización rojo verde desde el principio. Asegúrese de utilizar las pruebas para ayudarlo a refactorizar. Hasta que hayas dominado esta forma de trabajo, úsala con moderación en algo importante. Esta es una forma muy diferente de codificar y lleva tiempo acostumbrarse. Hacerlo a la mitad no le hará ningún bien a nadie.
Que dicho
Comprenda que una prueba unitaria NO es simplemente una prueba que actúa en una clase. Siempre que la API en la que esté trabajando pueda probarse sin hacer nada de lo siguiente, está haciendo pruebas unitarias muy bien:
Entonces, si su prueba de punta a punta involucra más de un objeto, está bien. Esta es una prueba unitaria, no una prueba de objeto.
Al igual que los métodos privados ya no necesitan ser probados luego de ser probados mediante la prueba de los métodos públicos que los usan, los objetos no necesitan ser desarrollados inicialmente bajo su propio arnés de prueba. Solo cuando se considera que los objetos se usan independientemente de la historia de extremo a extremo, realmente necesitan ser tratados como si tuvieran su propia interfaz y comportamiento para confirmar. Si tienes cuidado al respecto, es cuando haces públicos esos objetos. De esta manera no haces promesas que no hayas probado.
fuente