Python 单元测试:测试失败时自动运行调试器
有没有办法在单元测试失败时自动启动调试器?
现在我只是手动使用 pdb.set_trace() ,但这非常繁琐,因为我需要每次添加它并在最后取出它。
例如:
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()
Is there a way to automatically start the debugger at the point at which a unittest fails?
Right now I am just using pdb.set_trace() manually, but this is very tedious as I need to add it each time and take it out at the end.
For Example:
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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我认为您正在寻找的是鼻子。它的工作原理类似于 unittest 的测试运行程序。
您可以使用以下命令进入错误调试器:
I think what you are looking for is nose. It works like a test runner for unittest.
You can drop into the debugger on errors, with the following command:
我更正了代码以在异常上调用 post_mortem 而不是 set_trace。
I corrected the code to call post_mortem on the exception instead of set_trace.
第三方测试框架增强功能通常似乎包括该功能(其他答案中已经提到了nose 和nose2)。更多:
pytest 支持。
或者,如果您使用 absl-py 的
absltest
而不是unittest
模块:Third party test framework enhancements generally seem to include the feature (
nose
andnose2
were already mentioned in other answers). Some more:pytest supports it.
Or if you use absl-py's
absltest
instead ofunittest
module:一个简单的选择是只运行测试而不收集结果,并让第一个异常崩溃在堆栈中(用于任意事后处理),例如
另一个选项:覆盖
unittest.TextTestResult
的addError
和addFailure
在调试测试运行器中用于立即 post_mortem 调试(在tearDown()
之前) - 或者用于收集和处理错误&以高级方式回溯。(不需要额外的框架或测试方法的额外装饰器)
基本示例:
A simple option is to just run the tests without result collection and letting the first exception crash down the stack (for arbitrary post mortem handling) by e.g.
Another option: Override
unittest.TextTestResult
'saddError
andaddFailure
in a debug test runner for immediate post_mortem debugging (beforetearDown()
) - or for collecting and handling errors & tracebacks in an advanced way.(Doesn't require extra frameworks or an extra decorator for test methods)
Basic example:
将@cmcginty的答案应用于继任者nose 2 (由nose推荐,在基于Debian的系统上可通过
apt-get install noreferrer
获得),您可以/en/latest/plugins/debugger.html" rel="nofollow noreferrer">通过调用测试
。为此,您需要在主目录中有一个合适的
.unittest.cfg
或在项目目录中有一个unittest.cfg
;它需要包含以下行To apply @cmcginty's answer to the successor nose 2 (recommended by nose available on Debian-based systems via
apt-get install nose2
), you can drop into the debugger on failures and errors by callingin your test directory.
For this, you need to have a suitable
.unittest.cfg
in your home directory orunittest.cfg
in the project directory; it needs to contain the lines要解决代码中的注释“在文档中,unittest.TestCase 有一个 debug() 方法,但我不明白如何使用它”,您可以执行以下操作:
创建单独的测试用例,如下所示:
testCase = tests('test_trigger_pdb')
(其中tests
是TestCase
的子类,根据您的示例)。然后您可以执行testCase.debug()
来调试一个案例。To address the comment in your code "In the documentation the unittest.TestCase has a debug() method but I don't understand how to use it", you can do something like this:
Individual test cases are created like:
testCase = tests('test_trigger_pdb')
(wheretests
is a sub-class ofTestCase
as per your example). And then you can dotestCase.debug()
to debug one case.这是一个内置的、没有额外模块的解决方案:
使用 python myunittest.py --pdb 调用它,它将停止。不然不会。
Here's a built-in, no extra modules, solution:
call it with
python myunittest.py --pdb
and it will halt. Otherwise it won't.上面的一些解决方案修改了业务逻辑:
为了最小化对原始代码的更改,我们可以定义一个函数装饰器,并简单地装饰抛出的函数:
使用:
Some solution above modifies business logic:
To minimize changes to the original code, we can define a function decorator, and simply decorate the function that's throwing:
Use:
使用装饰器构建一个模块,该装饰器可以对除 AssertionError 之外的每种类型的错误进行分析。装饰器可以由日志记录根级别触发
Buildt a module with a decorator which post mortems into every type of error except AssertionError. The decorator can be triggered by the logging root level