2010-04-20 14 views
33

Sto usando py.test per l'unità test del mio programma python. Desidero eseguire il debug del mio codice di test con il debugger Python nel modo normale (con cui intendo pdb.set_trace() nel codice) ma non riesco a farlo funzionare.È possibile eseguire il debug con Python debugger quando si utilizza py.test in qualche modo?

Inserire pdb.set_trace() nel codice non funziona (solleva IOError: lettura da stdin mentre l'output viene acquisito). Ho anche provato a eseguire py.test con l'opzione --pdb ma non sembra che faccia il trucco se voglio esplorare cosa succede prima della mia affermazione. Si interrompe quando un'affermazione fallisce e passare da quella linea significa terminare il programma.

Qualcuno conosce un modo per ottenere il debug, o esegue il debug e py.test non vuole essere insieme?

risposta

0

Non ho familiarità con py.test, messo per unittest, tu fai quanto segue. Forse py.test è simile:

Nel vostro modulo di test (mytestmodule.py):

if __name__ == "__main__": 
    unittest.main(module="mytestmodule") 

quindi eseguire il test con

python -m pdb mytestmodule.py 

Si otterrà una shell pdb interattivo.

Guardando la documentazione, sembra che py.test ha un'opzione della riga di comando --pdb:

http://codespeak.net/py/dist/test/features.html

+0

Peter, grazie per i vostri suggerimenti. L'alternativa python -m pdb mi guida attraverso lo script ma non chiama le funzioni, quindi sebbene sia utile per il mio sviluppo di Python, non vedo come posso farlo funzionare. Ho menzionato l'opzione --pdb ma a meno che qualcuno non pensi a come usarlo, non posso andare oltre con quello. – Joel

+0

Suggerisco di leggere il manuale su pdb e di imparare i tasti. pdb stamperà la funzione che verrà eseguita successivamente. Se digiti "s", entrerai in quella funzione. Se si digita "n", che è l'impostazione predefinita, si passa alla riga di codice successiva.È molto probabile che stai premendo "n" anziché "s" quando vuoi entrare nella tua routine "principale". –

+2

Non è così che py.test funziona. Piccolo ma valido codice di prova per py.test: def test_arithmetic: asser 2 + 2 == 4 Questo è sufficiente per avere un test unitario. Nessuna routine "principale", solo una funzione che inizia con "test_". Se esegui questo con python normale, definiresti test_arithmetic, non eseguirlo. Ma py.test trova le funzioni che iniziano con test_ e le esegue per me, avendo cura di affermazioni fallite, ecc. – Joel

57

è reale semplice: porre assert 0 in cui si desidera avviare il debug nel codice ed eseguire il test con:

py.test --pdb 

fatto :)

In alternativa, se si utilizza pyt est-2.0.1 o superiore, c'è anche l'helper pytest.set_trace() che puoi inserire ovunque nel tuo codice di test. Ecco lo docs. Sarà necessario disabilitare internamente l'acquisizione prima di inviarti alla riga di comando del debugger pdb.

+0

Questo è ottimo se vuoi solo eseguire il debug di ciò che accade fino all'assert. Sarebbe anche bello se ci fosse py.test.set_trace() (che riabiliterebbe lo stdin e invocherà pdb.set_trace() (o simile). Il problema con assert 0 è che non è possibile (AFAIK) sopprimere l'eccezione e procedere al lavoro con il debugger: sarebbe preferibile un metodo che richiama il debugger che non altera il flusso logico: –

+0

Hey Jason, vedo e accetto, ci dovrebbe essere un "py.test.pdb() "o qualcosa di simile che funziona, con o senza" -s ".Se inoltrate un problema, vedrò di implementarlo. – hpk42

+3

Hey Jason. Ho appena aggiunto py.test.set_trace(), vedere http://bitbucket.org/hpk42/py-trunk/changeset/1d7b0838917f e potresti essere in grado di installare la versione di sviluppo con, ad esempio, "URL di installazione di pip" dove URL è il file zip qui: http: //hudson.testrun. org/view/pytest/job/py-trunk-sdist/(mi dispiace, sembra StackOverflow tronca gli URL male, quindi non è possibile incollare l'intero URL) – hpk42

22

Ho scoperto che posso eseguire py.test con capture disabilitato, quindi utilizzare pdb.set_trace() come al solito.

> py.test --capture=no 
============================= test session starts ============================== 
platform linux2 -- Python 2.5.2 -- pytest-1.3.3 
test path 1: project/lib/test/test_facet.py 

project/lib/test/test_facet.py ...> /home/jaraco/projects/project/lib/functions.py(158)do_something() 
-> code_about_to_run('') 
(Pdb) 
+2

questo è esattamente come ho impostato pdb (piuttosto che --pdb). Nota: puoi usare "-s" invece di "--capture = no" – alfredodeza

+1

Per molti anni, non è più necessario disabilitare l'acquisizione. Basta aggiungere la tua istruzione 'pdb.set_trace()' da qualche parte nello stack di esecuzione. –

12

Il modo più semplice sta usando il meccanismo py.test per creare breakpoint

http://pytest.org/latest/usage.html#setting-a-breakpoint-aka-set-trace

import pytest 
def test_function(): 
    ... 
    pytest.set_trace() # invoke PDB debugger and tracing 

Oppure, se volete pytest s' debugger come un one-liner, cambiare la tua import pdb; pdb.set_trace() in import pytest; pytest.set_trace()

+0

piccola modifica necessaria per '' 'import ipdb; ipdb.set_trace()' '' – Michael

Problemi correlati