Qualità del codice nei test unitari?

23

Durante la scrittura dei test delle unità, vale la pena dedicare del tempo in più per rendere il codice di buona qualità e leggibilità?

Durante la scrittura di test, spesso rompo la Legge di Demeter , per una scrittura più veloce e per evitare l'utilizzo di così tante variabili. Tecnicamente, i test unitari non sono riutilizzati direttamente - sono strettamente legati al codice quindi non vedo alcun motivo per spendere molto tempo su di essi; devono solo essere funzionali.

    
posta m3th0dman 27.06.2012 - 10:45
fonte

7 risposte

11

Dovresti sicuramente prendere lo stesso, se non meglio, cura dei tuoi test unitari rispetto al tuo codice di produzione in termini di qualità e leggibilità. I test unitari sono spesso la prima cosa che si guarda quando si cerca di capire cosa fa un pezzo di codice, e il lettore dovrebbe capire rapidamente cosa è in gioco quando si guarda il test. Anche i test unitari tendono a cambiare molto e si romperanno molto se il loro design non è robusto, il che annulla i benefici di avere dei test.

La violazione della legge di Demeter è sicuramente un problema nei test di unità per quel motivo e in altri 2 che mi vengono fuori di testa:

  • Se i tuoi test infrangono la legge di Demeter nelle loro sezioni Arrange o Act , probabilmente è un segno che il tuo codice di produzione lo fa anche, dal momento che i tuoi test unitari sono solo un altro consumatore del tuo codice e probabilmente chiameranno e faranno funzionare la classe in prova nello stesso modo in cui farebbe qualsiasi altro codice di produzione.

  • Se i tuoi test infrangono la legge di Demeter nelle loro sezioni Assert (cioè verifichi il valore di qualcosa che è profondamente annidato nel grafico delle dipendenze dell'oggetto sotto test), potrebbe essere che quelli sono davvero test di integrazione piuttosto che i test unitari. In altre parole, se in TestA asserisci che A.B.C.D è uguale a qualcosa, potrebbe essere che in effetti stai provando a testare D e A piuttosto che solo A.

A proposito, quando dici

I break very often the Law of Demeter, for faster writing and not using so many variables.

dovresti essere consapevole che scrivere

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

very.Deep();

in realtà non è migliore Demeter saggio di

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

se è quello che intendevi.

    
risposta data 27.06.2012 - 13:45
fonte
47

Vale assolutamente la pena di scrivere del codice di buona qualità per i test unitari:

  • Richiederà 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 mostrare davvero:
    • Intenzione: "qual è il comportamento previsto?".
    • Uso: "come dovrei usare questa API?".
  • Richiedono il debug come qualsiasi altro codice.

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

    
risposta data 27.06.2012 - 11:06
fonte
22

Sì, conta. Ci sono diversi motivi per cui i test unitari dovrebbero essere considerati conformi agli altri standard:

  • Ogni test unitario funge anche da documentazione per il candidato. 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 di una funzione. Possono anche servire come punto di partenza per le persone nuove al codice base.

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

  • Se, per qualche ragione, hai più tardi bisogno di dividere un modulo, probabilmente dovrai anche dividere i suoi test unitari. Questo è più facile se i test sono scritti in modo tale da avere delle dipendenze facilmente distinguibili.

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

    
risposta data 27.06.2012 - 11:00
fonte
12

Se non riesci a leggere un'uniforme e scopri cosa sta testando la prossima volta che fallisci, trascorri 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 le unittests dovrebbero avere un risultato previsto; fare la procedura; ottenere un risultato reale; test previsto contro il tipo effettivo di struttura che è facile da scrivere e comprendere

    
risposta data 27.06.2012 - 10:52
fonte
1

Il codice di prova dovrebbe ricevere tanto amore quanto il tuo codice di produzione. Per la leggibilità, forse anche di più. Se qualcun altro oltre a te (incluso te due settimane dopo aver lasciato il codice) dovrebbe capire cosa sta succedendo, allora dovresti rendere il tuo codice un po 'nitido.

Questo significa:

  • Estrai la compilazione dei dati di test nelle classi di build.
  • Estrai asserzioni multiblete in metodi di asserzione separati.
  • Sii molto preciso nella tua denominazione. Assert.That(x4, Is.EqualTo(y16*2*SOME_VALUE), ASS_ERR_TXT_56) rende molto poco sense a la maggior parte dei lettori.

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

    
risposta data 28.06.2012 - 08:49
fonte
1

La ragione pratica più importante è che ogni volta che si cambia codice, si cambiano i test unitari. E se stai facendo TDD, stai persino cambiando i test unitari.

Esegui una di queste cose nei test:

  • Codice duplicato
  • Riduzione della leggibilità
  • Accoppiamento stretto
  • Accoppiamento temporale
  • Elevata complessità ciclomatica (molte dipendenze)

E sei pronto per un sacco di lavoro quando è necessario un cambiamento.

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

    
risposta data 04.07.2012 - 00:52
fonte
0

Dipende se questi test unitari sono "temporanei" o meno. Se

  1. Il test verrà usato frequentemente;

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

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

allora i test dovrebbero essere scritti correttamente. Nel caso ci sia un bug nel test stesso, sarà difficile trovare il bug e correggerlo, specialmente se è trascorso un po 'di tempo da quando il test è stato scritto.

D'altra parte, se questi test sono usati solo dagli sviluppatori stessi / solo, penso che sia ok. Ma è ancora preferibile scrivere codice 'leggibile'. Come ha detto il maniaco del cricchetto, dovrai dedicare più tempo a correggere i tuoi test che a spendere per la scrittura corretta.

    
risposta data 27.06.2012 - 10:56
fonte

Leggi altre domande sui tag