TDD è non design - è un processo di progettazione.
Un artefatto principale che un processo TDD alla fine ti dà sono le suite di test unitari, che dovrebbero (in una certa misura) attestare l'ambito e le capacità del codice reale.
Le buone suite di test assicurano che il codice funzioni e hanno aggiunto la sicurezza che le future modifiche al codice possono essere apportate senza rompere il codice passato, poiché i test non riusciti impediscono la fuoriuscita di codice nel sistema.
Quindi, se vuoi valutare una suite di test scritta durante TDD dovresti cercare:
La leggibilità
I test dovrebbero essere letti facilmente. Dovrebbe essere ovvio cosa fa ogni test.
Una buona suite di test descrive la funzionalità del codice come un PRD (Product Requirement Documents), fino ai casi limite.
Prova che non puoi capire quello che fanno, sono confusi, pieni di "numeri magici", lunghe code, flusso illogico, obiettivi vaghi sono cattivi. Tra poche settimane nessuno ricorderà il loro scopo, e quando si romperanno, nessuno potrà né perché né come risolverli, e saranno cancellati dal codice base, o peggio ancora - semplicemente ignorati, e lasciati come test non funzionanti nel tuo codice.
concisione
I test individuali dovrebbero essere brevi. Dovrebbero testare una singola cosa o usare il caso.
Quando un buon test fallisce, il suo nome è sufficiente per inviare il programmatore alla classe e al metodo corretti, magari anche a una riga di codice dove dovrebbe cercare il problema.
Se un test è lungo e ha molte parti mobili, quando fallisce significa solo che ora il programmatore deve prima scoprire dove il test è fallito, e la caccia al bug, invece di essere focalizzato nel codice , inizia dalla pettinatura del test stesso.
La prevedibilità
I test dovrebbero essere deterministici.
Quando un buon test fallisce, non riesce a ogni volta.
I test che sono vincolati al tempo (dipendono da Time.now()
), statistici (usa Random
), o si basano su ipotesi esterne (che una riga specifica è in una tabella, che un servizio web è disponibile e funzionante ...) non sono affidabile, dal momento che potrebbero passare quando dovrebbero fallire, o fallire quando dovrebbero passare, e alla fine essere ignorati dal team.
Assicurati che un test stubs tutte le dipendenze esterne (sì, Time
e Random
pure)
Non puoi testare la casualità!
Una volta ho visto un test che ha verificato che un array shuffle non restituisce un array ordinato - beh, indovina un po '- l'array ordinato è un risultato casuale valido!
Completezza
Una buona suite di test è completa.
Quando leggi una suite di test, prova a pensare a tutti i casi limite e verifica se sono stati testati.
Le suite di test scadenti non riescono a coprire casi di utilizzo non mainstream e consentono l'esistenza di bug funzionali in un codice che li supera.
secchezza
Una buona suite di test dovrebbe essere DRY.
Ciò aiuta sia la leggibilità che la manutenibilità. Man mano che la base di codice si evolve, lo sono anche i test.
Se le modifiche ai test implicano la ricerca e la sostituzione ingombranti e passano ore di programmatore per far passare i test di errore (aggiornando i test) ogni volta che cambiano i requisiti, l'intero approccio fallirà, poiché i programmatori smetteranno semplicemente di eseguire i test e abbandona TDD del tutto come "troppo dispendioso".
I buoni test, quando sono DRY, sono più facili da mantenere, poiché le modifiche al codice dovrebbero comportare meno cambiamenti nei test e quindi meno tempo trascorso nel vecchio codice di test.
Velocità
Una buona suite di test non dovrebbe richiedere più di qualche secondo per l'esecuzione.
Più a lungo una suite di test richiede di essere eseguita, meno volte verrà eseguito .
I / O, in particolare il networking, ma anche letture / scritture su dischi pesanti, query DB complesse, ecc. Devono essere simulate o cancellate.
Mai utilizzare sleep()
nei test. Tempo falso, invece.
A volte ci sono dei test che hanno per fare e che richiedono più tempo. Contenerli in una speciale sezione "long running", magari nella suite di test di "integrazione", e farli girare meno spesso (magari di notte).