我正在使用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
开关是控制此设置的,但事实并非如此。
答案 0 :(得分:11)
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
如果要查看完整的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
对话框中会显示完整的差异,突出显示差异部分:
答案 1 :(得分:3)
由于pytest与unittest集成,因此您可以将其设置为单元测试,然后设置Test.maxDiff = None
或每个特定测试self.maxDiff = None
https://docs.pytest.org/en/latest/index.html
可以开箱即用单元测试(包括试用)和鼻子测试套件;
这些也可能有用......
答案 2 :(得分:0)
看看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
希望这里有所帮助!
答案 3 :(得分:0)
我遇到了类似的情况,并创建了一个函数,该函数返回一个字符串,其中两个dicts
的差值很好。在pytest
样式测试中,它看起来像:
assert expected == actual, build_diff_string(expected, actual)
并以unittest
风格
self.assertEqual(expected, actual, build_diff_string(expected, actual)
缺点是您必须修改所有存在此问题的测试,但这是一个“保持简单而愚蠢”的解决方案。
答案 4 :(得分:0)
在pycharm中,您可以将-vv放在运行配置的其他参数字段中,这应该可以解决问题。
或者至少可以在我的机器上工作...
答案 5 :(得分:0)
我在断言中有一些 getattr,它在 AssertionError
之后从不显示任何内容。
我在 -lv
字段中添加 Additional Arguments
以显示局部变量。