Improve quitting from pdb
Regarding tests: it merges ``test_pdb_interaction``, ``test_pdb_print_captured_stdout``, and ``test_pdb_print_captured_stderr`` into ``test_pdb_print_captured_stdout_and_stderr`` (clarity and performance, especially since pexpect tests are slow).
This commit is contained in:
parent
4947eb85c0
commit
e69b1255d7
|
@ -0,0 +1,3 @@
|
|||
Improve quitting from pdb, especially with ``--trace``.
|
||||
|
||||
Using ``q[quit]`` after ``pdb.set_trace()`` will quit pytest also.
|
|
@ -118,6 +118,10 @@ class pytestPDB(object):
|
|||
|
||||
do_c = do_cont = do_continue
|
||||
|
||||
def set_quit(self):
|
||||
super(_PdbWrapper, self).set_quit()
|
||||
outcomes.exit("Quitting debugger")
|
||||
|
||||
def setup(self, f, tb):
|
||||
"""Suspend on setup().
|
||||
|
||||
|
@ -210,8 +214,7 @@ def _enter_pdb(node, excinfo, rep):
|
|||
tw.sep(">", "entering PDB")
|
||||
tb = _postmortem_traceback(excinfo)
|
||||
rep._pdbshown = True
|
||||
if post_mortem(tb):
|
||||
outcomes.exit("Quitting debugger")
|
||||
post_mortem(tb)
|
||||
return rep
|
||||
|
||||
|
||||
|
@ -242,4 +245,5 @@ def post_mortem(t):
|
|||
p = Pdb()
|
||||
p.reset()
|
||||
p.interaction(None, t)
|
||||
return p.quitting
|
||||
if p.quitting:
|
||||
outcomes.exit("Quitting debugger")
|
||||
|
|
|
@ -49,13 +49,13 @@ class Failed(OutcomeException):
|
|||
__module__ = "builtins"
|
||||
|
||||
|
||||
class Exit(SystemExit):
|
||||
class Exit(Exception):
|
||||
""" raised for immediate program exits (no tracebacks/summaries)"""
|
||||
|
||||
def __init__(self, msg="unknown reason", returncode=None):
|
||||
self.msg = msg
|
||||
self.returncode = returncode
|
||||
SystemExit.__init__(self, msg)
|
||||
super(Exit, self).__init__(msg)
|
||||
|
||||
|
||||
# exposed helper methods
|
||||
|
@ -63,7 +63,7 @@ class Exit(SystemExit):
|
|||
|
||||
def exit(msg, returncode=None):
|
||||
"""
|
||||
Exit testing process as if SystemExit was triggered.
|
||||
Exit testing process.
|
||||
|
||||
:param str msg: message to display upon exit.
|
||||
:param int returncode: return code to be used when exiting pytest.
|
||||
|
|
|
@ -147,29 +147,6 @@ class TestPDB(object):
|
|||
assert rep.failed
|
||||
assert len(pdblist) == 1
|
||||
|
||||
def test_pdb_interaction(self, testdir):
|
||||
p1 = testdir.makepyfile(
|
||||
"""
|
||||
def test_1():
|
||||
i = 0
|
||||
assert i == 1
|
||||
|
||||
def test_not_called_due_to_quit():
|
||||
pass
|
||||
"""
|
||||
)
|
||||
child = testdir.spawn_pytest("--pdb %s" % p1)
|
||||
child.expect(".*def test_1")
|
||||
child.expect(".*i = 0")
|
||||
child.expect("Pdb")
|
||||
child.sendeof()
|
||||
rest = child.read().decode("utf8")
|
||||
assert "= 1 failed in" in rest
|
||||
assert "def test_1" not in rest
|
||||
assert "Exit: Quitting debugger" in rest
|
||||
assert "PDB continue (IO-capturing resumed)" not in rest
|
||||
self.flush(child)
|
||||
|
||||
@staticmethod
|
||||
def flush(child):
|
||||
if platform.system() == "Darwin":
|
||||
|
@ -214,40 +191,32 @@ class TestPDB(object):
|
|||
child.sendeof()
|
||||
self.flush(child)
|
||||
|
||||
def test_pdb_print_captured_stdout(self, testdir):
|
||||
p1 = testdir.makepyfile(
|
||||
"""
|
||||
def test_1():
|
||||
print("get\\x20rekt")
|
||||
assert False
|
||||
"""
|
||||
)
|
||||
child = testdir.spawn_pytest("--pdb %s" % p1)
|
||||
child.expect("captured stdout")
|
||||
child.expect("get rekt")
|
||||
child.expect("Pdb")
|
||||
child.sendeof()
|
||||
rest = child.read().decode("utf8")
|
||||
assert "1 failed" in rest
|
||||
assert "get rekt" not in rest
|
||||
self.flush(child)
|
||||
|
||||
def test_pdb_print_captured_stderr(self, testdir):
|
||||
def test_pdb_print_captured_stdout_and_stderr(self, testdir):
|
||||
p1 = testdir.makepyfile(
|
||||
"""
|
||||
def test_1():
|
||||
import sys
|
||||
sys.stderr.write("get\\x20rekt")
|
||||
print("get\\x20rekt")
|
||||
assert False
|
||||
|
||||
def test_not_called_due_to_quit():
|
||||
pass
|
||||
"""
|
||||
)
|
||||
child = testdir.spawn_pytest("--pdb %s" % p1)
|
||||
child.expect("captured stdout")
|
||||
child.expect("get rekt")
|
||||
child.expect("captured stderr")
|
||||
child.expect("get rekt")
|
||||
child.expect("traceback")
|
||||
child.expect("def test_1")
|
||||
child.expect("Pdb")
|
||||
child.sendeof()
|
||||
rest = child.read().decode("utf8")
|
||||
assert "1 failed" in rest
|
||||
assert "Exit: Quitting debugger" in rest
|
||||
assert "= 1 failed in" in rest
|
||||
assert "def test_1" not in rest
|
||||
assert "get rekt" not in rest
|
||||
self.flush(child)
|
||||
|
||||
|
@ -375,15 +344,17 @@ class TestPDB(object):
|
|||
i = 0
|
||||
print("hello17")
|
||||
pytest.set_trace()
|
||||
x = 3
|
||||
i == 1
|
||||
assert 0
|
||||
"""
|
||||
)
|
||||
child = testdir.spawn_pytest(str(p1))
|
||||
child.expect("test_1")
|
||||
child.expect("x = 3")
|
||||
child.expect(r"test_1\(\)")
|
||||
child.expect("i == 1")
|
||||
child.expect("Pdb")
|
||||
child.sendeof()
|
||||
child.sendline("c")
|
||||
rest = child.read().decode("utf-8")
|
||||
assert "AssertionError" in rest
|
||||
assert "1 failed" in rest
|
||||
assert "def test_1" in rest
|
||||
assert "hello17" in rest # out is captured
|
||||
|
@ -398,13 +369,14 @@ class TestPDB(object):
|
|||
print("hello17")
|
||||
pytest.set_trace(header="== my_header ==")
|
||||
x = 3
|
||||
assert 0
|
||||
"""
|
||||
)
|
||||
child = testdir.spawn_pytest(str(p1))
|
||||
child.expect("== my_header ==")
|
||||
assert "PDB set_trace" not in child.before.decode()
|
||||
child.expect("Pdb")
|
||||
child.sendeof()
|
||||
child.sendline("c")
|
||||
rest = child.read().decode("utf-8")
|
||||
assert "1 failed" in rest
|
||||
assert "def test_1" in rest
|
||||
|
@ -424,9 +396,9 @@ class TestPDB(object):
|
|||
child.expect("Pdb")
|
||||
child.sendeof()
|
||||
rest = child.read().decode("utf8")
|
||||
assert "1 failed" in rest
|
||||
assert "no tests ran" in rest
|
||||
assert "reading from stdin while output" not in rest
|
||||
assert "BdbQuit" in rest
|
||||
assert "BdbQuit" not in rest
|
||||
self.flush(child)
|
||||
|
||||
def test_pdb_and_capsys(self, testdir):
|
||||
|
@ -518,6 +490,7 @@ class TestPDB(object):
|
|||
print("hello18")
|
||||
pytest.set_trace()
|
||||
x = 4
|
||||
assert 0
|
||||
"""
|
||||
)
|
||||
child = testdir.spawn_pytest(str(p1))
|
||||
|
@ -530,11 +503,11 @@ class TestPDB(object):
|
|||
child.expect(r"PDB set_trace \(IO-capturing turned off\)")
|
||||
child.expect("x = 4")
|
||||
child.expect("Pdb")
|
||||
child.sendeof()
|
||||
child.sendline("c")
|
||||
child.expect("_ test_1 _")
|
||||
child.expect("def test_1")
|
||||
child.expect("Captured stdout call")
|
||||
rest = child.read().decode("utf8")
|
||||
assert "Captured stdout call" in rest
|
||||
assert "hello17" in rest # out is captured
|
||||
assert "hello18" in rest # out is captured
|
||||
assert "1 failed" in rest
|
||||
|
@ -795,7 +768,7 @@ class TestDebuggingBreakpoints(object):
|
|||
child.expect("Pdb")
|
||||
child.sendeof()
|
||||
rest = child.read().decode("utf8")
|
||||
assert "1 failed" in rest
|
||||
assert "Quitting debugger" in rest
|
||||
assert "reading from stdin while output" not in rest
|
||||
TestPDB.flush(child)
|
||||
|
||||
|
@ -808,12 +781,13 @@ class TestDebuggingBreakpoints(object):
|
|||
import pdb
|
||||
def test_1():
|
||||
pdb.set_trace()
|
||||
assert 0
|
||||
"""
|
||||
)
|
||||
child = testdir.spawn_pytest(str(p1))
|
||||
child.expect("test_1")
|
||||
child.expect("Pdb")
|
||||
child.sendeof()
|
||||
child.sendline("c")
|
||||
rest = child.read().decode("utf8")
|
||||
assert "1 failed" in rest
|
||||
assert "reading from stdin while output" not in rest
|
||||
|
@ -826,15 +800,29 @@ class TestTraceOption:
|
|||
"""
|
||||
def test_1():
|
||||
assert True
|
||||
|
||||
def test_2():
|
||||
pass
|
||||
|
||||
def test_3():
|
||||
pass
|
||||
"""
|
||||
)
|
||||
child = testdir.spawn_pytest("--trace " + str(p1))
|
||||
child.expect("test_1")
|
||||
child.expect("Pdb")
|
||||
child.sendeof()
|
||||
child.sendline("c")
|
||||
child.expect("test_2")
|
||||
child.expect("Pdb")
|
||||
child.sendline("c")
|
||||
child.expect("test_3")
|
||||
child.expect("Pdb")
|
||||
child.sendline("q")
|
||||
child.expect_exact("Exit: Quitting debugger")
|
||||
rest = child.read().decode("utf8")
|
||||
assert "1 passed" in rest
|
||||
assert "2 passed in" in rest
|
||||
assert "reading from stdin while output" not in rest
|
||||
assert "Exit: Quitting debugger" in child.before.decode("utf8")
|
||||
TestPDB.flush(child)
|
||||
|
||||
|
||||
|
@ -863,3 +851,31 @@ def test_trace_after_runpytest(testdir):
|
|||
rest = child.read().decode("utf8")
|
||||
TestPDB.flush(child)
|
||||
assert child.exitstatus == 0, rest
|
||||
|
||||
|
||||
def test_quit_with_swallowed_SystemExit(testdir):
|
||||
"""Test that debugging's pytest_configure is re-entrant."""
|
||||
p1 = testdir.makepyfile(
|
||||
"""
|
||||
def call_pdb_set_trace():
|
||||
__import__('pdb').set_trace()
|
||||
|
||||
|
||||
def test_1():
|
||||
try:
|
||||
call_pdb_set_trace()
|
||||
except SystemExit:
|
||||
pass
|
||||
|
||||
|
||||
def test_2():
|
||||
pass
|
||||
"""
|
||||
)
|
||||
child = testdir.spawn_pytest(str(p1))
|
||||
child.expect("Pdb")
|
||||
child.sendline("q")
|
||||
child.expect_exact("Exit: Quitting debugger")
|
||||
rest = child.read().decode("utf8")
|
||||
assert "no tests ran" in rest
|
||||
TestPDB.flush(child)
|
||||
|
|
Loading…
Reference in New Issue