unitarias pruebas por guiado ejemplo desarrollo comportamiento atdd java unit-testing junit tdd bdd

java - pruebas - tdd vs bdd



Desarrollo guiado por pruebas: cómo escribir una prueba antes de que no exista ningún código de implementación (4)

Cree la clase EnrollingServiceTest en src / test / java en el mismo paquete que EnrollingService

class EnrollingServiceTest { private EnrollingService enrollingService; @Before public void init() { enrollingService = new EnrollingService(); } @Test public void testEnroll() { boolean result = enrollingService.enroll(1l, 1l); assertTrue(result); ...

IDE (Supongo que usted está utilizando IDE) muestra errores: EnrollingService no existe.

Cursor de punto en EnrollService - IDE ofrecerá crear una clase - déjelo crear en src / main / java

Ahora el IDE dice que falta el método de inscripción (largo, largo); deje que el IDE lo cree por usted.

Ahora IDE no muestra errores. Ejecutar la prueba - falla Ve a inscribirte y empieza a implementar la lógica.

Y así...

Estoy aprendiendo TDD pero luchando por adoptarlo ya que no es sencillo.

La pregunta que no puedo responder es " ¿Cómo escribir una prueba antes de que exista algún código de implementación? ".

Si nuestra clase de destino / método de destino / tipo de parámetro de destino / tipo de retorno de destino no existe,

  • ¿A qué nos referimos al escribir código en la prueba? ¿Cómo empezamos a escribir la prueba?
  • ¿Cómo falló la prueba si todo lo que pudiéramos escribir es solo el nombre del método de prueba antes del código de implementación real?

Todos dicen POR QUÉ pero no CÓMO

Hice lo mejor que pude para encontrar recursos que elaboren las pruebas de escritura antes del código de producción, pero, suponiendo que perdí buenos recursos, la mayoría están llenos de clichés que explican por qué es importante el TTD que centrarse en las prácticas para adoptarlo.

Un ejemplo de caso de uso.

Supongamos que estamos desarrollando un software para una universidad y nuestro caso de uso es el registro de cursos.

Para que sea sencillo, confinemos esta discusión a

  • Escenario: "Un estudiante puede inscribirse en un máximo de 3 cursos por semestre"
  • Prueba de la capa de servicio y la capa dao.

Pseudocódigo

ENROLL(studentId, courseId) //check if student enrolled in less than 3 courses in the same semester as given courseId belongs in. //if yes, enroll him/her. //if not, return an error.

La implementación real de lo anterior podría abarcar un par de clases que involucran servicios, daos, etc.

Por favor, ¿podría explicar cómo realizar una prueba de desarrollo para desarrollarlo paso a paso? Si implementaras esto usando TDD, ¿cómo lo hiciste paso a paso?

Espero que esto pueda ayudar a muchas luchas como yo en el futuro.


En su escenario, debe probar cada capa por separado, por lo que debe imitar al dao al probar la capa de servicio.

La primera vez que escribe la prueba no se compilará, lo que significa que falla, pero eso está bien ya que las clases no existen.

En su ejemplo, ¿qué capa debe hacer cumplir para registrarse en un máximo de 3 cursos? Eso afectará a cómo te pruebas.

Escribir el examen primero te ayudará a resolver este tipo de preguntas.

Como se mencionó, esto es demasiado abierto para una respuesta definitiva, pero si comienza a escribir su prueba y luego publique como una actualización, podría ayudar.

Entonces, escriba su prueba dao, luego escriba las clases y los métodos para que se compile, pero aún así debería fallar hasta que finalice la implementación. Probablemente querrá probar para 2,3,4 registros de clase y asegurarse de que cada uno falla correctamente, luego finalice la implementación.


Esto se hará más claro cuando se centre en el comportamiento esperado del código en lugar de la implementación del código. Entonces, dado el escenario que describiste, puedes llegar a la conclusión de que tendrás que escribir el método de inscripción () en alguna clase. Luego puedes considerar cómo vas a probar esta clase.

Usted comienza considerando las condiciones de la clase y lo que se espera de ella. Tal vez puedas identificar ciertos invariantes de la clase. En ese caso, para probar la clase, se consideran las formas en que se puede violar ese invariante.

Así que tomando la declaración: un estudiante puede inscribirse para un máximo de 3 cursos por semestre, usted considera las formas en que esto puede ocurrir.

  1. El estudiante está registrado para 0 cursos para el semestre dado, intentar registrarse para un curso, resultado: registro exitoso; el estudiante ahora está registrado para 1 curso para el semestre dado.
  2. El estudiante está registrado para 1 curso por semestre determinado, intenta registrarse para un curso, resultado: registro exitoso; El estudiante ahora está registrado para 2 cursos para el semestre dado.
  3. El estudiante está registrado para 3 cursos para el semestre dado, intenta registrarse para un curso, resultado: ¿Fallo (quizás se lanza una excepción?)
  4. etcétera etcétera

A continuación realmente escribe estas pruebas. Cada uno de estos puede ser un método de prueba. Por lo tanto, el método de prueba aseguraría que los objetos se crean y el entorno se configura como se espera. Luego llame al método y compare el resultado con el resultado esperado. Si lo que esperas que pase realmente sucede, entonces la prueba pasó.

Ahora, inicialmente, como todavía no escribiste el método, las pruebas no pasarán. Pero a medida que comienza a escribir el código, sus pruebas comenzarán a aprobarse y, finalmente, pasará el 100% de sus pruebas, momento en el que está satisfecho de que su código cumple con los requisitos.


public void shouldNotEnrollInMoreThanFourClassesInASemester() { Enroller enroller = new Enroller(); Student student = new Student(); Semester one = new Semester(); Semester two = new Semester(); Course geology = new Course(one); Course architecture = new Course(one); Course calculus = new Course(one); Course sociology = new Course(one); Course geometry = new Course(two); assertOk(enroller.enroll(student, geology)); assertOk(enroller.enroll(student, architecture)); assertOk(enroller.enroll(student, calculus)); assertNotOk(enroller.enroll(student, sociology)); assertOk(enroller.enroll(student, geometry)); }