2009-06-18 5 views
12

Nell'ultimo anno circa ho sviluppato le mie costolette TDD in modo che ora sono abbastanza bravo nell'essenziale - prima test di scrittura, strutture di derisione, test delle piccole cose possibili, DI ecc.Prendendo il collaudo delle unità al livello successivo

Tuttavia, mi sembra che ci siano ancora molte cose che non riesco a superare.

Ad esempio, spesso trovo che il test delle unità in questo modo non verifichi realmente l'integrazione e nel complesso l'immagine ingrandita di ciò che il mio codice dovrebbe fare. Con tutto ciò che viene deriso, scopro che perdo di vista se i metodi in prova stanno producendo o meno i risultati che effettivamente ho bisogno di , piuttosto che solo i risultati che dicono forniranno. Mentre comincio a muovermi verso BDD, trovo che questo problema è solo esacerbato, con conseguente spreco di tempo di sviluppo e test inefficaci.

Un altro problema è che i test di unità richiedono una grande quantità di manutenzione per mantenerli ordinati, rallentando il refactoring.

Quando ho iniziato a testare le unità, come la maggior parte delle persone, ho scoperto che quello che stavo scrivendo erano davvero test di integrazione. Tuttavia ci sono stati molti vantaggi a questi test: erano molto più semplici da leggere e funzionavano come documentazione decente sull'API dei miei programmi. Inoltre, tendevano a catturare il problema del mondo reale molto più velocemente, piuttosto che i test unitari che trovo trascorrono molto tempo a individuare casi limite che potrebbero derivare solo dall'uso non corretto dell'API (ad esempio riferimenti null, divisione per 0 ecc.).

Quali sono i tuoi pensieri? Potete consigliare buoni libri, articoli o pratiche che affrontino test unitari più avanzati e mantengano la produttività e l'efficacia?

EDIT: Basta un po 'di domande, date le risposte: quindi in pratica stai dicendo che, nonostante tutto questo "test" di unità, non sto davvero testando il codice ... al quale rispondo, "Ma Voglio testare il codice dang! ' Infatti, quando ho scritto molti test di integrazione "più pesanti", ho scoperto che il mio codice tendeva a raggiungere uno stato di correttezza molto più veloce, e gli errori venivano identificati molto prima. È possibile raggiungere questo obiettivo senza i problemi di manutenibilità dei test di integrazione?

+0

@cbp: è _unit_ test. Non è pensato per testare l'integrazione, o un quadro generale. –

risposta

8

TDD e BDD non sono significati essere strumenti per misurare la qualità del codice, sono pensati per essere strumenti per aiutare nella progettazione di pezzi di codice liberamente accoppiati e altamente mantenibili. Ha più a che fare con la progettazione dell'API di qualsiasi altra cosa. Ha lo scopo di garantire che il codice esegua ciò che dice e lo fa in un modo in cui la modifica di una parte del codice non influisce sulle altre parti.

Mi aspetto che la tua sensazione di esasperazione con BDD derivi dall'aspettativa che tu stia scrivendo gli strumenti semplicemente per "eliminare i bug" o "sostituire il tuo processo di controllo qualità", che né BDD né TDD intendono fare. Test Driven Development significa "sviluppo, guidato da test" e non "test, guidati dallo sviluppo". Mi sembra che tu voglia il secondo.

I test di integrazione e la garanzia della qualità del software sono argomenti completamente diversi, ma capisco le ragioni della grande confusione tra questi e l'associazione di TDD con loro.

Test Driven Development significa "sviluppo, guidato da test" e non "test, guidati dallo sviluppo". Mi sembra che tu voglia il secondo.

Aggiornamento Voglio solo condividere la mia voce del blog riguardo a questo problema: Repeat after me: Test Driven Development is about design, NOT testing!

+0

I test unitari hanno lo scopo di fornire una suite di test di regressione, per informarti quando il refactoring interrompe la tua applicazione. –

+1

I test unitari hanno lo scopo di fornire loro, sì. TDD non lo è. –

+0

Scrivi test unitari separati dal TDD? –

2

Unit Testing è solo un tipo di test, non è l'unico tipo di test.

test Unità dovrebbe coprire l'unità più piccola possibile di lavoro possibile, beffardo fuori tutte le dipendenze è un processo molto importante per raggiungere questo obiettivo, dando che queste dipendenze hanno i propri test di unità che li ricopre.

Dopo di coprire una discreta quantità di vostre piccole unità, allora fai quello che viene chiamato Test funzionale, che si presenta come unità di prova tuttavia non deridere tutte le cose che si sta prendendo in giro in un test di unità, in genere se il tuo sistema creato da diversi team, Functional Tests prende in giro solo le dipendenze introdotte da altri team, ma il tuo codice squadra non viene deriso.

Dopo aver eseguito il test funzionale, si avranno i test di integrazione e qui quando inizi a utilizzare dipendenze reali da altri team, in generale non dovresti avere alcun tipo di derisione in questo tipo di test.

Dato che tutti e tre i tipi di test vengono creati utilizzando mstest o NUnit, è ancora il test del codice.

1

Se si segue veramente il TDD come descritto dai professionisti, ogni test dovrebbe testare una parte relativamente piccola del codice (solo poche righe). Per definizione, questi non sono test di integrazione. La gente di TDD ti dirà che hai bisogno di un'intera suite separata di test per fare test di integrazione.

Si è corretto, in quanto una tale suite di test TDD può alla fine impantanarsi in minuzie. Lo sviluppo basato sui test, per definizione, è la creazione, la progettazione e il test degli alberi, non delle foreste. TDD è la creazione di requisiti tramite test unitari ma, per sua stessa natura, incarna requisiti a livello microscopico.

Se, come afferma la gente del TDD, sono necessari test di integrazione separati, sono necessari anche requisiti, specifiche e procedure per questi test. Quando si inizia a risalire la catena alimentare, i test iniziano a diventare sempre più complessi, fino a raggiungere il livello di interfaccia funzionale/utente, in cui i test automatici diventano quasi impossibili.

+0

Rob Conery ha avuto una conversazione interessante con Scott Hanselman su uno dei suoi podcast durante una discussione sul suo strumento ORM, Subsonic. Subsonic deve essere in grado di interagire con database di diversi fornitori. Alcuni utenti di Subsonic si sono lamentati del fatto che i test unitari di Rob hanno colpito troppo il database (nel senso che gli utenti ritenevano che i test dovessero essere derisi). La risposta di Rob è stata che il fatto che il database deridesse essenzialmente invalida i test, dal momento che l'intero punto era quello di assicurarsi che il database di ciascun fornitore continuasse a funzionare correttamente con lo strumento. –

1

Scopri "Costruzione di software orientata agli oggetti" di Bertrand Mayer.

Il concetto si chiama "Contract Driven Development" È un tipo di test in linea a livello di funzione, ha cambiato il modo in cui programma.

Se si utilizza CDD in Eiffel, la lingua scritta anche da Bertrand, vengono controllati automaticamente dal runtime durante la fase di test e debug.

http://www.amazon.com/Object-Oriented-Software-Construction-Prentice-Hall-International/dp/0136291554

http://dev.eiffel.com