Gli asserti sono utili per parlarti dello stato interno del programma . Ad esempio, che le strutture dei dati abbiano uno stato valido, ad esempio, che una Time
struttura di dati non detenga il valore di 25:61:61
. Le condizioni controllate dalle asserzioni sono:
Presupposti, che assicurano che il chiamante mantenga il suo contratto,
Postcondizioni, che assicurano che la chiamata mantenga il suo contratto, e
Invarianti, che assicurano che la struttura dei dati abbia sempre delle proprietà dopo il ritorno della funzione. Un invariante è una condizione che è una precondizione e una postcondizione.
I test unitari sono utili per parlarti del comportamento esterno del modulo . Potresti Stack
avere uno stato coerente dopo push()
che è stato chiamato il metodo, ma se la dimensione dello stack non aumenta di tre dopo che è stato chiamato tre volte, questo è un errore. (Ad esempio, il caso banale in cui l' push()
implementazione errata controlla solo le affermazioni e le uscite.)
A rigor di termini, la principale differenza tra assert e unit test è che i test unitari hanno dati di test (valori per far funzionare il programma), mentre gli assert no. Cioè, puoi eseguire i test unitari automaticamente, mentre non puoi dire lo stesso per le asserzioni. Per motivi di questa discussione, ho assunto che tu stia parlando dell'esecuzione del programma nel contesto di test funzionali di ordine superiore (che eseguono l'intero programma e non guidano moduli come unit test). Se non stai parlando di test funzionali automatizzati come mezzo per "vedere input reali", allora chiaramente il valore risiede nell'automazione e quindi i test unitari vincerebbero. Se ne stai parlando nel contesto di test funzionali (automatizzati), vedi sotto.
Ci può essere qualche sovrapposizione in ciò che viene testato. Ad esempio, Stack
il postcondition di a potrebbe effettivamente affermare che la dimensione dello stack aumenta di uno. Ma ci sono limiti a ciò che può essere eseguito in tale asserzione: dovrebbe anche verificare che l'elemento superiore sia ciò che è stato appena aggiunto?
Per entrambi, l'obiettivo è aumentare la qualità. Per i test unitari, l'obiettivo è trovare i bug. Per asserzioni, l'obiettivo è quello di rendere più semplice il debug osservando gli stati di programma non validi non appena si verificano.
Si noti che nessuna delle due tecniche verifica la correttezza. In effetti, se si eseguono test di unità con l'obiettivo di verificare che il programma sia corretto, è probabile che si verifichino test poco interessanti che si sa funzioneranno. È un effetto psicologico: farai qualunque cosa per raggiungere il tuo obiettivo. Se il tuo obiettivo è trovare bug, le tue attività lo rifletteranno.
Entrambi sono importanti e hanno i loro scopi.
[Come nota finale sulle asserzioni: per ottenere il massimo valore, è necessario utilizzarle in tutti i punti critici del programma e non in alcune funzioni chiave. Altrimenti, la fonte originale del problema potrebbe essere stata mascherata e difficile da rilevare senza ore di debug.]
:-)