Risposte:
Entrambi sono preziosi. Uso sia doctest che nose prendendo il posto di unittest. Uso doctest per i casi in cui il test fornisce un esempio di utilizzo che è effettivamente utile come documentazione. Generalmente non faccio questi test completi, mirando esclusivamente a informazioni. Sto effettivamente usando doctest al contrario: non per testare il mio codice è corretto in base al mio doctest, ma per verificare che la mia documentazione sia corretta in base al codice.
Il motivo è che trovo che un completo test dei documenti ingombrerà troppo la tua documentazione, quindi finirai con docstrings inutilizzabili o test incompleti.
Per testare effettivamente il codice , l'obiettivo è quello di testare accuratamente ogni caso, piuttosto che illustrare ciò che fa l'esempio, che è un obiettivo diverso che penso sia meglio raggiunto da altri framework.
Uso unittest quasi esclusivamente.
Di tanto in tanto, inserirò alcune cose in una dotstring utilizzabile da doctest.
Il 95% dei casi di test è meno complicato.
Perché? Mi piace mantenere le dotstring un po 'più brevi e più precise. A volte i casi di test aiutano a chiarire una dotstring. Il più delle volte, i casi di test dell'applicazione sono troppo lunghi per una docstring.
docstring
e cosa no. In realtà mi piace docstring in termini che mostra esplicitamente come usare un'interfaccia, ma usarlo sia per quello che per i test unitari potrebbe non adattarsi bene.
Un altro vantaggio del doctesting è che puoi assicurarti che il tuo codice faccia quello che dice la tua documentazione. Dopo un po ', le modifiche al software possono far sì che la documentazione e il codice facciano cose diverse. :-)
Lavoro come bioinformatico e la maggior parte del codice che scrivo è script "una volta, un compito", codice che verrà eseguito solo una o due volte e che eseguirà un singolo compito specifico.
In questa situazione, scrivere grandi unittest può essere eccessivo e i doctest sono un utile compromesso. Sono più veloci da scrivere e, poiché di solito sono incorporati nel codice, consentono di tenere sempre d'occhio il comportamento del codice, senza dover aprire un altro file. È utile quando si scrive una piccola sceneggiatura.
Inoltre, i doctest sono utili quando devi passare la tua sceneggiatura a un ricercatore che non è esperto in programmazione. Alcune persone trovano molto difficile capire come sono strutturati gli unittest; d'altra parte, i doctest sono semplici esempi di utilizzo, quindi le persone possono semplicemente copiarli e incollarli per vedere come usarli.
Quindi, per riprendere la mia risposta: i doctest sono utili quando devi scrivere piccoli script e quando devi passarli o mostrarli ai ricercatori che non sono informatici.
Se hai appena iniziato con l'idea del test unitario, inizierei doctest
perché è così semplice da usare. Inoltre fornisce naturalmente un certo livello di documentazione. E per test più completi con doctest
, è possibile posizionare i test in un file esterno in modo da non ingombrare la documentazione.
Vorrei suggerire unittest
se provieni da un passato in cui hai utilizzato JUnit o qualcosa di simile, in cui vuoi essere in grado di scrivere test unitari in generale allo stesso modo in cui sei stato altrove.
doctest
per cominciare), ma alla fine me ne sono pentito. Per casi di test non banali, ho perso l'evidenziazione della sintassi e il completamento automatico del mio editor. Quando i test erano in un file separato, non potevo più eseguirlo direttamente dall'editor: avrei dovuto cambiare contesto ogni volta al file sorgente corrispondente.
Uso unittest esclusivamente; Penso che i doctest ingombrino troppo il modulo principale. Questo probabilmente ha a che fare con la scrittura di test approfonditi.
L'uso di entrambi è un'opzione valida e piuttosto semplice. Il doctest
modulo fornisce i metodi DoctTestSuite
e DocFileSuite
che creano rispettivamente una suite di test compatibile unittest da un modulo o un file.
Quindi uso entrambi e in genere uso doctest per test semplici con funzioni che richiedono una configurazione minima o nulla (tipi semplici per argomenti). In realtà penso che alcuni test doctest aiutino a documentare la funzione, piuttosto che a toglierla.
Ma per i casi più complicati e per una serie più completa di casi di test, utilizzo unittest che offre maggiore controllo e flessibilità.
Non uso doctest in sostituzione di unittest. Sebbene si sovrappongano un po ', i due moduli non hanno la stessa funzione:
Uso unittest
come framework di unit test, il che significa che mi aiuta a determinare rapidamente l'impatto di qualsiasi modifica sul resto del codice.
Uso doctest
come garanzia che i commenti (in particolare i docstring) siano ancora rilevanti per la versione corrente del codice.
I vantaggi ampiamente documentati dello sviluppo guidato dai test che ottengo unittest
. doctest
risolve il pericolo molto più sottile di avere commenti obsoleti che fuorviano il mantenimento del codice.
Non uso quasi mai i doctest. Voglio che il mio codice sia auto-documentato e i docstring forniscono la documentazione all'utente. L'IMO che aggiunge centinaia di righe di test a un modulo rende le dotstring molto meno leggibili. Trovo anche i test unitari più facili da modificare quando necessario.
Doctest
a volte può portare a risultati errati. Soprattutto quando l'output contiene sequenze di escape. Per esempio
def convert():
"""
>>> convert()
'\xe0\xa4\x95'
"""
a = '\xe0\xa4\x95'
return a
import doctest
doctest.testmod()
dà
**********************************************************************
File "hindi.py", line 3, in __main__.convert
Failed example:
convert()
Expected:
'क'
Got:
'\xe0\xa4\x95'
**********************************************************************
1 items had failures:
1 of 1 in __main__.convert
***Test Failed*** 1 failures.
Inoltre non controlla il tipo di output. Confronta solo le stringhe di output. Ad esempio, ha reso razionale un tipo che viene stampato come intero se è un numero intero. Supponiamo quindi di avere una funzione che ritorna razionale. Quindi, un doctest non farà distinzione se l'output è un numero intero razionale o un numero intero.
r""" ... """
) per risolvere il primo problema.
'\\xe0\\xa4\\x95'
nella tua documentazione.
Preferisco i sistemi basati sulla scoperta ("nose" e "py.test", usando attualmente il primo).
doctest è utile quando il test è valido anche come documentazione, altrimenti tendono a ingombrare troppo il codice.