views:

111

answers:

3

I am using py.test for unit testing my python program. I wish to debug my test code with the python debugger the normal way (by which i mean pdb.set_trace() in the code) but I can't make it work.

Putting pdb.set_trace() in the code doesn't work (raises IOError: reading from stdin while output is captured). I have also tried running py.test with the option --pdb but that doesn't seem to do the trick if I want to explore what happens before my assertion. It breaks when an assertion fails, and moving on from that line means terminating the program.

Does anyone know a way to get debugging, or is debugging and py.test just not meant to be together?

A: 

I'm not familiar with py.test, put for unittest, you do the following. Maybe py.test is similar:

In your test module (mytestmodule.py):

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

Then run the test with

python -m pdb mytestmodule.py

You will get an interactive pdb shell.

Looking at the docs, it looks like py.test has a --pdb command line option:

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

Peter Lyons
Peter, thank you for your suggestions.The python -m pdb alternative walks me through the script but doesn't call the functions, so although useful for my Python development, I don't see how I can make that one work.I mentioned the --pdb option but unless someone can think of how to use it, I can't go further with that one either.
Joel
I suggest reading the manual on pdb and learning the keystrokes. pdb will print the function that will execute next. If you type "s", you will step into that function. If you type "n", which is the default, you just go to the next line of code. It is very likely that you are hitting "n" instead of "s" when you want to step into your "main" routine.
Peter Lyons
That's not how py.test works. Small but valid test code for py.test: def test_arithmetic: assert 2+2==4That's enough to have a unit test. No "main" routine, just a function that starts with "test_". If run this with normal python, it would just define test_arithmetic, not run it. But py.test finds functions starting with test_ and runs them for me, taking care of failed asserts etc.
Joel
A: 

it's real simple: put an "assert 0" where you want to start debugging in your code and run your tests with:

py.test --pdb 

done :)

hpk42
This is great if you want to only want to debug what happens up to the assert. It would also be nice if there was a py.test.set_trace() (which would re-enable the stdin and invoke pdb.set_trace() (or similar). The problem with assert 0 is that it's not possible (AFAIK) to suppress the exception and proceed to work with the debugger. A method that invokes the debugger that doesn't alter the logic flow would be preferable.
Jason R. Coombs
Hey Jason. I see and agree. There should be a "py.test.pdb()" or something similar that just works, with or without "-s". If you file an issue, i'll see to go for implementing it.
hpk42
Hey Jason. I've just added py.test.set_trace() , see http://bitbucket.org/hpk42/py-trunk/changeset/1d7b0838917f and you might be able to install the development version with e.g. "pip install URL" where URL is the zip file here: http://hudson.testrun.org/view/pytest/job/py-trunk-sdist/ (sorry, seems StackOverflow truncates URLs badly, so can't paste the full URL)
hpk42
A: 

I found that I can run py.test with capture disabled, then use pdb.set_trace() as usual.

> 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)
Jason R. Coombs