如何让 PyCharm 显示来自 pytest 的整个错误差异?
Posted
技术标签:
【中文标题】如何让 PyCharm 显示来自 pytest 的整个错误差异?【英文标题】:How do I get PyCharm to show entire error diffs from pytest? 【发布时间】:2018-11-09 12:44:27 【问题描述】:我正在使用Pycharm 运行我的pytest 单元测试。我正在测试一个 REST API,所以我经常需要验证 JSON 块。当测试失败时,我会看到如下内容:
FAILED
test_document_api.py:0 (test_create_documents)
'items': ['i...ages': 1, ... != 'items': ['...ages': 1, ...
Expected :'items': ['...ages': 1, ...
Actual :'items': ['i...ages': 1, ...
<Click to see difference>
当我点击“点击查看差异”链接时,大部分差异都会转换为椭圆的点,就像这样
这是没用的,因为它没有告诉我有什么不同。对于大于单个字符串或数字的任何差异,我都会得到这种行为。
我假设 Pycharm 和/或 pytest 试图省略大输出差异的无信息部分。但是,这里太激进了,什么都忽略了。
如何让 Pycharm 和/或 pytest 向我展示全部差异?
我尝试将-vvv
添加到 pytest 的附加参数中,但没有效果。
自从原始帖子以来,我验证了当我从命令行运行单元测试时,我看到了相同的行为。所以这是 pytest 而不是 Pycharm 的问题。
查看到目前为止我得到的答案后,我想我真正要问的是“在 pytest 中是否可以在不更改测试源代码的情况下设置maxDiff=None
?”我从阅读 pytest 获得的印象是 -vv
开关控制此设置,但事实并非如此。
【问题讨论】:
【参考方案1】:由于 pytest 与 unittest 集成,作为一种解决方法,您可以将其设置为 unittest,然后设置 Test.maxDiff = None
或每个特定测试 self.maxDiff = None
https://docs.pytest.org/en/latest/index.html
可以开箱即用地运行单元测试(包括试用)和鼻子测试套件;
这些可能也有帮助...
https://***.com/a/21615720/9530790
https://***.com/a/23617918/9530790
【讨论】:
【参考方案2】:If you look closely into PyCharm sources,从整个pytest
输出中,PyCharm 使用单行解析数据以显示在Click to see difference
对话框中。这是AssertionError: <message>
行:
def test_spam():
> assert v1 == v2
E AssertionError: assert 'foo': 'bar' == 'foo': 'baz'
E Differing items:
E 'foo': 'bar' != 'foo': 'baz'
E Use -v to get the full diff
如果您想查看完整的差异行而不被截断,您需要在输出中自定义此行。对于单个测试,这可以通过在assert
语句中添加自定义消息来完成:
def test_eggs():
assert a == b, '0 != 1'.format(a, b)
如果您想将此行为应用于所有测试,请定义自定义 pytest_assertrepr_compare
挂钩。在conftest.py
文件中:
# conftest.py
def pytest_assertrepr_compare(config, op, left, right):
if op in ('==', '!='):
return ['0 1 2'.format(left, op, right)]
值的相等比较现在仍然会在太长时被剥离;要显示完整的行,您仍然需要使用 -vv
标志增加详细程度。
现在AssertionError
行中的值的相等比较将不会被剥离,完整的差异会显示在Click to see difference
对话框中,突出显示差异部分:
【讨论】:
感谢您的回答,我继续提出拉取请求:github.com/JetBrains/intellij-community/pull/1091 @Ilya 您是否跟进了 jetbrain 的评论并将 PR 转发到 teamcity-messages ? @AdrienH 是的,它被合并了:github.com/JetBrains/teamcity-messages/pull/210 -- 应该在最新的 PyCharm 中修复【参考方案3】:查看了 pytest 代码库,也许您可以尝试其中一些:
1) 在测试执行中设置详细级别:
./app_main --pytest --verbose test-suite/
2) 为“CI”或“BUILD_NUMBER”添加环境变量。在链接中 截断文件,您可以看到这些环境变量用于 判断截断块是否运行。
import os
os.environ["BUILD_NUMBER"] = '1'
os.environ["CI"] = 'CI_BUILD'
3) 尝试在截断模块上设置 DEFAULT_MAX_LINES 和 DEFAULT_MAX_CHARS(不推荐这样做,因为它使用私有模块):
from _pytest.assertion import truncate
truncate.DEFAULT_MAX_CHARS = 1000
truncate.DEFAULT_MAX_LINES = 1000
根据代码,-vv 选项应该可以工作,所以奇怪的是它不适合你:
当前的默认行为是在 ~8 条终端线,除非在“-vv”模式下运行或在 CI 上运行。
我的答案基于 Pytest 截断文件:pytest/truncate.py
希望这里能帮到你!
【讨论】:
【参考方案4】:我遇到了类似的事情,并创建了一个函数,该函数返回一个字符串,其中两个 dicts
的差异很大。在pytest
样式测试中,这看起来像:
assert expected == actual, build_diff_string(expected, actual)
并且采用unittest
风格
self.assertEqual(expected, actual, build_diff_string(expected, actual)
缺点是你必须修改所有有这个问题的测试,但这是一个保持简单和愚蠢的解决方案。
【讨论】:
【参考方案5】:在 pycharm 中,您只需将 -vv 放在运行配置的 Additional Arguments 字段中,这应该可以解决问题。
或者至少,它在我的机器上工作......
【讨论】:
【参考方案6】:我在断言中有一些 getattr,但在 AssertionError
之后它从不显示任何内容。
我在Additional Arguments
字段中添加-lv
以显示局部变量。
【讨论】:
以上是关于如何让 PyCharm 显示来自 pytest 的整个错误差异?的主要内容,如果未能解决你的问题,请参考以下文章
让 PyCharm 在 windows linux 子系统上识别 python(windows 上的 bash)