2009-06-19 16 views
10

Estoy tratando de practicar TDD.Descubriendo otros objetos mientras hago TDD

Mi entendimiento es que TDD deben ir así

  1. Escribir una lista de pruebas para la interfaz/clase que voy a desarrollar.
  2. Comience con la prueba más fácil no implementada de mi lista de prueba.
  3. Escriba la prueba, no hay código de implementación todavía.
  4. Escriba la interfaz de la clase para compilar el código.
  5. Ejecute la prueba dando como resultado una prueba de falla.
  6. Escriba la implementación que hace pasar la prueba.
  7. Refactorizar el desastre que he creado.
  8. Goto 2.

El problema que tengo es al escribir la puesta en práctica o hacer la refactorización. A menudo llego a la conclusión de que la implementación que acabo de escribir debería delegarse en otra clase.

¿Qué debería hacer un verdadero TDD'r en este momento?

  1. dejo la lista de prueba existente solo por un tiempo y crear uno nuevo para la clase recién descubierto (el mismo problema puede manifestarse en la aplicación de la nueva clase offcourse)
  2. ir por el camino de interacción basado de probando y simulando la nueva clase, continúa con las pruebas de la clase en la que estás trabajando y vuelve más tarde para crear una implementación correcta de la clase burlada.
  3. Esta situación no debería presentarse. Probablemente no he pensado bien mi diseño inicial. (¿pero no sería así para derrotar uno de los propósitos de TDD ?!).

Me encantaría saber cómo otras personas manejan estas situaciones.

Respuesta

9

No busque una relación uno-a-uno entre sus pruebas y sus clases. Si decide introducir una nueva clase, supongamos que se trata de una refactorización respaldada por la prueba original, y agregue las pruebas en el lugar apropiado (donde eso depende del caso específico) cuando desee agregar funcionalidad (o para probar las eventualidades que necesite) para cubrir aquello que aún no has probado).

Yo agregaría que el éxito principal en TDD es entrar en el ritmo del refactor rojo-verde. Cuando sientes el beneficio de ese ritmo, has comenzado a "obtenerlo". Eso no quiere decir que valdrá la pena en todos los casos, pero hasta que sienta ese ritmo no ha llegado a lo que sus partidarios le dicen al respecto.

Y generalmente hay (especialmente en aplicaciones arquitectónicamente complicadas, como aplicaciones n-tier) cierta cantidad de diseño inicial. Nada esbozado en piedra, pero suficiente para darles a las unidades un lugar adonde ir. Por supuesto, la arquitectura puede evolucionar en una metodología ágil, pero una idea general del paisaje debe estar allí si hay múltiples capas de la arquitectura.

EDITAR: (En respuesta al comentario). ¿Debería probarse la nueva clase por sí misma? No necesariamente.Depende si la clase desarrolla una importancia propia. Cuando está realizando pruebas unitarias, está probando una funcionalidad. No es una prueba de integración solo porque hay dos clases involucradas. Se convierte en una prueba de integración cuando dos unidades comienzan a interactuar. El límite en el que normalmente pienso es si tengo que configurar un estado significativo en el grupo de clases A para interactuar con el grupo de clases B, y especialmente si el grupo de clases A llama al grupo de clases B y qué Estoy interesado en probar cómo reaccionó B ante A, entonces estoy viendo una prueba de integración.

+1

Pero la (s) nueva (s) clase (s) deberían probarse por sí mismas, ¿o no? Si el diseño lo lleva al punto donde le gustaría crear múltiples clases de "soporte", la prueba de unidad con la que comenzó se está convirtiendo en una prueba de integración. –

1

Debería crear una clase simulada. Una única interfaz con retults predecibles. Entonces puedes probar el original.

Más adelante, puede repetir el procedimiento con la nueva clase.

+1

En realidad, esto es lo que creo que debería hacer, pero existe una guerra santa sobre las pruebas basadas en el estado y las basadas en la interacción. No me gusta el hecho de que esta solución vincule sus pruebas a una declaración particular de una interfaz que utiliza. En las pruebas basadas en estado, puedo cambiar la declaración de interfaz de la clase de soporte (lo más probable) sin tener que cambiar mis pruebas. Usando pruebas basadas en la interacción, también tengo que cambiar los testcases. –

2

Cuando me encuentro con esta situación, sigo su solución n. ° 1. Siga recurriendo, haciendo tantas clases como considere apropiadas, hasta que tenga una colección de implementaciones con las que esté satisfecho. Con la experiencia, descubrirá que sus diseños reflejan su experiencia, y este tipo de cosas no sucederá tanto.

+0

Eso es más o menos lo que estoy haciendo ahora, pero no me gusta el hecho de que te distrae de la clase que estabas probando. Después de un tiempo vuelves a esa clase y tratas de descubrir de dónde te fue. –

+1

Como dijo Yishai, no deberías pensar en términos de pruebas de clases. Está probando implementaciones de soluciones a problemas, y si la implementación abarca varias clases, está bien. –

6

El problema que tengo es que cuando llego al punto 6 & 7, en algún momento en el tiempo invariablemente llegado a la conclusión que la aplicación Me acabo de escribir debe ser delegada a otra clase.

Realizar su diseño sería mejor con una clase diferente, eso es diseño, y ese es el objetivo de TDD. Entonces es algo bueno, y no debería molestarte.

Pero te está molestando. ¿Entonces lo que hay que hacer? Reconocer que delegar en otra clase es una refactorización; esto es algo por hacer después de paso 6, durante el paso 7. Una vez que esté verde, refactorícese a un mejor diseño. Ya tienes las pruebas para la nueva clase; solo están conectados para llamar a la clase original. Eso está perfectamente bien. Después de extraer la clase y delegar, si se sentiría más cómodo con las pruebas, llame directamente a la clase extraída: vaya por ella. Sin daño. Si la clase extraída comienza a ser utilizada por otras personas que llaman, la recomendaría, y tal vez cuando comiences a llamarla desde otras clases es un buen momento para hacerlo (pero si te molesta ahora, hazlo ahora).

+0

Muy pragmático, gracias. –

Cuestiones relacionadas