Nello sviluppo basato su test, ci sono buone ragioni per non scrivere più test falliti e solo per farli passare?

7

Le tre regole dello sviluppo basato sui test dello zio Bob indicano quanto segue:

  1. You are not allowed to write any production code unless it is to make a failing unit test pass.
  2. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
  3. You are not allowed to write any more production code than is sufficient to pass the one failing unit test.

Alcune persone sostengono che la seconda regola implica che tu debba sempre aggiungere solo un test in errore (un esempio di comportamento isolato). Ma altri sostengono che potrebbe anche significare che potresti aggiungere più test falliti in una suite di test, a patto che tu smetta di lavorare su ciascun test separato non appena fallisce.

Vorrei sapere quali vantaggi si ottengono limitando te stesso alla scrittura di un solo nuovo test fallito e quindi interrompi la scrittura del codice test fino a quando non lo hai superato.

    
posta aef 11.04.2016 - 21:14
fonte

3 risposte

9

Quando si scrivono due test contemporaneamente e si inizia a implementare il codice per eseguire il primo test, non è possibile eseguire l'intera suite di test e ottenere un risultato "verde", perché il secondo test fallirà ancora. Puoi vedere l'output dettagliato del tuo framework di test unitario e verificare visivamente che il test abbia avuto esito negativo, naturalmente, ma che potrebbe diventare ingombrante e soggetto ad errori, specialmente quando il numero di test unitari inizia a crescere . E se, ad esempio, hai un sistema CI installato con una regola che non deve essere verificato alcun test non funzionante, perché i test non validi contano come build non funzionanti, significa che non puoi controllare il tuo codice finché non hai implementato abbastanza codice da rendere tutti i test passano.

Si noti che questo è un modello idealizzato, è fatto per allenarsi a lavorare nel più piccolo passo possibile, offrendo un programma compilabile e completamente testato ogni pochi minuti. L'idea è che più piccoli sono i passaggi da uno "stato completamente funzionante" a un altro, meglio è possibile controllare il processo.

Naturalmente, quando si esegue la "programmazione del mondo reale", se si preferisce, è possibile scegliere qualsiasi ordine di implementazione di test e codice di produzione desiderato, quando si ritiene che i passaggi più grandi si adattino meglio alle proprie esigenze. Tuttavia, quando lavori in questo modo, potrebbe essere una buona idea disattivare o commentare esplicitamente qualsiasi test che hai scritto in anticipo fino a quando non inizi a lavorare sulla parte relativa del codice di produzione.

    
risposta data 11.04.2016 - 21:53
fonte
6

Il motivo per rimanere con un test dell'unità in errore alla volta è l'attenzione. Quando hai quel singolo test unitario fallito, sai esattamente su cosa lavorare; sai a quale parte del codice pensare; sai quale problema stai risolvendo immediatamente. Se ti permetti di scrivere più test mentre lavori sulla risoluzione di un problema, molto presto risolverai due - o cinque o dieci - problemi, e con quella mancanza di concentrazione, non stai davvero risolvendo nulla.

Con ogni mezzo, mentre scopri ulteriori necessità di test, anche mentre il tuo test sta ancora fallendo: prendine nota. Controlla i tuoi appunti dopo aver fatto passare il test e sceglierne uno su cui lavorare mentre è ancora fresco nella tua mente. Ma se scrivi quel test di fallimento aggiuntivo prematuramente, ti allontani di più dal verde, e non vuoi essere lontano da quello stato.

Inoltre, se ritieni di aver bisogno di test aggiuntivi, lascia che questa sensazione ti guidi a scrivere test più piccoli per cominciare.

Questo è il dogma di base del TDD; in pratica molti di noi occasionalmente lo violano e scrivono quel secondo test negativo. Ma quando siamo al meglio, è solo un test fallito alla volta, e il focus è il motivo.

    
risposta data 11.04.2016 - 21:55
fonte
0

Fai i tuoi progetti, sei libero di scrivere quanti test vuoi, ma la mia esperienza nel business reale è che i test o il refactoring sono requisiti non funzionali solo secondo la tua opinione e il tuo cliente deve pagare per il tempo hai bisogno di scrivere i tuoi test. Sebbene un test sia parte integrante di ogni problema nel tuo progetto, non dovrebbe essere esagerato.

È la stessa discussione su quanti test unitari assicurano la qualità del mio software rispetto a un buon test di integrazione? Pensa alle parole di Uncle-Bob che testano una classe modello:

  • (test) "dovrebbe restituire un messaggio": model = new NewsModel()
  • (test non riuscito) NewsModel non definito
  • (impl fixes test) class NewsModel {}
  • (test) model.getMessage()
  • (test fallito) NewsModel::getMessage non definito
  • (impl fixes test) public getMessage() {}
  • ...

Non sono d'accordo con quel rigoroso red / green / refactor poiché un buon test di integrazione dovrebbe rivelare un comportamento scorretto e non credo che sia intenzione dello zio Bob di scrivere i test dei modelli in quel modo. Il messaggio è solo che non ti devi perdere nelle ore di test, ma scrivi buoni test e almeno non esegui test a doppio test.

Se riesci a formare ogni piccolo requisito del tuo cliente in un test, spedirai un software eccezionale, se la tua implementazione farà passare i test. Stessa cosa con i bug: scrivi un test che lo riproduce (rosso), poi aggiustalo (verde) e almeno rifattalo.

E ora di nuovo alla tua domanda: Avendo un solo test fallito, isola quel comportamento scorretto garantendo nel contempo che tutti gli altri componenti si comportino correttamente. Se stai provando a risolvere il problema e poi due test falliscono, potresti andare nella direzione sbagliata.

    
risposta data 12.04.2016 - 00:35
fonte

Leggi altre domande sui tag