【问题标题】:How do I get PyCharm to show entire error diffs from pytest?如何让 PyC​​harm 显示来自 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 开关控制此设置,但事实并非如此。

【问题讨论】:

    标签: python pycharm pytest difference


    【解决方案1】:

    由于 pytest 与 unittest 集成,作为一种解决方法,您可以将其设置为 unittest,然后设置 Test.maxDiff = None 或每个特定测试 self.maxDiff = None

    https://docs.pytest.org/en/latest/index.html

    可以开箱即用地运行单元测试(包括试用)和鼻子测试套件;

    这些可能也有帮助...

    https://stackoverflow.com/a/21615720/9530790

    https://stackoverflow.com/a/23617918/9530790

    【讨论】:

      【解决方案2】:

      If you look closely into PyCharm sources,从整个pytest 输出中,PyCharm 使用单行解析数据以显示在Click to see difference 对话框中。这是AssertionError: &lt;message&gt; 行:

      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 对话框中,突出显示差异部分:

      【讨论】:

      【解决方案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 以显示局部变量。

            【讨论】:

              猜你喜欢
              • 2019-06-29
              • 1970-01-01
              • 2021-01-29
              • 2015-12-16
              • 2015-01-22
              • 2018-07-15
              • 2013-09-26
              • 2020-09-30
              • 2016-11-09
              相关资源
              最近更新 更多