drop into an interactive session to examine a failed unit test - python

I'd like to be able to enter an interactive session, preferably with IPython, if a unit test fails. Is there an easy way to do this?
edit: by "interactive session" I mean a full Python REPL rather than a pdb shell.
edit edit: As a further explanation: I'd like to be able to start an interactive session that has access to the context in which the test failure occurred. So for example, the test's self variable would be available.

In IPython, use %pdb before running the test
In [9]: %pdb
Automatic pdb calling has been turned ON

Nosetests runner provides --pdb option that will put you into the debugger session on errors or failures.
http://nose.readthedocs.org/en/latest/usage.html

Are you really sure you want to do this? Your unit tests should do one thing, should be well-named, and should clearly print what failed. If you do all of that, the failure message will pinpoint what went wrong; no need to go look at it interactively. In fact, one of the big advantages of TDD is that it helps you avoid having to go into the debugger at all to diagnose problems.

Related

How do I exit from pdb debugging when running hypothesis?

I like using hypothesis for my unit tests. I also like using pdb for debugging when things go wrong. But trying to use these two together can be very annoying. If I set a breakpoint in a file that is run by hypothesis using pytest <PATH-TO-FILE> -s, it will stop at the breakpoint as expected, and I can do my analysis. But after I am done, I want to be able to exit out of the test. However, if I do ctrl+c from inside the breakpoint, the test doesn't quit, it simply goes to the next hypothesis test case. And I have to keep doing this until hypothesis is done generating all it's test cases.
I usually end up opening system monitor and killing the pytest process everytime I want to be able to quit the test.
I'm hoping there is a better way.
The issue can be reproduced by the following snippet -
import hypothesis
from hypothesis import strategies as st
#hypothesis.given(st.integers())
def test_some_function(some_arg):
breakpoint()
print(some_arg)
test_some_function()
I am using python 3.8 with hypothesis 5.37.0
This happens under Linux but not under Windows, and it's unclear whether or not that's a bug in Hypothesis, or in Pdb, or 'just' undesirable behaviour from a combination of features.
As a workaround, you can import os; os._exit(0) to skip all cleanup logic and exit instantly.
A better, albeit somewhat more involved, solution is to disable multi-bug reporting and the shrinking phase when you use a debugger, so that Hypothesis stops generating examples immediately after the first failure. You can create a settings profile for use with the debugger, and then activate it via the --hypothesis-profile= argument to pytest.

How do you debug pydoit?

I have a python doit script that is getting stuck on one step but doesn't throw an error. It would sit all day if I let it. I've checked all the inputs and they look exactly the same as the last time I ran it. How do I debug? I tried using pdb but maybe I don't know how to use it and I googled and couldn't find example code. I can't post my code since its confidential. Just a general how to debug in doit would help me greatly. I use Python 2.7 and yes eventually I'll have to update to 3 but for now I'm using 2.7. (Sorry I have had quite a few ask why I continue with 2.7--- no time right now to update all my scripts, there are over 200)
https://pydoit.org/tools.html#set-trace
doit provides a set_trace() function that will call PDB set_trace and make sure stdout output is printed on terminal.
Not your case, but doit also provides a command line option --pdb that automatically drops in PDB when an unhandled exception occurs.

How can I tell pytest-dependency to temporarily ignore test dependencies?

I've got a functional test suite using pytest-dependency to skip tests when other tests they depend on fail. That way, for example, if the login page is broken, I get one test failure saying "The login page is broken" instead of a slew of test failures saying "I couldn't log into user X", "I couldn't log into user Y", etc.
This works great for running the entire suite, but I'm trying to shorten my edit-compile-test loop, and right now the slowest point is testing my tests. If the test I'm working on has a bunch of other tests it depends on, they all have to succeed in order to not skip the test I'm trying to test. So, I either have to run the entire dependency tree, or comment out my #pytest.mark.dependency(...) decorators (which is an additional thing that I, as a human, have to remember to do). Technically there's nothing these depended-on tests do that enables their dependers to run - the only reason I want these dependencies at all is to make it easier for me to triage test failures.
Is there a command-line argument that would tell pytest-dependency to not skip things on account of dependents, or to tell pytest to not use the pytest-dependency plugin on this run (and this run only)?
The -p option allows disabling a particular plugin:
pytest -p no:dependency

Why python debugger always get this timeout waiting for response on 113 when using Pycharm?

Bigger image
Especially I run code perhaps running a little long time(10 mins roughly), and hit the break point.
The python debugger always show me this kind of error "timeout waiting for response on 113"
I circle them in red in screencut.
And I use Pycharm as my python IDE, is it just issue for Pycharm IDE? Or Python debugger issue?
And if Pycharm is not recommended, can anyone give me better IDE which be able to debug efficiently.
I had a similar thing happen to me a few months ago, it turned out I had a really slow operation within a __repr__() for a variable I had on the stack. When PyCharm hits a breakpoint it grabs all of the variables in the current scope and calls __repr__ on them. Here's an amusement that demonstrates this issue:
import time
class Foo(object):
def __repr__(self):
time.sleep(100)
return "look at me"
if __name__ == '__main__':
a = Foo()
print "set your breakpoint here"
PyCharm will also call __getattribute__('__class__'). If you have a __getattribute__ that's misbehaving that could trip you up as well.
This may not be what's happening to you but perhaps worth considering.
As you are on Windows, for debugging such & most things I use the good old PythonWin IDE:
This IDE + Debugger runs in the same process as the debugged stuff!
This way, being in direct touch with real objects, like pdb in simple interactive shell, but having a usable GUI, is a big advantage most of the time. And this way there are no issues of transferring vast objects via repr/pickle or so between processes, no delays, no issues of timeouts etc.
If a step takes a long time, PythonWin will also simply wait and not respond before ... (unless one issues a break signal/KeyboardInterrupt via the PythonWin system tray icon).
And the interactive shell of PythonWin is also fully usable during the debugging - with namespace inside the current frame.
It's an old question but reply can be helpful.
Delete the .idea folder from the project root dir. It will clean up the Pycharm's database and the debugger will stop timing out. It works for me on Windows.

stopping execution of Python program on exception in ipython

I have a long running Python program that raises exception at some point. Is there some way to run this from ipython session and stop on the exception so I could examine the live data?
You may want ipython -i yourscript.py, which will execute your script in the interpreter environment. But this won't let you inspect the local environment where the exception happened, for example local variables within a function – you'll just be able to inspect globals. You probably want this instead:
In [1]: %run test.py
<exception occurs>
In [2]: %debug test.py
If you're not familiar with using PDB, check out some docs first.
Edit thanks to Thomas K
yes, depending on how you are setup. you can import your program and run it like any other module inside a try except block.
import yourprogram
try:
yourprogram.main_function(args)
except:
print "we blew up, investigate why"
If your program is not in a function you may need to put the try block around your import.
The problem with this approach is that the variables you are wanting to look at may be no longer in scope. I usually use print statements or log messages at various points to figure out what is not looking like I am expecting.

Categories