La metodologia TDD può essere applicata dall'alto verso il basso?

13

Non sono chiaro in che modo TDD, la metodologia, gestisce il caso seguente. Supponiamo di voler implementare l'algoritmo del mergesort, in Python. Comincio scrivendo

assert mergesort([]) === []

e il test fallisce con

NameError: name 'mergesort' is not defined

Quindi aggiungo

def mergesort(a):
    return []

e il mio test passa. Successivamente aggiungo

assert mergesort[5] == 5

e il mio test fallisce con

AssertionError

che faccio passare con

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

Successivamente, aggiungo

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

e ora devo provare a fare questo passaggio. Io "conosco" l'algoritmo del mergesort così scrivo:

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

E questo fallisce con

NameError: name 'merge' is not defined

Ora ecco la domanda. Come posso iniziare a implementare merge usando TDD? Sembra che non ci riesca perché ho questo test "in sospeso" non riuscito, non riuscito per mergesort , che non passerà fino a quando merge è terminato! Se questo test si blocca, posso mai veramente fare TDD perché non sarò "verde" durante le mie iterazioni TDD costruendo merge .

Mi sembra di essere bloccato con i seguenti tre brutti scenari e vorrei sapere (1) quale di questi preferisce la comunità TDD, oppure (2) c'è un altro approccio che mi manca? Ho visto diverse procedure dettagliate di Uncle Bob TDD e non ricordo di aver visto un caso come questo prima d'ora!

Ecco i 3 casi:

  1. Implementare l'unione in una directory diversa con una suite di test diversa.
  2. Non preoccuparti di essere verde quando sviluppi la funzione di aiuto, tieni traccia dei test che veramente vorranno veramente passare manualmente.
  3. Commenta (GASP!) o elimina le righe in mergesort che chiamano merge ; poi, dopo aver ottenuto merge a lavorare, rimettili in.

Mi sembrano tutte sciocche (o sto guardando questo sbagliato?). Qualcuno conosce l'approccio preferito?

    
posta Ray Toal 09.11.2016 - 20:19
fonte

1 risposta

12

Ecco alcuni modi alternativi di guardare le tue opzioni. Ma prima, le regole di TDD, da Uncle Bob con enfasi da parte mia:

  1. Non sei autorizzato a scrivere alcun codice di produzione a meno che non si debba effettuare un passaggio di prova dell'unità in errore.
  2. Non è consentito scrivere più di un test unitario di quanto sia sufficiente per fallire; e gli errori di compilazione sono errori.
  3. Non ti è permesso scrivere altro codice di produzione di quanto sia sufficiente per superare il test dell'unità in mancanza.

Quindi, un modo per leggere la regola numero 3 è che hai bisogno della funzione merge per superare il test, quindi puoi implementarlo, ma solo nella sua forma più semplice.

Oppure, in alternativa, si inizia scrivendo l'operazione di fusione in linea e quindi si esegue il refactoring in una funzione dopo aver eseguito il test.

Un'altra interpretazione è che stai scrivendo un mergesort, sai che avrai bisogno di un'operazione merge (cioè, non è YAGNI, che è ciò che la regola "sufficiente" tenta di ridurre). Pertanto, avresti dovuto iniziare con i test per l'unione e solo dopo proceduto ai test per l'ordinamento generale.

    
risposta data 09.11.2016 - 20:46
fonte

Leggi altre domande sui tag