Un fattore importante che rende estremamente utili i test unitari è il feedback rapido .
Considera cosa succede quando la tua app è completamente coperta da test di integrazione / Sistema / funzionali (che è già una situazione ideale, lontana dalla realtà nella maggior parte dei negozi di sviluppo). Questi sono spesso gestiti da un team di test dedicato.
- Commetti una modifica al repository SCM,
- qualche giorno (forse giorni) dopo, i ragazzi del test ottengono una nuova versione interna e iniziano a testarla,
- trovano un bug e presentano una segnalazione di bug,
- (nel caso ideale) qualcuno ti assegna la segnalazione di bug.
Tutto ciò può richiedere giorni o addirittura settimane. A questo punto hai già lavorato su altre attività, quindi non hai in mente i minimi dettagli del codice scritto in precedenza. Inoltre, in genere non hai nemmeno una prova diretta di dove si trova effettivamente il bug, quindi ci vuole molto tempo per trovare e correggere il bug.
Considerando che nel test unitario (TDD)
- scrivi un test,
- scrivi del codice per soddisfare il test,
- il test fallisce ancora,
- guardi il codice e in genere hai un'esperienza "oops" in pochi secondi (come "oops, ho dimenticato di verificare quella condizione!"), quindi
- correggi immediatamente il bug.
Tutto ciò accade in pochi minuti .
Questo non significa che i test di integrazione / sistema non siano utili; servono solo a scopi diversi. Con test di unità ben scritti puoi catturare una grande parte dei bug nel codice prima che arrivino alla fase di integrazione, dove è già molto più costoso trovarli e risolverli. Hai ragione sul fatto che i test di integrazione sono necessari per rilevare quei tipi di bug che sono difficili o impossibili da rilevare con i test unitari. Tuttavia, nella mia esperienza quelli sono quelli più rari; la maggior parte dei bug che ho visto sono causati da un'omissione semplice o addirittura banale da qualche parte all'interno di un metodo.
Per non parlare del fatto che i test unitari verificano anche le interfacce per usabilità / sicurezza, ecc., Fornendo così un feedback di vitale importanza per migliorare il design e le API. Quale IMHO può ridurre considerevolmente le possibilità di bug di integrazione modulo / sistema: più facile e pulita è un'API, minore è la possibilità di incomprensioni o omissioni.
Che esperienza hai con i test di unità automatizzati, i test di integrazione automatizzati e i test di accettazione automatizzati e nella tua esperienza che cosa ha prodotto il ROI più elevato? e perché?
Il ROI dipende da molti fattori, probabilmente il principale è se il tuo progetto è greenfield o legacy. Con lo sviluppo del greenfield il mio consiglio (e l'esperienza finora) è quello di fare unit test TDD dall'inizio. Sono fiducioso che questo è il metodo più conveniente in questo caso.
In un progetto legacy, tuttavia, costruire una copertura sufficiente per i test unitari è un'impresa enorme che sarà molto lenta a produrre benefici. Se possibile, è più efficace provare a coprire le funzionalità più importanti con test di sistema / funzionali tramite l'interfaccia utente. (Le app della GUI desktop possono essere difficili da testare automaticamente tramite la GUI, sebbene gli strumenti di supporto automatico dei test stiano gradualmente migliorando ...). Ciò fornisce rapidamente una rete di sicurezza grossolana ma efficace. Quindi puoi iniziare a costruire gradualmente unit test intorno alle parti più critiche dell'app.
Se dovessi scegliere solo una forma di test da automatizzare per il tuo prossimo progetto, quale sarebbe?
Questa è una domanda teorica e la trovo inutile. Tutti i tipi di test hanno il loro uso nella cassetta degli attrezzi di un buon ingegnere SW, e tutti questi hanno scenari in cui sono insostituibili.