test_ok1/testing/test_pdb.py

952 lines
28 KiB
Python
Raw Normal View History

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
2018-03-22 17:40:35 +08:00
import os
import platform
import sys
import _pytest._code
import pytest
try:
breakpoint
except NameError:
SUPPORTS_BREAKPOINT_BUILTIN = False
else:
SUPPORTS_BREAKPOINT_BUILTIN = True
2018-05-23 22:48:46 +08:00
_ENVIRON_PYTHONBREAKPOINT = os.environ.get("PYTHONBREAKPOINT", "")
def runpdb_and_get_report(testdir, source):
p = testdir.makepyfile(source)
result = testdir.runpytest_inprocess("--pdb", p)
reports = result.reprec.getreports("pytest_runtest_logreport")
assert len(reports) == 3, reports # setup/call/teardown
return reports[1]
2016-09-20 00:05:57 +08:00
@pytest.fixture
def custom_pdb_calls():
called = []
# install dummy debugger class and track which methods were called on it
class _CustomPdb(object):
quitting = False
2016-09-20 00:05:57 +08:00
def __init__(self, *args, **kwargs):
called.append("init")
def reset(self):
called.append("reset")
def interaction(self, *args):
called.append("interaction")
_pytest._CustomPdb = _CustomPdb
return called
@pytest.fixture
def custom_debugger_hook():
called = []
# install dummy debugger class and track which methods were called on it
class _CustomDebugger(object):
def __init__(self, *args, **kwargs):
called.append("init")
def reset(self):
called.append("reset")
def interaction(self, *args):
called.append("interaction")
def set_trace(self, frame):
print("**CustomDebugger**")
called.append("set_trace")
_pytest._CustomDebugger = _CustomDebugger
yield called
del _pytest._CustomDebugger
class TestPDB(object):
@pytest.fixture
def pdblist(self, request):
monkeypatch = request.getfixturevalue("monkeypatch")
pdblist = []
def mypdb(*args):
pdblist.append(args)
2018-05-23 22:48:46 +08:00
plugin = request.config.pluginmanager.getplugin("debugging")
monkeypatch.setattr(plugin, "post_mortem", mypdb)
return pdblist
def test_pdb_on_fail(self, testdir, pdblist):
2018-05-23 22:48:46 +08:00
rep = runpdb_and_get_report(
testdir,
"""
def test_func():
assert 0
2018-05-23 22:48:46 +08:00
""",
)
assert rep.failed
assert len(pdblist) == 1
tb = _pytest._code.Traceback(pdblist[0][0])
assert tb[-1].name == "test_func"
def test_pdb_on_xfail(self, testdir, pdblist):
2018-05-23 22:48:46 +08:00
rep = runpdb_and_get_report(
testdir,
"""
import pytest
@pytest.mark.xfail
def test_func():
assert 0
2018-05-23 22:48:46 +08:00
""",
)
assert "xfail" in rep.keywords
assert not pdblist
def test_pdb_on_skip(self, testdir, pdblist):
2018-05-23 22:48:46 +08:00
rep = runpdb_and_get_report(
testdir,
"""
import pytest
def test_func():
pytest.skip("hello")
2018-05-23 22:48:46 +08:00
""",
)
assert rep.skipped
assert len(pdblist) == 0
def test_pdb_on_BdbQuit(self, testdir, pdblist):
2018-05-23 22:48:46 +08:00
rep = runpdb_and_get_report(
testdir,
"""
import bdb
def test_func():
raise bdb.BdbQuit
2018-05-23 22:48:46 +08:00
""",
)
assert rep.failed
assert len(pdblist) == 0
def test_pdb_on_KeyboardInterrupt(self, testdir, pdblist):
2018-05-23 22:48:46 +08:00
rep = runpdb_and_get_report(
testdir,
"""
def test_func():
raise KeyboardInterrupt
2018-05-23 22:48:46 +08:00
""",
)
assert rep.failed
assert len(pdblist) == 1
2016-10-22 00:10:35 +08:00
@staticmethod
def flush(child):
2018-05-23 22:48:46 +08:00
if platform.system() == "Darwin":
return
if child.isalive():
child.wait()
def test_pdb_unittest_postmortem(self, testdir):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
import unittest
class Blub(unittest.TestCase):
def tearDown(self):
self.filename = None
def test_false(self):
self.filename = 'debug' + '.me'
assert 0
2018-05-23 22:48:46 +08:00
"""
)
child = testdir.spawn_pytest("--pdb %s" % p1)
child.expect("Pdb")
2018-05-23 22:48:46 +08:00
child.sendline("p self.filename")
child.sendeof()
rest = child.read().decode("utf8")
2018-05-23 22:48:46 +08:00
assert "debug.me" in rest
2016-10-22 00:10:35 +08:00
self.flush(child)
def test_pdb_unittest_skip(self, testdir):
"""Test for issue #2137"""
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
import unittest
@unittest.skipIf(True, 'Skipping also with pdb active')
class MyTestCase(unittest.TestCase):
def test_one(self):
assert 0
2018-05-23 22:48:46 +08:00
"""
)
child = testdir.spawn_pytest("-rs --pdb %s" % p1)
2018-05-23 22:48:46 +08:00
child.expect("Skipping also with pdb active")
child.expect("1 skipped in")
child.sendeof()
self.flush(child)
def test_pdb_print_captured_stdout_and_stderr(self, testdir):
2018-05-23 22:48:46 +08:00
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
2018-05-23 22:48:46 +08:00
"""
)
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 "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)
def test_pdb_dont_print_empty_captured_stdout_and_stderr(self, testdir):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
def test_1():
assert False
2018-05-23 22:48:46 +08:00
"""
)
child = testdir.spawn_pytest("--pdb %s" % p1)
child.expect("Pdb")
output = child.before.decode("utf8")
child.sendeof()
assert "captured stdout" not in output
assert "captured stderr" not in output
2016-10-22 00:10:35 +08:00
self.flush(child)
2018-05-23 22:48:46 +08:00
@pytest.mark.parametrize("showcapture", ["all", "no", "log"])
def test_pdb_print_captured_logs(self, testdir, showcapture):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
def test_1():
import logging
logging.warn("get " + "rekt")
assert False
2018-05-23 22:48:46 +08:00
"""
)
2018-08-23 09:30:42 +08:00
child = testdir.spawn_pytest(
"--show-capture={} --pdb {}".format(showcapture, p1)
)
2018-05-23 22:48:46 +08:00
if showcapture in ("all", "log"):
child.expect("captured log")
child.expect("get rekt")
child.expect("Pdb")
child.sendeof()
rest = child.read().decode("utf8")
assert "1 failed" in rest
self.flush(child)
def test_pdb_print_captured_logs_nologging(self, testdir):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
def test_1():
import logging
logging.warn("get " + "rekt")
assert False
2018-05-23 22:48:46 +08:00
"""
)
2018-10-11 06:53:21 +08:00
child = testdir.spawn_pytest("--show-capture=all --pdb -p no:logging %s" % p1)
child.expect("get rekt")
output = child.before.decode("utf8")
assert "captured log" not in output
child.expect("Pdb")
child.sendeof()
rest = child.read().decode("utf8")
assert "1 failed" in rest
self.flush(child)
def test_pdb_interaction_exception(self, testdir):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
import pytest
def globalfunc():
pass
def test_1():
pytest.raises(ValueError, globalfunc)
2018-05-23 22:48:46 +08:00
"""
)
child = testdir.spawn_pytest("--pdb %s" % p1)
child.expect(".*def test_1")
child.expect(".*pytest.raises.*globalfunc")
child.expect("Pdb")
child.sendline("globalfunc")
child.expect(".*function")
child.sendeof()
child.expect("1 failed")
2016-10-22 00:10:35 +08:00
self.flush(child)
def test_pdb_interaction_on_collection_issue181(self, testdir):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
import pytest
xxx
2018-05-23 22:48:46 +08:00
"""
)
child = testdir.spawn_pytest("--pdb %s" % p1)
# child.expect(".*import pytest.*")
child.expect("Pdb")
child.sendline("c")
child.expect("1 error")
2016-10-22 00:10:35 +08:00
self.flush(child)
def test_pdb_interaction_on_internal_error(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makeconftest(
"""
def pytest_runtest_protocol():
0/0
2018-05-23 22:48:46 +08:00
"""
)
p1 = testdir.makepyfile("def test_func(): pass")
child = testdir.spawn_pytest("--pdb %s" % p1)
child.expect("Pdb")
# INTERNALERROR is only displayed once via terminal reporter.
2018-10-14 09:13:25 +08:00
assert (
len(
[
x
for x in child.before.decode().splitlines()
if x.startswith("INTERNALERROR> Traceback")
]
)
== 1
)
child.sendeof()
2016-10-22 00:10:35 +08:00
self.flush(child)
def test_pdb_interaction_capturing_simple(self, testdir):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
import pytest
def test_1():
i = 0
2018-10-13 22:42:33 +08:00
print("hello17")
pytest.set_trace()
i == 1
assert 0
2018-05-23 22:48:46 +08:00
"""
)
child = testdir.spawn_pytest(str(p1))
child.expect(r"test_1\(\)")
child.expect("i == 1")
child.expect("Pdb")
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
2016-10-22 00:10:35 +08:00
self.flush(child)
def test_pdb_set_trace_kwargs(self, testdir):
p1 = testdir.makepyfile(
"""
import pytest
def test_1():
i = 0
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.sendline("c")
rest = child.read().decode("utf-8")
assert "1 failed" in rest
assert "def test_1" in rest
assert "hello17" in rest # out is captured
self.flush(child)
def test_pdb_set_trace_interception(self, testdir):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
import pdb
def test_1():
pdb.set_trace()
2018-05-23 22:48:46 +08:00
"""
)
child = testdir.spawn_pytest(str(p1))
child.expect("test_1")
child.expect("Pdb")
child.sendeof()
rest = child.read().decode("utf8")
assert "no tests ran" in rest
assert "reading from stdin while output" not in rest
assert "BdbQuit" not in rest
2016-10-22 00:10:35 +08:00
self.flush(child)
def test_pdb_and_capsys(self, testdir):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
import pytest
def test_1(capsys):
2018-10-13 22:42:33 +08:00
print("hello1")
pytest.set_trace()
2018-05-23 22:48:46 +08:00
"""
)
child = testdir.spawn_pytest(str(p1))
child.expect("test_1")
child.send("capsys.readouterr()\n")
child.expect("hello1")
child.sendeof()
child.read()
2016-10-22 00:10:35 +08:00
self.flush(child)
def test_pdb_with_caplog_on_pdb_invocation(self, testdir):
p1 = testdir.makepyfile(
"""
def test_1(capsys, caplog):
import logging
logging.getLogger(__name__).warning("some_warning")
assert 0
"""
)
child = testdir.spawn_pytest("--pdb %s" % str(p1))
child.send("caplog.record_tuples\n")
child.expect_exact(
"[('test_pdb_with_caplog_on_pdb_invocation', 30, 'some_warning')]"
)
child.sendeof()
child.read()
self.flush(child)
def test_set_trace_capturing_afterwards(self, testdir):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
import pdb
def test_1():
pdb.set_trace()
def test_2():
2018-10-13 22:42:33 +08:00
print("hello")
assert 0
2018-05-23 22:48:46 +08:00
"""
)
child = testdir.spawn_pytest(str(p1))
child.expect("test_1")
child.send("c\n")
child.expect("test_2")
child.expect("Captured")
child.expect("hello")
child.sendeof()
child.read()
2016-10-22 00:10:35 +08:00
self.flush(child)
def test_pdb_interaction_doctest(self, testdir):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
import pytest
def function_1():
'''
>>> i = 0
>>> assert i == 1
'''
2018-05-23 22:48:46 +08:00
"""
)
child = testdir.spawn_pytest("--doctest-modules --pdb %s" % p1)
child.expect("Pdb")
2018-05-23 22:48:46 +08:00
child.sendline("i")
child.expect("0")
child.expect("Pdb")
child.sendeof()
rest = child.read().decode("utf8")
assert "1 failed" in rest
2016-10-22 00:10:35 +08:00
self.flush(child)
def test_pdb_interaction_capturing_twice(self, testdir):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
import pytest
def test_1():
i = 0
2018-10-13 22:42:33 +08:00
print("hello17")
pytest.set_trace()
x = 3
2018-10-13 22:42:33 +08:00
print("hello18")
pytest.set_trace()
x = 4
assert 0
2018-05-23 22:48:46 +08:00
"""
)
child = testdir.spawn_pytest(str(p1))
child.expect(r"PDB set_trace \(IO-capturing turned off\)")
child.expect("test_1")
child.expect("x = 3")
child.expect("Pdb")
2018-05-23 22:48:46 +08:00
child.sendline("c")
child.expect(r"PDB continue \(IO-capturing resumed\)")
child.expect(r"PDB set_trace \(IO-capturing turned off\)")
child.expect("x = 4")
child.expect("Pdb")
child.sendline("c")
child.expect("_ test_1 _")
child.expect("def test_1")
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
2016-10-22 00:10:35 +08:00
self.flush(child)
def test_pdb_interaction_continue_recursive(self, testdir):
p1 = testdir.makepyfile(
mytest="""
import pdb
import pytest
count_continue = 0
# Simulates pdbpp, which injects Pdb into do_debug, and uses
# self.__class__ in do_continue.
class CustomPdb(pdb.Pdb, object):
def do_debug(self, arg):
import sys
import types
newglobals = {
'Pdb': self.__class__, # NOTE: different with pdb.Pdb
'sys': sys,
}
if sys.version_info < (3, ):
do_debug_func = pdb.Pdb.do_debug.im_func
else:
do_debug_func = pdb.Pdb.do_debug
orig_do_debug = types.FunctionType(
do_debug_func.__code__, newglobals,
do_debug_func.__name__, do_debug_func.__defaults__,
)
return orig_do_debug(self, arg)
do_debug.__doc__ = pdb.Pdb.do_debug.__doc__
def do_continue(self, *args, **kwargs):
global count_continue
count_continue += 1
return super(CustomPdb, self).do_continue(*args, **kwargs)
def foo():
print("print_from_foo")
def test_1():
i = 0
print("hello17")
pytest.set_trace()
x = 3
print("hello18")
assert count_continue == 2, "unexpected_failure: %d != 2" % count_continue
pytest.fail("expected_failure")
"""
)
child = testdir.spawn_pytest("--pdbcls=mytest:CustomPdb %s" % str(p1))
child.expect(r"PDB set_trace \(IO-capturing turned off\)")
child.expect(r"\n\(Pdb")
child.sendline("debug foo()")
child.expect("ENTERING RECURSIVE DEBUGGER")
child.expect(r"\n\(\(Pdb")
child.sendline("c")
child.expect("LEAVING RECURSIVE DEBUGGER")
assert b"PDB continue" not in child.before
assert b"print_from_foo" in child.before
child.sendline("c")
child.expect(r"PDB continue \(IO-capturing resumed\)")
rest = child.read().decode("utf8")
assert "hello17" in rest # out is captured
assert "hello18" in rest # out is captured
assert "1 failed" in rest
assert "Failed: expected_failure" in rest
assert "AssertionError: unexpected_failure" not in rest
self.flush(child)
def test_pdb_without_capture(self, testdir):
p1 = testdir.makepyfile(
"""
import pytest
def test_1():
pytest.set_trace()
"""
)
child = testdir.spawn_pytest("-s %s" % p1)
child.expect(r">>> PDB set_trace >>>")
child.expect("Pdb")
child.sendline("c")
child.expect(r">>> PDB continue >>>")
child.expect("1 passed")
2016-10-22 00:10:35 +08:00
self.flush(child)
def test_pdb_used_outside_test(self, testdir):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
import pytest
pytest.set_trace()
x = 5
2018-05-23 22:48:46 +08:00
"""
)
2018-08-23 09:30:42 +08:00
child = testdir.spawn("{} {}".format(sys.executable, p1))
child.expect("x = 5")
child.expect("Pdb")
child.sendeof()
self.flush(child)
2011-08-01 16:53:37 +08:00
def test_pdb_used_in_generate_tests(self, testdir):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
2011-08-01 16:53:37 +08:00
import pytest
def pytest_generate_tests(metafunc):
pytest.set_trace()
x = 5
def test_foo(a):
pass
2018-05-23 22:48:46 +08:00
"""
)
2011-08-01 16:53:37 +08:00
child = testdir.spawn_pytest(str(p1))
child.expect("x = 5")
child.expect("Pdb")
2011-08-01 16:53:37 +08:00
child.sendeof()
self.flush(child)
def test_pdb_collection_failure_is_shown(self, testdir):
p1 = testdir.makepyfile("xxx")
result = testdir.runpytest_subprocess("--pdb", p1)
result.stdout.fnmatch_lines(
["E NameError: *xxx*", "*! *Exit: Quitting debugger !*"] # due to EOF
)
2014-09-18 20:58:42 +08:00
def test_enter_leave_pdb_hooks_are_called(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makeconftest(
"""
mypdb = None
def pytest_configure(config):
config.testing_verification = 'configured'
def pytest_enter_pdb(config, pdb):
assert config.testing_verification == 'configured'
2018-10-13 22:42:33 +08:00
print('enter_pdb_hook')
global mypdb
mypdb = pdb
mypdb.set_attribute = "bar"
def pytest_leave_pdb(config, pdb):
assert config.testing_verification == 'configured'
print('leave_pdb_hook')
global mypdb
assert mypdb is pdb
assert mypdb.set_attribute == "bar"
2018-05-23 22:48:46 +08:00
"""
)
p1 = testdir.makepyfile(
"""
2014-09-18 20:58:42 +08:00
import pytest
def test_foo():
pytest.set_trace()
assert 0
2018-05-23 22:48:46 +08:00
"""
)
2014-09-18 20:58:42 +08:00
child = testdir.spawn_pytest(str(p1))
child.expect("enter_pdb_hook")
child.sendline("c")
child.expect(r"PDB continue \(IO-capturing resumed\)")
child.expect("Captured stdout call")
rest = child.read().decode("utf8")
assert "leave_pdb_hook" in rest
assert "1 failed" in rest
2014-09-18 20:58:42 +08:00
child.sendeof()
2016-10-22 00:10:35 +08:00
self.flush(child)
2016-09-20 00:05:57 +08:00
def test_pdb_custom_cls(self, testdir, custom_pdb_calls):
p1 = testdir.makepyfile("""xxx """)
2018-05-23 22:48:46 +08:00
result = testdir.runpytest_inprocess("--pdb", "--pdbcls=_pytest:_CustomPdb", p1)
result.stdout.fnmatch_lines(["*NameError*xxx*", "*1 error*"])
2016-09-20 00:05:57 +08:00
assert custom_pdb_calls == ["init", "reset", "interaction"]
2016-09-20 00:05:57 +08:00
def test_pdb_custom_cls_without_pdb(self, testdir, custom_pdb_calls):
p1 = testdir.makepyfile("""xxx """)
2018-05-23 22:48:46 +08:00
result = testdir.runpytest_inprocess("--pdbcls=_pytest:_CustomPdb", p1)
result.stdout.fnmatch_lines(["*NameError*xxx*", "*1 error*"])
2016-09-20 00:05:57 +08:00
assert custom_pdb_calls == []
def test_pdb_custom_cls_with_settrace(self, testdir, monkeypatch):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
custom_pdb="""
class CustomPdb(object):
def __init__(self, *args, **kwargs):
skip = kwargs.pop("skip")
assert skip == ["foo.*"]
print("__init__")
super(CustomPdb, self).__init__(*args, **kwargs)
def set_trace(*args, **kwargs):
2018-10-13 22:42:33 +08:00
print('custom set_trace>')
2018-05-23 22:48:46 +08:00
"""
)
p1 = testdir.makepyfile(
"""
import pytest
def test_foo():
pytest.set_trace(skip=['foo.*'])
2018-05-23 22:48:46 +08:00
"""
)
monkeypatch.setenv("PYTHONPATH", str(testdir.tmpdir))
child = testdir.spawn_pytest("--pdbcls=custom_pdb:CustomPdb %s" % str(p1))
child.expect("__init__")
2018-05-23 22:48:46 +08:00
child.expect("custom set_trace>")
self.flush(child)
2018-03-22 17:40:35 +08:00
class TestDebuggingBreakpoints(object):
def test_supports_breakpoint_module_global(self):
"""
2018-03-23 12:39:34 +08:00
Test that supports breakpoint global marks on Python 3.7+ and not on
2018-03-22 17:40:35 +08:00
CPython 3.5, 2.7
"""
if sys.version_info.major == 3 and sys.version_info.minor >= 7:
assert SUPPORTS_BREAKPOINT_BUILTIN is True
if sys.version_info.major == 3 and sys.version_info.minor == 5:
assert SUPPORTS_BREAKPOINT_BUILTIN is False
if sys.version_info.major == 2 and sys.version_info.minor == 7:
assert SUPPORTS_BREAKPOINT_BUILTIN is False
2018-05-23 22:48:46 +08:00
@pytest.mark.skipif(
not SUPPORTS_BREAKPOINT_BUILTIN, reason="Requires breakpoint() builtin"
)
@pytest.mark.parametrize("arg", ["--pdb", ""])
def test_sys_breakpointhook_configure_and_unconfigure(self, testdir, arg):
"""
Test that sys.breakpointhook is set to the custom Pdb class once configured, test that
hook is reset to system value once pytest has been unconfigured
"""
2018-05-23 22:48:46 +08:00
testdir.makeconftest(
"""
2018-03-29 06:03:20 +08:00
import sys
from pytest import hookimpl
from _pytest.debugging import pytestPDB
def pytest_configure(config):
config._cleanup.append(check_restored)
def check_restored():
assert sys.breakpointhook == sys.__breakpointhook__
def test_check():
assert sys.breakpointhook == pytestPDB.set_trace
2018-05-23 22:48:46 +08:00
"""
)
testdir.makepyfile(
"""
def test_nothing(): pass
2018-05-23 22:48:46 +08:00
"""
)
args = (arg,) if arg else ()
result = testdir.runpytest_subprocess(*args)
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines(["*1 passed in *"])
2018-05-23 22:48:46 +08:00
@pytest.mark.skipif(
not SUPPORTS_BREAKPOINT_BUILTIN, reason="Requires breakpoint() builtin"
)
def test_pdb_custom_cls(self, testdir, custom_debugger_hook):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
def test_nothing():
breakpoint()
2018-05-23 22:48:46 +08:00
"""
)
result = testdir.runpytest_inprocess(
2018-05-23 22:48:46 +08:00
"--pdb", "--pdbcls=_pytest:_CustomDebugger", p1
)
result.stdout.fnmatch_lines(["*CustomDebugger*", "*1 passed*"])
assert custom_debugger_hook == ["init", "set_trace"]
2018-05-23 22:48:46 +08:00
@pytest.mark.parametrize("arg", ["--pdb", ""])
@pytest.mark.skipif(
not SUPPORTS_BREAKPOINT_BUILTIN, reason="Requires breakpoint() builtin"
)
def test_environ_custom_class(self, testdir, custom_debugger_hook, arg):
2018-05-23 22:48:46 +08:00
testdir.makeconftest(
"""
import os
2018-03-29 06:03:20 +08:00
import sys
os.environ['PYTHONBREAKPOINT'] = '_pytest._CustomDebugger.set_trace'
def pytest_configure(config):
config._cleanup.append(check_restored)
def check_restored():
assert sys.breakpointhook == sys.__breakpointhook__
def test_check():
import _pytest
assert sys.breakpointhook is _pytest._CustomDebugger.set_trace
2018-05-23 22:48:46 +08:00
"""
)
testdir.makepyfile(
"""
def test_nothing(): pass
2018-05-23 22:48:46 +08:00
"""
)
args = (arg,) if arg else ()
result = testdir.runpytest_subprocess(*args)
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines(["*1 passed in *"])
@pytest.mark.skipif(
not SUPPORTS_BREAKPOINT_BUILTIN, reason="Requires breakpoint() builtin"
)
@pytest.mark.skipif(
not _ENVIRON_PYTHONBREAKPOINT == "",
reason="Requires breakpoint() default value",
)
def test_sys_breakpoint_interception(self, testdir):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
def test_1():
breakpoint()
2018-05-23 22:48:46 +08:00
"""
)
child = testdir.spawn_pytest(str(p1))
child.expect("test_1")
child.expect("Pdb")
child.sendeof()
rest = child.read().decode("utf8")
assert "Quitting debugger" in rest
assert "reading from stdin while output" not in rest
TestPDB.flush(child)
2018-05-23 22:48:46 +08:00
@pytest.mark.skipif(
not SUPPORTS_BREAKPOINT_BUILTIN, reason="Requires breakpoint() builtin"
)
def test_pdb_not_altered(self, testdir):
2018-05-23 22:48:46 +08:00
p1 = testdir.makepyfile(
"""
import pdb
def test_1():
pdb.set_trace()
assert 0
2018-05-23 22:48:46 +08:00
"""
)
child = testdir.spawn_pytest(str(p1))
child.expect("test_1")
child.expect("Pdb")
child.sendline("c")
rest = child.read().decode("utf8")
assert "1 failed" in rest
assert "reading from stdin while output" not in rest
TestPDB.flush(child)
2018-07-01 09:26:58 +08:00
2018-07-02 11:22:50 +08:00
2018-07-02 11:18:00 +08:00
class TestTraceOption:
2018-07-01 09:26:58 +08:00
def test_trace_sets_breakpoint(self, testdir):
p1 = testdir.makepyfile(
"""
def test_1():
2018-07-01 12:36:27 +08:00
assert True
def test_2():
pass
def test_3():
pass
2018-07-01 09:26:58 +08:00
"""
)
child = testdir.spawn_pytest("--trace " + str(p1))
child.expect("test_1")
child.expect("Pdb")
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")
2018-07-01 09:26:58 +08:00
rest = child.read().decode("utf8")
assert "2 passed in" in rest
2018-07-01 09:26:58 +08:00
assert "reading from stdin while output" not in rest
assert "Exit: Quitting debugger" in child.before.decode("utf8")
2018-07-02 11:18:00 +08:00
TestPDB.flush(child)
2018-07-03 10:46:26 +08:00
def test_trace_after_runpytest(testdir):
"""Test that debugging's pytest_configure is re-entrant."""
p1 = testdir.makepyfile(
"""
from _pytest.debugging import pytestPDB
def test_outer(testdir):
from _pytest.debugging import pytestPDB
assert len(pytestPDB._saved) == 1
testdir.runpytest("-k test_inner")
__import__('pdb').set_trace()
def test_inner(testdir):
assert len(pytestPDB._saved) == 2
"""
)
child = testdir.spawn_pytest("-p pytester %s -k test_outer" % p1)
child.expect(r"\(Pdb")
child.sendline("c")
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)