¿Cuáles son las escuelas de TDD en Londres y Chicago?

88

He estado escuchando sobre el estilo de Londres frente al estilo de Chicago (a veces llamado estilo de Detroit) de Test Driven Development (TDD).

Taller del grupo de usuarios de Utah Extreme Programming:

El estilo de interacción TDD también se llama estilo burlón o estilo londinense después del club Extreme Tuesday de Londres, donde se hizo popular. Suele contrastarse con el TDD clásico o al estilo de Detroit, que se basa más en el estado.

Taller de Jason Gorman :

El taller cubre tanto la escuela de TDD de Chicago (pruebas de comportamiento y triangulación basadas en el estado) como la escuela de Londres , que se enfoca más en las pruebas de interacción, burlas y TDD de extremo a extremo, con énfasis particular en el diseño basado en la responsabilidad y el Enfoque Tell, Don't Ask para OO recientemente re-popularizado por el excelente libro Crecimiento orientado a objetos de Steve Freeman y Nat Pryce Libro guiado por pruebas .

¿El post TDD clásico o "London School"? Jason Gorman fue útil, pero sus ejemplos me confundieron, porque usa dos ejemplos diferentes en lugar de uno con ambos enfoques. ¿Cuáles son las diferencias? ¿Cuándo usas cada estilo?

Arturo Herrero
fuente

Respuestas:

76

Suponga que tiene una clase llamada "libro mayor", un método llamado "calcular" que usa una "Calculadora" para hacer diferentes tipos de cálculos dependiendo de los argumentos pasados ​​para "calcular", por ejemplo, "multiplicar (x, y)" o "restar ( x, y) ".

Ahora, suponga que desea probar lo que sucede cuando llama a ledger.calculate ("5 * 7").

La escuela de Londres / Interacción le indicará si se llamó a Calculator.multiply (5,7). Los diversos marcos de simulación son útiles para esto, y puede ser muy útil si, por ejemplo, no tiene la propiedad del objeto "Calculadora" (suponga que es un componente o servicio externo que no puede probar directamente, pero sí Sabe que tiene que llamar de una manera particular).

La escuela de Chicago / State le indicará si el resultado es 35. Los marcos de jUnit / nUnit generalmente están orientados a hacer esto.

Ambas son pruebas válidas e importantes.

Matthew Flynn
fuente
Muy buen ejemplo.
sevenseacat
1
Agregaré algunas razones más para usar cada una: si lo importante es determinar que algo ha cambiado o no en función de la acción que se está tomando (por ejemplo, ledger.bucket.value se convierte en 35 cuando ledger.calculate ("5 * 7 ") se llama), desea utilizar afirmaciones de estado (escuela de Chicago). Esto es más útil cuando tiene control total sobre el estado del sistema antes de que se llame al método, y cuando realmente controla lo que hace el método.
Matthew Flynn
1
Si lo importante es saber que se llama un segundo método (por ejemplo, Calculator.multiply (5, 7)), desea utilizar aserciones de actividad, como a través de un objeto simulado. Esto es más útil si el método que se llama tiene un efecto secundario deseado (por ejemplo, guardar datos, incrementar un contador, enviar un mensaje, etc.) si no controla realmente lo que hace el método, por lo que el valor de retorno puede ser inconsistente . Además, si no puede controlar fácilmente el estado del sistema, lo mejor que puede hacer es determinar qué actividades ocurren.
Matthew Flynn
El enfoque de Londres es útil cuando la clase Calculadora es potencialmente larga por alguna razón, o involucra una red y, por lo tanto, puede ser inestable en las configuraciones de dev / qa. Es decir, la burla permite que sus pruebas sean rápidas y confiables en casos en los que de otra manera no sería posible.
Kevin
1
El enfoque de Londres también argumenta que proporciona señales de retroalimentación más claras, porque si Calculatorregresa multiply, verá que dos pruebas fallan: la prueba del libro mayor y la prueba de la calculadora, pero solo una prueba falla si se burla de la calculadora. Eso podría facilitar la localización del origen del error, especialmente si el sistema es complejo.
Matthias
30

El artículo Las burlas no son trozos , de Martin Fowler, es una buena introducción al tema.

Dependiendo del estilo de diseño que elija (y los principios de diseño sobre los cuales construye sus programas), existen al menos dos formas de ver un objeto:

  1. Como una unidad que realiza cálculos basados ​​en entradas. Como resultado de este cálculo, el objeto puede devolver un valor o cambiar su estado.
  2. Como un elemento activo que se comunica con otros elementos en el sistema al pasar mensajes.

En el primer caso, está interesado en lo que sale del procesamiento o en qué estado queda el objeto después de ese procesamiento. Aquí es donde los métodos como assertEquals()ingresar la imagen. En este caso, no importa mucho qué otros objetos estuvieron involucrados en el procesamiento, qué métodos se llamaron, etc. Este tipo de verificación se llama verificación basada en estado y es el estilo "clásico".

En el segundo caso, dado que la mayoría de los objetos ni siquiera devuelven ningún resultado (por ejemplo, voidmétodos en Java), está más interesado en cómo los objetos se comunican entre sí y si pasan los mensajes correctos en las circunstancias impuestas por la prueba. Estas interacciones generalmente se verifican con la ayuda de marcos simulados. Este tipo de verificación se denomina verificación basada en el comportamiento o en la interacción. Una de sus implicaciones es la técnica llamada Behavior Driven Development, mediante la cual se desarrolla una clase suponiendo que sus colaboradores ya existen (aunque todavía no existan), por lo que puede codificar contra sus interfaces.

Tenga en cuenta que esta no es una opción o una opción. Puede tener un estilo de diseño que combine ambos enfoques para obtener lo mejor de cada uno.

Otavio Macedo
fuente