Skip to content

Instantly share code, notes, and snippets.

@jpeyret
Last active September 5, 2017 17:48
Show Gist options
  • Save jpeyret/ca2269d84e4dfeadf813821e64655d3e to your computer and use it in GitHub Desktop.
Save jpeyret/ca2269d84e4dfeadf813821e64655d3e to your computer and use it in GitHub Desktop.
conditional debugging on unitttests
import unittest
import sys
import pdb
####################################
def ppdb(e=None):
"""conditional debugging
use with: `if ppdb(): pdb.set_trace()`
"""
return ppdb.enabled
ppdb.enabled = False
###################################
class SomeTest(unittest.TestCase):
def test_success(self):
try:
pass
except Exception, e:
if ppdb(): pdb.set_trace()
raise
def test_fail(self):
try:
1/0
except Exception, e:
if ppdb(): pdb.set_trace()
raise
if __name__ == '__main__':
#conditional debugging, but not in nosetests
if "--pdb" in sys.argv:
ppdb.enabled = not sys.argv[0].endswith("nosetests")
sys.argv.remove("--pdb")
unittest.main()
@jpeyret
Copy link
Author

jpeyret commented Sep 5, 2017

Sample usage:


Running the unit test normally:

$ python test_with_debugger.py

which gives:

E.
======================================================================
ERROR: test_fail (__main__.SomeTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_with_debugger.py", line 27, in test_fail
    1/0
ZeroDivisionError: integer division or modulo by zero

----------------------------------------------------------------------
Ran 2 tests in 0.000s

FAILED (errors=1)

Request debugging:

$ python test_with_debugger.py --pdb

which gives:

> /Users/jluc/kds2/wk/explore/test_with_debugger.py(30)test_fail()
-> raise
(Pdb) print ("I am in the debugger")
I am in the debugger
(Pdb) e
ZeroDivisionError('integer division or modulo by zero',)
(Pdb) c
E.
======================================================================
ERROR: test_fail (__main__.SomeTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_with_debugger.py", line 27, in test_fail
    1/0
ZeroDivisionError: integer division or modulo by zero

----------------------------------------------------------------------
Ran 2 tests in 44.499s

FAILED (errors=1)

requesting debugging via nosetests

$ nosetests --pdb test_with_debugger.py

and, we stop, but not because of ppdb(), but just because of nosetests' builtin handling of --pdb flag.

nose.config: INFO: Ignoring files matching ['^\\.', '^_', '^setup\\.py$']
test_fail (test_with_debugger.SomeTest) ... > /Users/jluc/kds2/wk/explore/test_with_debugger.py(27)test_fail()
-> res = 1/0
(Pdb) ppdb()
False
(Pdb) c
ERROR
test_success (test_with_debugger.SomeTest) ... ok

======================================================================
ERROR: test_fail (test_with_debugger.SomeTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/jluc/kds2/wk/explore/test_with_debugger.py", line 27, in test_fail
    res = 1/0
ZeroDivisionError: integer division or modulo by zero

----------------------------------------------------------------------
Ran 2 tests in 27.754s

FAILED (errors=1)

unittest sees nothing of the --pdb trick:

$ python test_with_debugger.py --pdb -h

output:

Usage: test_with_debugger.py [options] [test] [...]

Options:
  -h, --help       Show this message
  -v, --verbose    Verbose output
  -q, --quiet      Minimal output
  -f, --failfast   Stop on first failure
  -c, --catch      Catch control-C and display results
  -b, --buffer     Buffer stdout and stderr during test runs

Examples:
  test_with_debugger.py                               - run default set of tests
  test_with_debugger.py MyTestSuite                   - run suite 'MyTestSuite'
  test_with_debugger.py MyTestCase.testSomething      - run MyTestCase.testSomething
  test_with_debugger.py MyTestCase                    - run all 'test*' test methods
                                               in MyTestCase

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment