2010-08-18 16 views
5

Sé que esta pregunta es parte de una guerra religiosa, pero tengo la siguiente situación: Tengo un objeto, Responder que llama a un método en el objeto Updater en respuesta a diferentes eventos. Recientemente separaron las pruebas de esta manera: pruebas basadas en estado para el método Updater en sí mismo, y pruebas basadas en el comportamiento para el Responder que lo llama. Es decir, me burlo del Updater en las pruebas Responder, solo para asegurarme de que se llame.Comportamiento vs. Pruebas basadas en el estado

¿Debería seguir probando el estado de los objetos que se supone deben actualizarse en las pruebas Responder y no burlarme del Updater? Me gusta lo que hice porque requiere menos configuración y parece aislar mejor las pruebas. Sin embargo, esto parece vincular la implementación y el comportamiento esperado de Responder a Updater. ¿Eso es muy frágil? Este es un ejemplo simplificado.

+0

¿Qué tipo de pruebas será satisfactoria aumentar su nivel de comodidad que funciona el código? ¿Sería suficiente una prueba de integración? –

+0

Supongo que una prueba de integración que lo vincule todo aumentará mi confianza. Sin embargo, también me gustaría saber si las personas piensan que esta es una forma válida de probar a nivel de unidad. –

Respuesta

8

Si yo he entendido bien su pregunta, se necesita al menos dos niveles de comprobación:

  1. Las pruebas unitarias, en las que están tratando de probar una sola clase y simulacros de todas las dependencias (por lo que en su caso El actualizador debe ser burlado aquí). Estas pruebas lo ayudan a desarrollar el código (especialmente si está usando TDD), asegúrese de que la clase se comporte como se diseñó e incluso documente cómo se comportará esta clase. Casi todas las clases deberían tener pruebas unitarias. Sin embargo, como notó, incluso si tiene una cobertura del 100% de prueba, ¡no tiene garantía de que su programa funcione o incluso se inicie!

  2. Pruebas de aceptación, integración y extremo a extremo: estas pruebas cubren toda la aplicación o los módulos grandes y prueban que todo funciona en conjunto. En general, no se utilizan simulaciones en este nivel (aunque es posible que resida un módulo/servicio web completo, según el contexto). Estas pruebas no tienen que probar todos los detalles de implementación (y no deberían), porque esto se hace mediante pruebas unitarias. Se aseguran de que todo esté correctamente conectado y trabajando en conjunto. En tu caso, no te burlarás de Updater aquí.

En resumen, creo que realmente necesita hacer ambas cosas para que su aplicación sea probada adecuadamente.

0

Supongo que depende de qué/cómo está intentando probar.

Si no tiene ninguna dependencia en la clase Updater, no hay otra manera que probar su estado después de llamar al método bajo prueba. Si hay alguna dependencia, puede probar su comportamiento en cuanto a lo que debería hacer (llamar a otros métodos en otras clases)

La otra opción también podría ser cierto para la clase Responder. Podrías probar su estado o puedes probar su comportamiento como lo hiciste ahora. Probando su estado, probablemente usará la implementación real del Actualizador y no se burlará de él, o usará un talón en su lugar que hace solo lo mínimo.

Cuando mayormente se prueba el comportamiento y se burla de muchas cosas, sería aún más necesario tener pruebas de aceptación (regresión/integración/extremo a extremo) para respaldar las pruebas unitarias, como menciona Grzenio. (Parece que es un probador "mockist" (de comportamiento))

Cuando se realizan pruebas basadas en estado principalmente, se usan implementaciones más reales y su interacción y la necesidad de respaldarlas es menos relevante. Pero de ninguna manera es una manera de descartarlos por completo, es solo que ya tiene alguna regresión/integración en sus pruebas.

creo que no se debe dividir las pruebas hasta demasiado, ya que puede hacer que sea más fácil que las cosas caigan entre las grietas.

Negación: No soy un gurú de TDD y yo no defiendo una sobre la otra. Se puede encontrar buena información sobre el comportamiento clásico vs en la red. Martin Fowler tiene un buen punto de partida sobre el tema: Mocks Aren't Stubs

Actualmente estoy leyendo Growing Object Oriented Software, Guiado por Tests y estoy inclinado hacia el lado mockist de la valla. Pero creo que hay una pequeña área gris en ambos lados.

Cuestiones relacionadas