I test unitari sono davvero usati come documentazione?


22

Non riesco a contare il numero di volte che ho letto affermazioni sulla vena di "unit test sono una fonte molto importante di documentazione del codice in prova". Non nego che siano veri.

Ma personalmente non mi sono mai trovato ad usarli come documentazione. Per i quadri tipici che uso, le dichiarazioni del metodo documentano il loro comportamento e questo è tutto ciò di cui ho bisogno. E suppongo che i test delle unità eseguano il backup di tutto quanto indicato in quella documentazione, oltre a probabilmente altre cose interne, quindi da un lato duplica la documentazione mentre dall'altro potrebbe aggiungere un po 'di più che è irrilevante.

Quindi la domanda è: quando vengono utilizzati i test unitari come documentazione? Quando i commenti non coprono tutto? Sviluppando estendendo la fonte? E cosa espongono che può essere utile e rilevante che la documentazione stessa non può esporre?


4
Non ho mai pensato di usare il test unitario direttamente come documentazione. Penso che i test unitari siano spesso illeggibili, perché molti sviluppatori non impiegano il tempo per scriverli chiaramente.
superM,

10
I commenti potrebbero essere errati.

2
So che stai chiedendo specificamente dei test unitari, ma noterei anche che i test di integrazione / sistema sono anche una documentazione davvero utile, solo a un livello diverso
jk.

3
Ho visto test unitari che sarebbero stati meglio definiti come "esperimenti unitari". La loro dipendenza da fattori esterni era tanto da renderli quasi inutili. Erano anche molto poco chiari. (Sì, ho un obiettivo a lungo termine di riformattare in modo che siano migliori, ma faccio anche altre cose ...)
Donal Fellows,

4
I test unitari di @Ant invocano il codice reale e documentano la risposta prevista e la confrontano con la risposta effettiva. Che il codice invocato sia corretto o meno, non è questo il punto: i test documentano come invocarlo.

Risposte:


17

NON sono una documentazione di riferimento ASSOLUTA

Si noti che molte delle seguenti considerazioni si applicano anche ai commenti, in quanto possono non essere sincronizzati con il codice, come i test (anche se è meno applicabile).

Quindi, alla fine, il modo migliore per capire il codice è avere un codice di lavoro leggibile .

Se possibile, e non scrivere sezioni di codice di basso livello cablate o condizioni particolarmente complicate, sarebbe cruciale una documentazione aggiuntiva.

  • I test possono essere incompleti:
    • L'API è cambiata e non è stata testata,
    • La persona che ha scritto il codice ha scritto i test per i metodi più semplici da testare al posto dei metodi più importanti da testare, quindi non ha avuto il tempo di terminare.
  • I test possono essere obsoleti.
  • I test possono essere messi in corto circuito in modi non ovvi e non effettivamente eseguiti.

MA SONO ANCORA UN COMPLEMENTO DI Documentazione utile

Tuttavia, in caso di dubbi su ciò che fa una determinata classe, specialmente se piuttosto lungo, oscuro e privo di commenti (sai il tipo ...), cerco rapidamente di trovare le sue classi di test e controllare:

  • ciò che effettivamente cercano di controllare (dà un suggerimento sulle curiosità più importanti, tranne se lo sviluppatore ha fatto l'errore sopra menzionato di implementare solo i test "facili"),
  • e se ci sono casi d'angolo.

Inoltre, se scritti usando uno stile BDD , danno una definizione piuttosto buona del contratto della classe . Apri il tuo IDE (o usa grep) per vedere solo i nomi dei metodi e tada: hai un elenco di comportamenti.

Anche le regressioni e i bug hanno bisogno di test

Inoltre, è buona norma scrivere test per la regressione e per la segnalazione di bug: correggi qualcosa, scrivi un test per riprodurre il caso. Guardandoli indietro, è un buon modo per trovare la relativa segnalazione di bug e tutti i dettagli su un vecchio problema, per esempio.

Direi che sono un buon complemento alla documentazione reale e almeno una risorsa preziosa in questo senso. È un buon strumento, se usato correttamente. Se inizi a testare presto nel tuo progetto e lo rendi un'abitudine, POTREBBE essere un'ottima documentazione di riferimento. Su un progetto esistente con cattive abitudini di codifica già puzzando la base di codice, gestirli con cura.


Posso chiedere perché sono stato sottoposto a downvoting? Cosa ti spunta lì dentro o con cosa non sei d'accordo?
haylem,

2
La parte migliore (IMO) del tuo argomento è scritta con il carattere più piccolo - il modo migliore per capire il codice è innanzitutto avere un codice leggibile. Lo cambierei in "codice leggibile e funzionante", ma sono d'accordo. Quindi, se guardi di nuovo i test unitari, i test in esecuzione funzionano correttamente (e come tutto il codice, dovrebbero essere leggibili), quindi in realtà è abbastanza buona (se spesso troppo locale) se eseguita bene.
Joris Timmermans,

@MadKeithV: grazie. Ho aggiornato per "codice leggibile e funzionante" e ho spinto quel bit più in alto.
haylem,

11

Un'interpretazione è che i test unitari sono "documentazione eseguibile". Puoi eseguire i test unitari sul codice e ti dirà se sta ancora funzionando com'era quando i test sono stati scritti per passare o meno. In tal modo l'unità testa "documenta" la funzionalità del sistema in un determinato momento, in modo eseguibile.

D'altra parte, anche raramente ho letto il codice unit test come "documentazione" per comprendere la funzionalità. Un test di una singola unità è troppo localizzato, specifico e astratto in modo da poterti dire molto sul sistema reale che sta dietro alla classe in prova.


5

Se per documentazione intendi che voglio qualcosa per scoprire come funziona il codice , i test unitari sono piccoli esempi perfetti di come funzionano le unità del codice sia in casi previsti , casi limite che errori (ovvero bug ). Inoltre, i tuoi test potrebbero essere creati prima della scrittura del codice e quindi alla base di ciò che il codice dovrebbe fare da un punto di vista aziendale / dei requisiti.

Stanno sostituendo la documentazione? No.

Sono un'utile aggiunta alla documentazione? Sì.


4

Vedo i test unitari come:

  • un modo per dimostrare che la documentazione è corretta (supponendo che la documentazione corrisponda all'implementazione dell'API).
  • un modo per dimostrare a uno sviluppatore come utilizzare una particolare funzione; i dispositivi di test unitari / test unitari di solito sono abbastanza piccoli da poter imparare rapidamente da esso.
  • e ovviamente per individuare eventuali bug di regressione.

In una certa misura possono essere visti come un complemento di una documentazione esistente ma non come la documentazione.


3

Risponderò alla tua domanda chiedendoti un'altra.

Quante volte quando hai lavorato con una nuova API / routine hai trovato aiuto per cercare un esempio di codice della cosa che stai cercando di usare? Non riesci a passare a Google per una ricerca online di esempi di codice?

Questo è esattamente quando useresti i test unitari come documentazione.

  • In effetti, i test unitari possono essere un po 'più rigorosi rispetto ai normali esempi di codice, poiché è necessario disporre di più test (esempi).
  • Speriamo che i tuoi test unitari mostrino un uso corretto . Ad esempio, mostrano chiaramente tutte le dipendenze essenziali tramite oggetti normali o oggetti finti. (Altrimenti non sono particolarmente buoni test unitari.)
  • NOTA: se i commenti o la "documentazione normale" forniscono esempi di codice, in realtà si stanno violando i principi DRY. E quegli esempi di codice possono facilmente diventare errati nel tempo, mentre ci sono molte meno possibilità di farlo con test unitari eseguiti regolarmente.
  • Se i test unitari sono accurati (di solito un grande if ), dovrebbero fornire ulteriori informazioni:
    • Tutti i casi limite noti sono chiaramente illustrati.
    • Tutte le eccezioni previste che possono essere generate.
    • Tutti i bug precedentemente rilevati (ciò è probabilmente più utile quando si estende l'unità sotto test che quando si scrive un nuovo client per l'unità).
    • Tutte le regole commerciali sottostanti associate all'unità. (se presente)

Ho il sospetto che ci siano alcuni motivi per cui i test unitari non tendono ad essere utilizzati come documentazione anche se potrebbero essere un complemento eccellente alla documentazione più tradizionale:

  • Mi permetto di suggerire che spesso i test stessi non sono abbastanza ben scritti per lo scopo. Altre risposte hanno già fatto allusione a test che sono:
    • Incompleta.
    • Confondere. (Ho visto casi di test che non chiamano direttamente il metodo testato: si passa a 3/4 livelli di profondità nello stack di chiamate prima che venga chiamato e le condizioni preliminari per chiamare il metodo sono sparse in luoghi diversi in una gerarchia di classi complesse. )
    • Obsoleto. (di solito i test dovrebbero fallire quando diventano obsoleti, ma non è sempre così).
  • Di solito ci sono molti esempi di utilizzo già disponibili nel codice di produzione ogni volta che si presenta la necessità di un esempio.
  • L'unità sottoposta a test è così ben scritta (autocertificazione) che i metodi non hanno bisogno di esempi. Spero che!
  • Nella mia esperienza di programmatore, tendiamo ad essere abbastanza entusiasti di saltare alla fine e RTFM martedì prossimo ...
  • Documentazione e commenti che violano il principio DRY.

2

TL; test unitari DR e commenti API sono complementari: alcune cose sono meglio descritte nel codice e altre in prosa.

I test unitari sono utili soprattutto per documentare casi speciali e condizioni limite difficili da descrivere (e ingombranti) nei commenti API. Inoltre, i commenti sull'API sono generalmente indirizzati a persone che desiderano utilizzare l'API.

Se si desidera modificare il codice, in genere è necessario sapere molto altro e alcuni di questi sono difficili da inserire nei commenti (e questi commenti diventano rapidamente obsoleti). In tal caso, un test unitario funziona anche come documentazione.

Un esempio: hai un metodo m (a, b)che esegue un determinato calcolo. A causa dei requisiti di compatibilità con le versioni precedenti, è necessario immettere input in casi speciali di a=0e a=-1, ma solo se bè NULL. Inserirlo in un commento è complicato, dettagliato e rischia di diventare obsoleto se il requisito viene successivamente rimosso.

Se si eseguono alcuni test unitari che controllano il comportamento di m(0, NULL), m(-1, x)si ottengono diversi vantaggi:

  • La descrizione del comportamento corretto è chiara, i malintesi sono ridotti
  • Le persone non possono trascurare il requisito quando cambiano il codice, a differenza di un commento

ma per il tuo esempio, se quel comportamento non è affatto documentato nel commento, un utente potrebbe ottenere risultati imprevisti per quel caso limite. Che non è esattamente una buona cosa.
stijn,

@stijn: True. In tal caso, il modo migliore sarebbe probabilmente quello di avere una breve menzione del caso speciale nei documenti, oltre ai test unitari per i dettagli disordinati.
sleske,
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.