如何让 PyCharm 显示来自 pytest 的整个错误差异?
How do I get PyCharm to show entire error diffs from pytest?
我正在使用 Pycharm to run my 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>
当我点击 "Click to see difference" link 时,大部分差异被转换为椭圆点,像这样
这是无用的,因为它没有告诉我有什么不同。对于大于单个字符串或数字的任何差异,我都会得到这种行为。
我假设 Pycharm and/or pytest 试图消除大输出差异中无信息的部分。但是,它在这里过于激进并且省略了所有内容。
如何让 Pycharm and/or pytest 显示全部差异?
我试过将 -vvv
添加到 pytest 的附加参数中,但这没有效果。
自从最初的 post 我验证了当我从命令行进行 运行 单元测试时我看到了相同的行为。所以这是 pytest 的问题,而不是 Pycharm.
看了到目前为止我得到的答案后,我想我真正想问的是 "in pytest is it possible to set maxDiff=None
without changing the source code of your tests?" 我从阅读有关 pytest 的文章中得到的印象是 -vv
开关是是什么控制了这个设置,但情况似乎并非如此。
由于 pytest 与 unittest 集成,作为一种解决方法,您可以将其设置为 unittest,然后设置 Test.maxDiff = None
或每个特定测试 self.maxDiff = None
https://docs.pytest.org/en/latest/index.html
Can run unittest (including trial) and nose test suites out of the box;
这些也可能有帮助...
If you look closely into PyCharm sources,从整个 pytest
输出中,PyCharm 使用单行解析数据以显示在 Click to see difference
对话框中。这是 AssertionError: <message>
行:
def test_spam():
> assert v1 == v2
<b>E AssertionError: assert {'foo': 'bar'} == {'foo': 'baz'}</b>
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
对话框中,突出显示差异部分:
查看了 pytest 代码库,也许您可以尝试其中的一些:
1) 在测试执行中设置详细级别:
./app_main --pytest --verbose test-suite/
2) 为"CI" 或"BUILD_NUMBER" 添加环境变量。在 link 到
t运行cate 文件你可以看到这些环境变量是用来
判断 t运行cation 块是否为 运行.
import os
os.environ["BUILD_NUMBER"] = '1'
os.environ["CI"] = 'CI_BUILD'
3) 尝试在 t运行cate 模块上设置 DEFAULT_MAX_LINES 和 DEFAULT_MAX_CHARS(不推荐这样做,因为它使用私有模块):
from _pytest.assertion import truncate
truncate.DEFAULT_MAX_CHARS = 1000
truncate.DEFAULT_MAX_LINES = 1000
根据代码,-vv 选项应该有效,所以很奇怪它不适合你:
Current default behaviour is to truncate assertion explanations at
~8 terminal lines, unless running in "-vv" mode or running on CI.
Pytest t运行cation 文件,我的答案基于:pytest/truncate.py
希望这里的内容对您有所帮助!
我 运行 陷入了类似的境地,并创建了一个函数,该函数 returns 一个字符串,其中两个 dicts
具有很好的差异。在 pytest
样式测试中,它看起来像:
assert expected == actual, build_diff_string(expected, actual)
并采用 unittest
风格
self.assertEqual(expected, actual, build_diff_string(expected, actual)
缺点是你必须修改所有有这个问题的测试,但这是一个保持简单和愚蠢的解决方案。
在 pycharm 中,您可以将 -vv 放在 运行 配置的附加参数字段中,这应该可以解决问题。
或者至少,它在我的机器上运行...
我在断言中有一些 getattr,但在 AssertionError
之后它不再显示任何内容。
我在 Additional Arguments
字段中添加 -lv
以显示局部变量。
我正在使用 Pycharm to run my 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>
当我点击 "Click to see difference" link 时,大部分差异被转换为椭圆点,像这样
这是无用的,因为它没有告诉我有什么不同。对于大于单个字符串或数字的任何差异,我都会得到这种行为。
我假设 Pycharm and/or pytest 试图消除大输出差异中无信息的部分。但是,它在这里过于激进并且省略了所有内容。
如何让 Pycharm and/or pytest 显示全部差异?
我试过将 -vvv
添加到 pytest 的附加参数中,但这没有效果。
自从最初的 post 我验证了当我从命令行进行 运行 单元测试时我看到了相同的行为。所以这是 pytest 的问题,而不是 Pycharm.
看了到目前为止我得到的答案后,我想我真正想问的是 "in pytest is it possible to set maxDiff=None
without changing the source code of your tests?" 我从阅读有关 pytest 的文章中得到的印象是 -vv
开关是是什么控制了这个设置,但情况似乎并非如此。
由于 pytest 与 unittest 集成,作为一种解决方法,您可以将其设置为 unittest,然后设置 Test.maxDiff = None
或每个特定测试 self.maxDiff = None
https://docs.pytest.org/en/latest/index.html
Can run unittest (including trial) and nose test suites out of the box;
这些也可能有帮助...
If you look closely into PyCharm sources,从整个 pytest
输出中,PyCharm 使用单行解析数据以显示在 Click to see difference
对话框中。这是 AssertionError: <message>
行:
def test_spam():
> assert v1 == v2
<b>E AssertionError: assert {'foo': 'bar'} == {'foo': 'baz'}</b>
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
对话框中,突出显示差异部分:
查看了 pytest 代码库,也许您可以尝试其中的一些:
1) 在测试执行中设置详细级别:
./app_main --pytest --verbose test-suite/
2) 为"CI" 或"BUILD_NUMBER" 添加环境变量。在 link 到 t运行cate 文件你可以看到这些环境变量是用来 判断 t运行cation 块是否为 运行.
import os
os.environ["BUILD_NUMBER"] = '1'
os.environ["CI"] = 'CI_BUILD'
3) 尝试在 t运行cate 模块上设置 DEFAULT_MAX_LINES 和 DEFAULT_MAX_CHARS(不推荐这样做,因为它使用私有模块):
from _pytest.assertion import truncate
truncate.DEFAULT_MAX_CHARS = 1000
truncate.DEFAULT_MAX_LINES = 1000
根据代码,-vv 选项应该有效,所以很奇怪它不适合你:
Current default behaviour is to truncate assertion explanations at ~8 terminal lines, unless running in "-vv" mode or running on CI.
Pytest t运行cation 文件,我的答案基于:pytest/truncate.py
希望这里的内容对您有所帮助!
我 运行 陷入了类似的境地,并创建了一个函数,该函数 returns 一个字符串,其中两个 dicts
具有很好的差异。在 pytest
样式测试中,它看起来像:
assert expected == actual, build_diff_string(expected, actual)
并采用 unittest
风格
self.assertEqual(expected, actual, build_diff_string(expected, actual)
缺点是你必须修改所有有这个问题的测试,但这是一个保持简单和愚蠢的解决方案。
在 pycharm 中,您可以将 -vv 放在 运行 配置的附加参数字段中,这应该可以解决问题。
或者至少,它在我的机器上运行...
我在断言中有一些 getattr,但在 AssertionError
之后它不再显示任何内容。
我在 Additional Arguments
字段中添加 -lv
以显示局部变量。