Qualità del codice nei test unitari?


23

Quando si scrivono test unitari, vale la pena dedicare del tempo extra per rendere il codice di buona qualità e leggibilità?

Quando scrivo i test infrangono spesso la Legge di Demetra , per una scrittura più veloce e per evitare di usare così tante variabili. Tecnicamente, i test unitari non vengono riutilizzati direttamente - sono strettamente vincolati al codice, quindi non vedo alcun motivo per dedicare molto tempo ad essi; devono solo essere funzionali.


5
La leggibilità e la manutenibilità devono essere al centro dei test unitari.
EL Yusubov,

2
Anche i test sono codici!
Grant Palin,

Fa ancora parte del tuo progetto, anche se non viene spedito ai clienti. Trattalo di conseguenza.

Risposte:


11

Dovresti assolutamente fare lo stesso, se non meglio, i test unitari del tuo codice di produzione in termini di qualità e leggibilità. I test unitari sono spesso la prima cosa che guardi quando cerchi di capire cosa fa un pezzo di codice e il lettore dovrebbe capire rapidamente cosa c'è in gioco quando guarda il test. Anche i test unitari tendono a cambiare molto e si rompono molto se il loro design non è solido, il che annulla i vantaggi di avere test.

La violazione della Legge di Demetra è sicuramente un problema nei test unitari per questo motivo, così come altri 2 che mi vengono in mente:

  • Se i tuoi test infrangono la Legge di Demetra nelle loro sezioni Arrange o Act , è probabilmente un segno che anche il tuo codice di produzione lo fa, poiché i tuoi test unitari sono solo un altro consumatore del tuo codice e probabilmente chiameranno e gestiranno la classe sotto test nello stesso come farebbe qualsiasi altro codice di produzione.

  • Se i tuoi test infrangono la Legge di Demetra nelle loro sezioni Assert (cioè verifichi il valore di qualcosa che è profondamente annidato nel grafico delle dipendenze dell'oggetto sotto test), è possibile che si tratti di test di integrazione piuttosto che di unit test. In altre parole, se in TestA affermi che ABCD è uguale a qualcosa, potrebbe essere che stai effettivamente cercando di testare D e A piuttosto che solo A.

A proposito, quando dici

Infrango molto spesso la Legge di Demetra, per scrivere più velocemente e non usare così tante variabili.

dovresti essere consapevole che scrivere

var grab = myDependency.Grab;
var something = grab.Something;
var very = something.Very;

very.Deep();

Demeter non è in realtà migliore di

myDependency.Grab.Something.Very.Deep();

se è questo che intendevi.


47

Vale assolutamente la pena dedicare tempo a scrivere un codice di buona qualità per i test unitari:

  • Richiederanno la manutenzione come qualsiasi altro codice.
  • I test unitari sono una delle migliori fonti di documentazione per il tuo sistema e probabilmente la forma più affidabile. Dovrebbero davvero mostrare:
    • Intento: "qual è il comportamento previsto?".
    • Uso: "come dovrei usare questa API?".
  • Richiederanno il debug come qualsiasi altro codice.

L'unico fattore a favore di un approccio leggermente più ad hoc è che i test unitari non diventeranno mai un'API pubblica, quindi non devi preoccuparti di quali interfacce / ecc. stai esponendo.


22

Sì, importa. Esistono diversi motivi per cui i test unitari devono essere tenuti a uno standard comparabile come altri codici:

  • Ogni test unitario funge anche da documentazione per il testato. Quando i test sono completi e coprono il maggior numero possibile di casi limite e condizioni di errore, possono spesso sostituire la documentazione di commento di una classe o funzione. Possono anche servire come punto di partenza per le persone nuove alla base di codice.

  • Anche i test unitari possono essere difettosi. E gli errori sono più visibili quando il codice è ben scritto.

  • Se, per qualche motivo, in seguito dovessi suddividere un modulo, probabilmente dovrai dividere anche i suoi test unitari. Questo è più semplice se i test sono scritti in modo tale da avere dipendenze facilmente distinguibili.

Detto questo, c'è sempre la questione della praticità. A seconda della lingua e della natura del codice, può essere difficile scrivere test unit "puliti" senza passare molto più tempo sui test che sul codice che dovrebbero testare. In tal caso, di solito torno a testare le cose facili, rapide e le funzionalità più importanti, senza preoccuparmi troppo della copertura completa. Ogni volta che un bug si ripresenta in un secondo momento, scrivo un test per esso e controllo se posso refactoring il nuovo test e quelli esistenti per renderli più belli.


12

se non riesci a leggere un unittest e scopri cosa sta testando la prossima volta che fallisce, passerai il doppio del tempo di debug (una volta per scoprire di cosa tratta il test e una volta per correggere il codice che sta testando)

onestamente gli unittest dovrebbero avere un risultato atteso; fare la procedura; ottenere risultati effettivi; test atteso rispetto al tipo effettivo di struttura che è facile da scrivere e capire


1

Il codice di prova dovrebbe ricevere lo stesso amore del tuo codice di produzione. Per leggibilità, forse anche di più. Se si suppone che qualcun altro di te (incluso te due settimane dopo aver lasciato il codice) capisca cosa sta succedendo, allora dovresti rendere il tuo codice piacevole e nitido.

Questo significa:

  • Estrai la costruzione di dati di test in classi del builder.
  • Estrarre più asserzioni in metodi di asserzione separati.
  • Sii molto preciso nella tua denominazione. Assert.That(x4, Is.EqualTo(y16*2*SOME_VALUE), ASS_ERR_TXT_56)fa ben poco senso alla maggior parte dei lettori.

Prese all'estremo, i test possono essere scritti in modo che siano quasi facili da leggere e da capire come la prosa. Il tester estremo direbbe probabilmente che un test unitario lungo più di 10 righe è negativo.


1

Il motivo pratico più importante è che ogni volta che si cambia codice, si cambiano i test unitari. E se stai facendo TDD, stai anche cambiando prima i test unitari.

Fai una di queste cose nei tuoi test:

  • Codice duplicato
  • Leggibilità discreta
  • Accoppiamento stretto
  • Accoppiamento temporale
  • Elevata complessità ciclomatica (molte dipendenze)

E hai un sacco di lavoro quando è necessario un cambiamento.

Tratta i tuoi test come hai suggerito e finirai per pentirti. Probabilmente arriverai persino alla falsa conclusione che "TDD non funziona".


0

Dipende dal fatto che questi test unitari siano "temporanei" o meno. Se

  1. Il test verrà utilizzato frequentemente;

  2. Gli sviluppatori devono lavorare con test unitari scritti da altri sviluppatori;

  3. La maggior parte dei test viene eseguita da test unitari

quindi i test devono essere scritti correttamente. Nel caso in cui ci sia un bug nel test stesso, sarà difficile trovare il bug e risolverlo, specialmente se è passato del tempo da quando il test è stato scritto.

D'altra parte, se questi test vengono utilizzati solo dagli sviluppatori stessi, penso che vada bene. Ma è ancora preferibile scrivere codice "leggibile". Come ha detto il maniaco del cricchetto, avrai più tempo a sistemare i tuoi test di quanto spenderesti per scriverli correttamente.


(1) i test unitari non sono mai temporanei (2) anche se sono per te stesso, in un mese (o più), non ricorderai tutti i dettagli, quindi è importante farlo correttamente - anche per te stesso
BЈовић
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.