Python Unit Testing: Automatyczne uruchamianie debuggera, gdy test się nie powiedzie
Czy istnieje sposób na automatyczne uruchomienie debuggera w punkcie, w którym unittest się nie powiedzie?
W tej chwili używam pdb.set_trace () ręcznie, ale jest to bardzo uciążliwe, ponieważ muszę ją dodawać za każdym razem i wyjmować na końcu.Na Przykład:
import unittest
class tests(unittest.TestCase):
def setUp(self):
pass
def test_trigger_pdb(self):
#this is the way I do it now
try:
assert 1==0
except AssertionError:
import pdb
pdb.set_trace()
def test_no_trigger(self):
#this is the way I would like to do it:
a=1
b=2
assert a==b
#magically, pdb would start here
#so that I could inspect the values of a and b
if __name__=='__main__':
#In the documentation the unittest.TestCase has a debug() method
#but I don't understand how to use it
#A=tests()
#A.debug(A)
unittest.main()
6 answers
import unittest
import sys
import pdb
import functools
import traceback
def debug_on(*exceptions):
if not exceptions:
exceptions = (AssertionError, )
def decorator(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
try:
return f(*args, **kwargs)
except exceptions:
info = sys.exc_info()
traceback.print_exception(*info)
pdb.post_mortem(info[2])
return wrapper
return decorator
class tests(unittest.TestCase):
@debug_on()
def test_trigger_pdb(self):
assert 1 == 0
Poprawiłem kod, aby wywołać post_mortem na wyjątku zamiast set_trace.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-14 19:03:14
Myślę, że to, czego szukasz, to nos . Działa jak biegacz testowy dla unittest .
Możesz wpaść do debuggera w przypadku błędów, za pomocą następującego polecenia:
nosetests --pdb
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-31 00:39:59
Prostą opcją jest po prostu Uruchamianie testów bez zbierania wyników i pozwalanie, aby pierwszy wyjątek spadł ze stosu (dla arbitralnej obsługi post mortem) przez np.
try: unittest.findTestCases(__main__).debug()
except:
pdb.post_mortem(sys.exc_info()[2])
Inna opcja: Zastąp unittest.TextTestResult
'S addError
i addFailure
w testowym biegaczu debugowania do natychmiastowego debugowania post_mortem (przed tearDown()
) - lub do zbierania i obsługi błędów i tracebacków w zaawansowany sposób.
(nie wymaga dodatkowych ram ani dodatkowego dekoratora dla metod badawczych)
Podstawowe przykład:
import unittest, pdb
class TC(unittest.TestCase):
def testZeroDiv(self):
1 / 0
def debugTestRunner(post_mortem=None):
"""unittest runner doing post mortem debugging on failing tests"""
if post_mortem is None:
post_mortem = pdb.post_mortem
class DebugTestResult(unittest.TextTestResult):
def addError(self, test, err):
# called before tearDown()
traceback.print_exception(*err)
post_mortem(err[2])
super(DebugTestResult, self).addError(test, err)
def addFailure(self, test, err):
traceback.print_exception(*err)
post_mortem(err[2])
super(DebugTestResult, self).addFailure(test, err)
return unittest.TextTestRunner(resultclass=DebugTestResult)
if __name__ == '__main__':
##unittest.main()
unittest.main(testRunner=debugTestRunner())
##unittest.main(testRunner=debugTestRunner(pywin.debugger.post_mortem))
##unittest.findTestCases(__main__).debug()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-30 14:06:31
Zewnętrzne ulepszenia frameworku testowego wydają się na ogół obejmować tę funkcję (nose
i nose2
były już wspomniane w innych odpowiedziach). Trochę więcej:
Pytest go wspiera.
pytest --pdb
Lub jeśli używasz absl-py ' S absltest
zamiast unittest
module:
name_of_test.py --pdb_post_mortem
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-27 22:31:36
Aby zastosować odpowiedź@cmcginty do następcy nos 2 (zalecane przez nose dostępne na systemach opartych na Debianie przez apt-get install nose2
), możesz wpaść do debugera na awarie i błędy, wywołując
nose2
W katalogu testów.
W tym celu musisz mieć odpowiedni .unittest.cfg
w katalogu domowym lub unittest.cfg
w katalogu projektu; musi on zawierać linie
[debugger]
always-on = True
errors-only = False
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-19 09:06:19
Oto wbudowane, bez dodatkowych modułów rozwiązanie:
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:
res = 1/0
#note: a `nosetests --pdb` run will stop after any exception
#even one without try/except and ppdb() does not not modify that.
except Exception, e:
if ppdb(): pdb.set_trace()
raise
if __name__ == '__main__':
#conditional debugging, but not in nosetests
if "--pdb" in sys.argv:
print "pdb requested"
ppdb.enabled = not sys.argv[0].endswith("nosetests")
sys.argv.remove("--pdb")
unittest.main()
Zadzwoń z {[1] } i się zatrzyma. W przeciwnym razie nie będzie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-05 18:26:07