我正在使用py.test对我的python程序进行单元测试。我希望用python调试器以正常的方式调试我的测试代码(我的意思是代码中的pdb.set_trace())但是我无法使它工作。
将pdb.set_trace()放入代码中不起作用(引发IOError:在捕获输出时从stdin读取)。我也尝试使用选项--pdb运行py.test但是如果我想探索在断言之前发生的事情,那似乎并不起作用。它在断言失败时中断,从该行开始意味着终止程序。
有没有人知道调试的方法,或者调试和py.test只是不想在一起?
答案 0 :(得分:82)
这很简单:将assert 0
放在要在代码中开始调试的位置并运行测试:
py.test --pdb
完成:)
或者,如果您使用的是pytest-2.0.1或更高版本,那么您还可以将pytest.set_trace()
助手放在测试代码中的任何位置。这是docs。在将您发送到pdb调试器命令行之前,需要注意内部禁用捕获。
答案 1 :(得分:31)
我发现我可以在禁用捕获的情况下运行py.test,然后像往常一样使用pdb.set_trace()。
> py.test --capture=no
============================= test session starts ==============================
platform linux2 -- Python 2.5.2 -- pytest-1.3.3
test path 1: project/lib/test/test_facet.py
project/lib/test/test_facet.py ...> /home/jaraco/projects/project/lib/functions.py(158)do_something()
-> code_about_to_run('')
(Pdb)
答案 2 :(得分:17)
最简单的方法是使用py.test机制创建断点
http://pytest.org/latest/usage.html#setting-a-breakpoint-aka-set-trace
import pytest
def test_function():
...
pytest.set_trace() # invoke PDB debugger and tracing
或者,如果您希望将pytest
的调试程序作为一行,请将import pdb; pdb.set_trace()
更改为import pytest; pytest.set_trace()
答案 3 :(得分:1)
我不熟悉py.test,为了进行单元测试,你会做以下事情。也许py.test类似:
在您的测试模块(mytestmodule.py)中:
if __name__ == "__main__":
unittest.main(module="mytestmodule")
然后用
运行测试python -m pdb mytestmodule.py
您将获得一个交互式pdb shell。
查看文档,看起来py.test有一个--pdb
命令行选项:
答案 4 :(得分:1)
与Peter Lyon的答案类似,但是有了pytest所需的确切代码,您可以将以下内容添加到pytest模块的底部(my_test_module.py):
if __name__ == "__main__":
pytest.main(["my_test_module.py", "-s"])
然后您可以从命令行调用调试器:
pdb3 my_test_module.py
景气。您正在调试器中,并且能够输入调试器命令。这种方法不会让您的测试代码受到set_trace()调用的干扰,并且会在pytest中“正常”运行。
答案 5 :(得分:0)
尽管您可以通过在代码中添加breakpoint()
或set_trace()
语句来添加断点,但是这种方法存在两个问题:
breakpoint()
进入调试器后,我可以添加其他断点,但是不能删除初始断点。尽管可以通过将初始breakpoint
放在较高的位置来缓解这种情况,但是,如果您有参数化测试,那么即使这样做也很有限。我可能会发现自己经常重复cont
。breakpoint()
命令,必须在切换分支之前删除它们,等等。我有时发现我想使用调试器来比较两个分支之间的测试运行,并且每次都必须编辑源代码以添加一个断点,这会使操作变得相当慢,而且容易出错。我什至可能要在我正在调用的库中添加一个断点,在这种情况下,我正在编辑的文件甚至可能不在我的git存储库中,而是在我的conda环境中的某个深处,这增加了忘记删除它的风险。以我的愚见,编辑文件以添加断点是很丑的。要以交互方式添加和删除断点而无需编辑任何源文件,可以按如下方式调用pytest
(在bash shell中):
python -mipdb $(type -p pytest) -s test_fileset.py
-s
标志在这里至关重要,因为它可以防止pytest与stdin和stdout发生混乱,并且在调试器中运行时,pytest将无法与stdin和stdout发生混乱,并且一切都会出错。对于不同的外壳,确切的调用语法将有所不同。
答案 6 :(得分:0)
只需使用:pytest --trace test_your_test.py
。
这将在测试开始时调用 Python 调试器