Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pdbcls without pdb on fail #1952

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions _pytest/debugging.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ def pytest_namespace():
return {'set_trace': pytestPDB().set_trace}

def pytest_configure(config):
if config.getvalue("usepdb") or config.getvalue("usepdb_cls"):
if config.getvalue("usepdb_cls"):
modname, classname = config.getvalue("usepdb_cls").split(":")
__import__(modname)
pdb_cls = getattr(sys.modules[modname], classname)
else:
pdb_cls = pdb.Pdb

if config.getvalue("usepdb"):
config.pluginmanager.register(PdbInvoke(), 'pdbinvoke')
if config.getvalue("usepdb_cls"):
modname, classname = config.getvalue("usepdb_cls").split(":")
__import__(modname)
pdb_cls = getattr(sys.modules[modname], classname)
else:
pdb_cls = pdb.Pdb
pytestPDB._pdb_cls = pdb_cls

old = (pdb.set_trace, pytestPDB._pluginmanager)
def fin():
Expand All @@ -38,6 +38,7 @@ def fin():
pdb.set_trace = pytest.set_trace
pytestPDB._pluginmanager = config.pluginmanager
pytestPDB._config = config
pytestPDB._pdb_cls = pdb_cls
config._cleanup.append(fin)

class pytestPDB:
Expand Down
65 changes: 50 additions & 15 deletions testing/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,26 @@ def runpdb_and_get_report(testdir, source):
return reports[1]


@pytest.fixture
def custom_pdb_calls():
called = []

# install dummy debugger class and track which methods were called on it
class _CustomPdb:
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



class TestPDB:

@pytest.fixture
Expand Down Expand Up @@ -334,27 +354,42 @@ def test_foo():
if child.isalive():
child.wait()

def test_pdb_custom_cls(self, testdir):
called = []

# install dummy debugger class and track which methods were called on it
class _CustomPdb:
def __init__(self, *args, **kwargs):
called.append("init")

def reset(self):
called.append("reset")

def interaction(self, *args):
called.append("interaction")
def test_pdb_custom_cls(self, testdir, custom_pdb_calls):
p1 = testdir.makepyfile("""xxx """)
result = testdir.runpytest_inprocess(
"--pdb", "--pdbcls=_pytest:_CustomPdb", p1)
result.stdout.fnmatch_lines([
"*NameError*xxx*",
"*1 error*",
])
assert custom_pdb_calls == ["init", "reset", "interaction"]

_pytest._CustomPdb = _CustomPdb

def test_pdb_custom_cls_without_pdb(self, testdir, custom_pdb_calls):
p1 = testdir.makepyfile("""xxx """)
result = testdir.runpytest_inprocess(
"--pdbcls=_pytest:_CustomPdb", p1)
result.stdout.fnmatch_lines([
"*NameError*xxx*",
"*1 error*",
])
assert called == ["init", "reset", "interaction"]
assert custom_pdb_calls == []

def test_pdb_custom_cls_with_settrace(self, testdir, monkeypatch):
testdir.makepyfile(custom_pdb="""
class CustomPdb:
def set_trace(*args, **kwargs):
print 'custom set_trace>'
""")
p1 = testdir.makepyfile("""
import pytest

def test_foo():
pytest.set_trace()
""")
monkeypatch.setenv('PYTHONPATH', str(testdir.tmpdir))
child = testdir.spawn_pytest("--pdbcls=custom_pdb:CustomPdb %s" % str(p1))

child.expect('custom set_trace>')
if child.isalive():
child.wait()