¿Se puede aplicar la metodología TDD de arriba a abajo?

13

No estoy claro cómo TDD, la metodología, maneja el siguiente caso. Supongamos que quiero implementar el algoritmo mergesort, en Python. Comienzo escribiendo

assert mergesort([]) === []

y la prueba falla con

  

NameError: el nombre 'mergesort' no está definido

Luego agrego

def mergesort(a):
    return []

y mi prueba pasa. A continuación agrego

assert mergesort[5] == 5

y mi prueba falla con

  

AssertionError

con el que hago pasar

def mergesort(a):
    if not a:
        return []
    else:
        return a

A continuación, agrego

assert mergesort([10, 30, 20]) == [10, 20, 30]

y ahora tengo que intentar hacer este pase. Yo "sé" el algoritmo mergesort así que escribo:

def mergesort(a):
    if not a:
        return []
    else:
        left, right = a[:len(a)//2], a[len(a)//2:]
        return merge(mergesort(left)), mergesort(right))

Y esto falla con

  

NameError: el nombre 'merge' no está definido

Ahora aquí está la pregunta. ¿Cómo puedo ejecutar y comenzar a implementar merge utilizando TDD? Parece que no puedo porque tengo esta prueba "colgada" no cumplida, fallida para mergesort , que no pasará hasta que merge haya terminado. Si esta prueba se cuelga, puedo nunca hago TDD realmente porque no seré "verde" durante mis iteraciones TDD construyendo merge .

Parece que estoy atascado con los siguientes tres escenarios feos, y me gustaría saber (1) cuál de estos prefiere la comunidad de TDD, o (2) ¿hay otro enfoque que me esté perdiendo? ¡He visto varios tutoriales de Uncle Bob TDD y no recuerdo haber visto un caso como este antes!

Aquí están los 3 casos:

  1. Implementar la fusión en un directorio diferente con un conjunto de pruebas diferente.
  2. No te preocupes por ser verde cuando desarrolles la función de ayuda, simplemente realiza un seguimiento manual de las pruebas que realmente quiere aprobar.
  3. Comente fuera (¡GASP!) o elimine las líneas en mergesort que llaman a merge ; luego, después de hacer que merge funcione, vuelva a colocarlos.

Todo esto me parece tonto (¿o estoy viendo esto mal?). ¿Alguien sabe el enfoque preferido?

    
pregunta Ray Toal 09.11.2016 - 20:19

1 respuesta

12

Aquí hay algunas formas alternativas de ver sus opciones. Pero primero, las reglas de TDD, de tío Bob con énfasis por mí:

  1. No se le permite escribir ningún código de producción a menos que sea para hacer una prueba de prueba fallida.
  2. No se le permite escribir más de una prueba de unidad de lo que es suficiente para fallar; y las fallas de compilación son fallas.
  3. No se le permite escribir más código de producción del que es suficiente para pasar la prueba de la unidad que falla.

Entonces, una forma de leer la regla número 3 es que necesita la función merge para pasar la prueba, para que pueda implementarla, pero solo en su forma más básica.

O, alternativamente, comienza escribiendo la operación de combinación en línea y luego la refactorizas en una función después de hacer que la prueba funcione.

Otra interpretación es que estás escribiendo mergesort, sabes que necesitarás una operación merge (es decir, no es YAGNI, que es lo que la regla "suficiente" intenta restringir). Por lo tanto, debería haber comenzado con las pruebas para la combinación, y solo entonces se procedió a las pruebas para la clasificación general.

    
respondido por el kdgregory 09.11.2016 - 20:46

Lea otras preguntas en las etiquetas