Estoy aprendiendo TDD usando c #, por lo que sé, la prueba debería impulsar el desarrollo , es decir, primero escribir una prueba fallida después de escribir el código mínimo para pasar la prueba y luego refactorizar.
Pero también se dice que " Programa a la interfaz, no a la implementación ", así que primero escribe una interfaz . Aquí es donde comienza mi confusión, si estoy escribiendo Interface primero, entonces está violando dos cosas
El código que está escrito para la interfaz no está controlado por la prueba .
No es lo mínimo, obviamente, puedo escribirlo con una clase simple.
¿Debo comenzar escribiendo pruebas para la interfaz también? sin ninguna implementación, ¿qué voy a probar?
Si esta pregunta suena tonta, perdón por eso, pero estoy completamente confundido. Puede ser que estoy tomando las cosas demasiado literalmente.
fuente
interface
para todo. Aclass
también proporciona una interfaz, porque puede ocultar detalles de implementación enprivate
variables.contract
. Esto podría ser en forma de una clase abstracta, por ejemplo, aunque no debería ser una clase / método virtual porque no debería ser capaz de crear una instancia.Respuestas:
Su primera infracción ("El código que se escribe para la interfaz no se controla mediante prueba") no es válido. Usemos un ejemplo trivial. Supongamos que está escribiendo una clase de calculadora y está escribiendo una operación de suma. ¿Qué prueba podrías escribir?
Su prueba acaba de definir la interfaz. Es el
add
método, ¿ves?add
toma dos argumentos y devuelve su suma. Posteriormente, puede determinar que necesita varias calculadoras y extraer una interfaz Java (en este caso) en ese momento. Sus pruebas no deberían cambiar entonces, ya que probó la interfaz pública de esa clase.En un nivel más teórico, las pruebas son la especificación ejecutable de un sistema. Las interfaces con un sistema deben ser conducidas por los usuarios de ese sistema, y las pruebas son el primer método que tiene para definir interacciones.
No creo que pueda separar el diseño de la interfaz del diseño de prueba. Definir interacciones y diseñar pruebas para ellas es la misma operación mental: cuando envío esta información a una interfaz, espero un cierto resultado. Cuando algo está mal con mi entrada, espero este error. Puede hacer este trabajo de diseño en papel y luego escribir sus pruebas a partir de eso, o puede hacerlos al mismo tiempo, realmente no importa.
fuente
new Calculator()
es correcta la implementación? Si se necesita una nueva implementación, ¿tal vez harías un MultiplicationCalculator y tendrías que cambiar la pruebanew AdditionCalculator()
para que todavía se apruebe? O me estoy perdiendo algo ?¿Qué estamos haciendo cuando escribimos un
interface
? ¿Estamos escribiendo código o estamos diseñando?No soy fanático de la noción de Test Driven Design, pero me encanta Test Driven Development . Personalmente, obtuve mis mejores resultados cuando diseño la clase por adelantado al diseñar la interfaz antes de escribir una prueba. No cuento la interfaz como código. La interfaz es un diseño que implementaré usando TDD. Es probable que cambie y evolucione a medida que trabajo, pero es mi hoja de ruta (junto con mi lista de pruebas).
Me detendré antes de comenzar a despotricar, pero espero que sea una forma útil de pensarlo.
fuente
Todo depende de qué tan ortodoxo / religioso quieras hacer TDD .
Como está aprendiendo, debe experimentar para obtener un flujo de trabajo personal, que funcione para usted.
Si desea hacerlo de acuerdo con los libros , primero escribe una prueba, que obviamente fallará, porque está comenzando sin ningún código. Luego escribes un código para pasar la prueba. Si se hace eso, puede refactorizar el código existente, ya que tiene una prueba que proporciona algún tipo de red de seguridad para las refactorizaciones. Decidir usar una interfaz es algún tipo de refactorización.
Además de TDD o no: la pregunta, si usar una interfaz o no, no es interesante en primer lugar. Por supuesto, si está seguro, tiene un comportamiento diferente que desea difundir entre varios objetos, tiene sentido pensar en usar una interfaz: por ejemplo, si tiene algún tipo de salida a diferentes destinos, tiene sentido implementarlo a través de un escritor de interfaz y tiene diferentes clases para la salida ( FileWriter , Printer , etc.). Aunque es un dicho común escribir en una interfaz , eso no significa: usar una interfaz para todo . A veces es un nivel de indirección a mucho. Por cierto. Lo mismo ocurre con los servicios. Pero ese es un tema diferente.
Por otro lado, podría desarrollar pruebas conducidas de otra manera: diseñe su código para la comprobabilidad. Lo que significa, que escriben el código, que es fácil de prueba - aunque se escriben las pruebas después . No importa si escribe pruebas de antemano o después, siempre y cuando lo haga de todos modos.
fuente
TDD o BDD significaría primero hacer sus interfaces de dominio y luego escribir pruebas contra ellas según mi interpretación. La implementación de una interfaz tiene un comportamiento esperado.
todavía es una prueba antes del código porque una interfaz no contiene una lógica comprobable, es la estructura contra la que escribe una prueba.
Lo haría de la siguiente manera
Escriba el comportamiento semi formal (dado: cuándo: entonces :)
Escribir la interfaz (al método de encapsulación del comportamiento del host)
Escriba la prueba que identifica (ingrese el dado, llame al cuándo, pruebe el entonces)
Escribir / alterar el concreto (clase que implementa la interfaz) para pasar la prueba
fuente
Nunca escriba pruebas antes de haber diseñado las interfaces. Cuando esté pensando en qué tipos de pruebas escribir (diseño de prueba), no debería también diseñar (diseñar) su aplicación simultáneamente. No pienses en dos cosas al mismo tiempo. ¿Has oído hablar de la separación de las preocupaciones? Se aplica no solo a la estructura física de su código sino también a su proceso de pensamiento.
Decida cómo se debe diseñar primero su aplicación. Esto significa que diseña tus interfaces y las relaciones entre estas interfaces. Hasta que haya hecho esto, no debe comenzar a pensar en las pruebas. Una vez que sepa cuáles son sus interfaces, puede crearlas primero y luego escribir pruebas contra ellas o escribir pruebas primero y luego crearlas. En este último caso, obviamente no podrá compilar las pruebas. No veo ningún daño ni ninguna violación de la filosofía TDD al crear las interfaces antes de las pruebas.
fuente
interface
palabra clave C # , no al término general "interfaz".Está bien escribir la interfaz / código / prueba al mismo tiempo siempre que su incorporación al proyecto sea atómica.
A menos que su jefe sea religioso sobre TDD, en cuyo caso probablemente tenga que escribir una interfaz vacía -> prueba -> código mínimo (paso sin sentido) -> más pruebas -> más código sin sentido -> más pruebas -> finalmente escriba el código real - > hecho.
fuente