2013-06-07 12 views
6

... e un pony! No sul serio. Sto cercando un modo per organizzare test che "funziona". La maggior parte delle cose funziona, ma non tutti i pezzi si incastrano. Quindi ecco cosa voglio:Rilevamento test Python con doctest, copertura e parallelismo

  • Avendo rilevato automaticamente i test. Questo include doctest. Si noti che la somma dei doctest non deve apparire come un singolo test. (non è ciò che py.test --doctest-modules fa)
  • Essere in grado di eseguire test in parallelo. (Qualcosa come py.test -n da xdist)
  • Generazione di un report di copertura.
  • Make python setup.py test solo lavoro.

Il mio approccio attuale prevede una directory tests e load_tests protocol. Tutti i file contenuti sono denominati come test_*.py. Questo rende python -m unittest discover solo lavoro, se creo un file test_doctests.py con il seguente contenuto.

import doctest 
import mymodule1, mymodule2 
def load_tests(loader, tests, ignore): 
    tests.addTests(doctest.DocTestSuite(mymodule1)) 
    tests.addTests(doctest.DocTestSuite(mymodule2)) 
    return tests 

Questo approccio ha anche la testa che si può usare setuptools e fornire .

Tuttavia questo approccio ha alcuni problemi.

  • coverage.py si aspetta di eseguire uno script. Quindi non posso usare la scoperta di unittest2 qui.
  • py.test non esegue le funzioni load_tests, quindi non trova i doctest e l'opzione --doctest-modules è una merda.
  • nosetests esegue le funzioni load_tests ma non fornisce alcun parametro. Questo sembra totalmente rotto sul lato del naso.

Come posso far funzionare meglio le cose o risolvere alcuni dei problemi sopra riportati?

+0

Bello. La tua domanda era solo la risposta che stavo cercando. :-) Per quanto riguarda coverage.py: usare 'coverage -m unittest2 discover' dovrebbe funzionare (almeno lo fa per unittest' in Py2.7). –

risposta

1

Io uso il naso e ho trovato la tua domanda quando ho riscontrato lo stesso problema.

Quello con cui ho finito non è bello, ma esegue i test.

import doctest 
import mymodule1, mymodule2 

def test_mymodule1(): 
    assert doctest.testmod(mymodule1, raise_on_error=True) 

def test_mymodule2(): 
    assert doctest.testmod(mymodule2, raise_on_error=True) 

Sfortunatamente esegue tutti i doctest in un modulo come test singolo. Ma se le cose vanno male, almeno so dove cominciare a cercare. Un guasto si traduce in un DocTestFailure, con un messaggio utile:

DocTestFailure: <DocTest mymodule1.myfunc from /path/to/mymodule1.py:63 (4 examples)> 
+0

Mentre funziona con il naso, i messaggi di errore sono una schifezza totale ora. Imo, questo è appena oltre utile. Considero questa soluzione inferiore alla alternativa presentata. –

1

Questa è una vecchia questione, ma il problema persiste per alcuni di noi! Ci stavo solo lavorando e ho trovato una soluzione simile a quella di kaapstorm, ma con un output molto più bello.Io uso py.test per farlo funzionare, ma penso che dovrebbe essere compatibili con tutti i corridori di prova:

import doctest 
from mypackage import mymodule 

def test_doctest(): 
    results = doctest.testmod(mymodule) 
    if results.failed: 
     raise Exception(results) 

Quello che io alla fine con in un caso di fallimento è l'uscita stdout stampato che si otterrebbe da corsa doctest manualmente, con una ulteriore eccezione che assomiglia a questo:

Exception: TestResults(failed=1, attempted=21) 

come kaapstrom detto, non conta test correttamente (a meno che non ci sono errori), ma trovo che non vale un bel po 'a condizione che i numeri di copertura tornano alta:)