繁体   English   中英

以某种方式使用 py.test 时,我可以使用 python 调试器进行调试吗?

[英]Can I debug with python debugger when using py.test somehow?

我正在使用 py.test 对我的 python 程序进行单元测试。 我希望使用 python 调试器以正常方式调试我的测试代码(我的意思是代码中的 pdb.set_trace() ),但我无法让它工作。

将 pdb.set_trace() 放在代码中不起作用(引发 IOError:在捕获输出时从标准输入读取)。 我也尝试使用选项 --pdb 运行 py.test 但如果我想探索在我的断言之前发生的事情,这似乎并没有奏效。 当断言失败时它会中断,从该行继续前进意味着终止程序。

有没有人知道调试的方法,或者调试和 py.test 并不意味着在一起?

这真的很简单:在代码中要开始调试的位置放置一个assert 0并使用以下命令运行测试:

py.test --pdb 

完毕 :)

或者,如果您使用 pytest-2.0.1 或更高版本,还有pytest.set_trace()助手,您可以将其放在测试代码中的任何位置。 这是文档 在将您发送到 pdb 调试器命令行之前,它会注意在内部禁用捕获。

我发现我可以在禁用捕获的情况下运行 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)

最简单的方法是使用 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 pdb; pdb.set_trace() import pytest; pytest.set_trace() import pytest; pytest.set_trace()

类似于 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 中运行。

我对 py.test 不熟悉,换个 unittest,你做以下。 也许 py.test 是类似的:

在您的测试模块 (mytestmodule.py) 中:

if __name__ == "__main__":
    unittest.main(module="mytestmodule")

然后运行测试

python -m pdb mytestmodule.py

您将获得一个交互式 pdb shell。

查看文档,看起来 py.test 有一个--pdb命令行选项:

http://codespeak.net/py/dist/test/features.html

无需编辑源文件即可添加和删除断点

尽管您可以通过在代码中添加breakpoint()set_trace()语句来添加breakpoint() ,但这种方法存在两个问题:

  • 首先,一旦开始运行代码,就无法删除断点。 我经常发现,一旦我开始运行我的代码并到达初始断点,我想放置另一个并删除初始断点。 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 混淆,一切都会出错。 对于不同的 shell,确切的调用语法会有所不同。

只需使用: pytest --trace test_your_test.py 这将在测试开始时调用 Python 调试器

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM