Come spiegare il valore del test unitario


30

Voglio introdurre il concetto di unit test (e test in generale) ai miei collaboratori; in questo momento non ci sono test e le cose vengono testate eseguendo effettivamente le attività tramite l'interfaccia utente per vedere il risultato desiderato. Come puoi immaginare, il codice è strettamente associato all'implementazione esatta, anche con il risultato che il codice che dovrebbe essere in una classe e riutilizzato in tutto il sistema viene copiato e incollato tra i metodi.

A causa dei mutati requisiti, mi è stato chiesto di modificare un modulo che ho scritto in precedenza e che è abbastanza vagamente accoppiato (non quanto vorrei, ma come meglio posso ottenere senza dover introdurre molti altri concetti). Ho deciso di includere una serie di unit test con il mio codice rivisto per "dimostrare" che funziona come previsto e dimostrare come funzionano i test; Non sto seguendo il vero TDD poiché parte del codice è già stato scritto, ma spero di seguire alcuni concetti TDD per il nuovo codice che dovrò creare.

Ora, inevitabilmente, sono sicuro che mi verrà chiesto perché mi ci vuole più di un giorno o due per scrivere il codice, poiché parti di ciò con cui interagirò già esistono nel sistema (anche se senza test e molto strettamente accoppiato), e quando controllo il codice mi verrà chiesto quale sia questo progetto "Test". Posso spiegare le basi del test, ma non posso spiegare i vantaggi effettivi in ​​un modo che gli altri potrebbero capire (perché pensano che il test richieda l'esecuzione dell'app da soli, poiché spesso l'interfaccia utente effettiva conta nel determinare se la funzione "funziona" " o no). Non capiscono l'idea di un accoppiamento libero (chiaramente evidente dal fatto che nulla è liberamente accoppiato; non ci sono nemmeno interfacce al di fuori del codice che ho scritto), quindi provare a usarlo come beneficio probabilmente mi farebbe guadagnare un "Eh?" un po 'di aspetto, e di nuovo non posso essere così lento come vorrei senza dover rielaborare diversi moduli esistenti e probabilmente introdurre un qualche tipo di contenitore IoC, che sarebbe visto come perdere tempo e non "programmare".

Qualcuno ha qualche suggerimento su come posso puntare a questo codice e dire "Dovremmo iniziare a creare unit test" senza apparire né condiscendenti (ad esempio "Scrivere test ti costringe a scrivere un buon codice", che probabilmente verrebbe assunto per significare codice tranne che il mio è cattivo ) o senza far sembrare una perdita di tempo che non aggiunge alcun valore reale?


1
Sembra che il tempo in cui ho chiesto al "ragazzo del database di esperti" perché le informazioni sulla carta di credito fossero A. non trattate e B. Perché il campo del numero di telefono era nvarchar (MAX) e C. Perché non c'erano relazioni tra nessuno dei tavoli. Non l'ha capito.
The Muffin Man,

1
(questa è una risposta sarcastica, è uno scherzo ) -> (A) Se alcuni si rompono nel tuo server di database hai problemi più grandi. (B) L'archiviazione dei dati è economica e se si volesse archiviare i metadati all'interno di un campo. (C) NoSQL baby;) ( Ancora una volta fammi ripetere sto scherzando )
Darknight

C'è un intero capitolo su questo nel grande The Art of Unit Testing .
StuperUser,

6
@Wayne, ogni volta che leggo una delle tue domande sono convinto che devi trovare un nuovo lavoro. Sono una reliquia obsoleta nello sviluppo del software e tu no. Se si apre una finestra per te, saltaci sopra e non guardare indietro.
maple_shaft

2
@WayneM, Esci. Sul serio.
AK_

Risposte:


18

Voglio introdurre il concetto di unit test (e test in generale) ai miei collaboratori

Penso che potrebbe essere meglio iniziare dal lato pratico, non concettuale. Naturalmente, se durante una discussione informale scopri che i tuoi colleghi e / o i tuoi dirigenti sono interessati a conoscere i test unitari, tanto meglio - allora potresti ottenere da Google alcune esperienze / prove concrete dal web, mettere insieme una breve formazione, ecc. Tuttavia, da quello che descrivi, sembra che i tuoi compagni di squadra non siano molto aperti a questa strana nuova idea.

In una situazione del genere, inizierei a scrivere i miei piccoli test unitari senza prima provare a spiegare troppo a nessuno. Aggiungine un paio ogni volta che cambio codice, senza cercare di coprire tutto il codice (che richiederebbe una quantità eccessiva di tempo). Idealmente, se riesco a trovare un buon equilibrio, quando si accorgono che sto scrivendo test unitari, potrei già avere una serie di test sostanziale e alcuni risultati concreti da mostrare (come "con questo caso di test sono riuscito a catturare un bug introdotto dal cambiamento della scorsa settimana, che altrimenti sarebbe scivolato al QA / produzione "). Ciò dimostrerà il valore dei test per qualsiasi sviluppatore serio.

Dopodiché, sono in una buona posizione per iniziare a spiegare i vantaggi a lungo termine dei test unitari, come

  • dimostra che il codice funziona - sempre e ovunque, istantaneamente e automaticamente, che a sua volta
  • dà fiducia al refactor, con conseguente miglioramento del design e migliore manutenibilità,
  • e se qualcosa si rompe, i test unitari forniscono un feedback (quasi) immediato, al contrario di diversi giorni o settimane di latenza se il bug viene rilevato da un reparto di controllo qualità separato. Ciò che di solito ti consente di correggere il bug in pochi secondi, anziché eseguire il debug per ore / giorni, nel codice che è da tempo caduto dalla tua memoria a breve termine.

Vedi anche questo thread correlato: test di unità automatizzati, test di integrazione o test di collaudo .

E uno precedente di SO: che cos'è il test unitario?


4
+1 per l'aspetto pratico. Lo abbiamo fatto nei nostri oltre 50 sviluppatori. negozio e sta prendendo piede. Ogni volta che otteniamo un altro sviluppatore. scrivendo i test, sono agganciati.
Ale

La parte negativa è che sta scrivendo i test, ma i suoi colleghi non li conoscono e cambieranno qualcosa nel codice di produzione che causerà il fallimento dei test annullando così tutti i suoi sforzi :(
Igor Popov

Hai controllato i test all'inizio o li hai tenuti per te? Potrei immaginare che un recensore non sarebbe entusiasta se comincio a controllare i file di test senza l'approvazione del mio capo
Frode Akselsen,

12

Rifattorizza senza paura

Dal punto di vista leggermente diverso, TDD ti consente di "ripensare senza paura", e questo è un vantaggio chiave che puoi vendere alla tua squadra. Impedisce agli sviluppatori di dire a se stessi:

  • "Non voglio toccare questo codice perché temo di romperlo"
  • "Non voglio scrivere nuove funzionalità su questo codice perché non so come funziona"
  • "Segretamente, ho paura di quel codice"

Potrei arpionare di più, ma questo è un terreno ben coperto come lo zio Bob su TDD e Martin Fowler su TDD .

dipendenze

Oh, aggiungerò un'altra cosa. Mostrerà loro come TDD impone una buona progettazione che consente di gestire in modo pulito le dipendenze.

Bob: "Oh c% ^ p! I boss ci hanno costretti a usare MS SQL Server 2008" Jane: "Va bene, il danno è ridotto al minimo perché abbiamo creato il nostro datasource e le nostre classi DAO, sono così felice che TDD abbia incoraggiato noi lungo quel sentiero ".


4

Mentre lavoriamo su un codice sorgente che non ha test automatici, dobbiamo lavorare con molta cura e abbiamo bisogno di più recensioni per rimanere fiduciosi che il tipo di modifiche che stiamo apportando non rompe nessuna delle funzionalità esistenti.

Quando avremo buoni casi di test automatizzati, le conseguenze saranno uno sviluppo più rapido, sicuro e senza paura (può essere la correzione di bug, il miglioramento o il re-factoring).


4

Fai i conti

  • t mt = il tempo necessario per testare manualmente tutto ciò che è possibile che influisca
  • t wt = il tempo necessario per scrivere i test
  • k = il numero di volte in cui dovrai probabilmente provare tutto prima di rilasciare il nuovo codice

    if (t wt <t mt ) o (t wt <(k * t mt )) allora è un gioco da ragazzi: scrivere i test accelererà lo sviluppo.

altrimenti guarda il rapporto (t wt / (k * t mt )). Se è un numero molto grande, aspetta un'altra opportunità; altrimenti giustificare con i benefici del test di regressione.

Nota: a questo punto suggerisco di testare solo le funzionalità, non le unità , molto più facile da giustificare e comprendere, e probabilmente meno lavoro con un valore superiore rispetto ai semplici test unitari durante il refactoring.

Nota 2: il tempo necessario per eseguire i test non ha importanza , perché sono automatizzati. Puoi fare qualcos'altro produttivo durante l'esecuzione dei test, a meno che i test non impieghino così tanto tempo a farti perdere la scadenza. Che è raro.


Ti sto dando un +1, ma quella matematica sembra spaventosa!
Wayne Molina,

@Wayne sono solo gli abbonamenti, sono intimidatori. Ma la programmazione non è per femminucce! ;-)
Steven A. Lowe,

1

Un suggerimento se sei un negozio Microsoft: trova alcuni documenti su MSDN che raccomandano test unitari o accoppiamento libero come best practice (sono sicuro che ci sono più istanze di questo ) e indica se ci sono conflitti.

Può sembrare un modo grossolano di fare le cose, ma ho scoperto che l'uso del termine "best practice" ti porterà molto lontano, soprattutto con la gestione.


1

Come consiglio sempre, se conosci una buona pratica, il modo migliore per introdurla delicatamente nel tuo ambiente sarebbe ovviamente iniziare a farlo da solo e poi da qualche parte lungo la strada, alcuni dei tuoi collaboratori vedranno i benefici e prendilo.

La parola chiave qui è evoluzione, non rivoluzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.