【问题标题】:How can I get my assertions in pytest to stop being abbreviated with ellipsis?如何让我在 pytest 中的断言停止用省略号缩写?
【发布时间】:2016-06-23 20:15:19
【问题描述】:

如何让我在 pytest 中的断言不再被省略号缩写?

每次我有一个报告错误的断言时,它都会用“...”截断我的所有字符串,这是为什么?我怎么能阻止呢?

【问题讨论】:

  • assert("a"*(10**6) == "a"*(10**6 - 1))。为什么不想截断?
  • 显然我知道为什么值被截断以及不被截断的风险。但这大大超过了我不知道在两个较大的字符串之间进行断言时测试失败的事实。
  • 在这里查看一个简单的 hack:stackoverflow.com/questions/19171554/…

标签: python pytest


【解决方案1】:

other solution 通常不起作用。 例如,在our use case 中,pytest 会截断传递给从断言语句调用的函数的参数:

E                   AssertionError: assert None is not None
E                    +  where None = search('\\n\\*\\s.*\\b[Tt]upla item 0\\b',
'@beartyped pep_hinted() parameter pep_hinted_param=((<function <lambda> at
0x7fe278838830>,),) violates PEP type hint...7fe278838830>,):\n  * Not int, bool, or
float.\n  * Tuple item 0 value <function <lambda> at 0x7fe278838830> not str.')

beartype_test/unit/pep/p484/test_p484.py:124: AssertionError

请注意 pytest 在上述输出中的子字符串violates PEP type hint7fe278838830&gt;,):\n 之间插入的省略号(即...),替换了理解该输出所需的关键任务子字符串。

谢谢,非常乐于助人的 pytest 开发人员。你不应该有。 真的。

有什么问题,兄弟?

为了证实@NicholasDiPiazza@MatthiasUrlichs,Pytest 在截断传递给从断言语句调用的函数的参数时很遗憾地忽略了-v 选项——这有点让人生气。

Pytest 开发人员,如果我们要求冗长四次,这意味着:“是的,我们确实想要冗长,对潜在的陷阱有充分的了解,并且可能不太在意,因为未经审查的错误报告比最大限度地减少那些坦率地说不适用于现实世界的持续集成的模糊理论危害。”

有什么解决办法,兄弟?

我们的工作解决方案如下:

addopts = -vvvv --showlocals -p no:xvfb -r a --doctest-glob=
  • 将被截断的详细字符串(或对象表示,或 whatever)分配给有问题的测试中的局部变量。例如,在我们的用例中,我们将被截断的详细异常消息分配给该测试中的局部变量:例如,
def test_problem_function():
    with raises(Exception) as exception_info:
        raise ValueError("a"*1024)

    exception_str = str(exception_info.value)   # <--- This is where the magic happens.
    assert problem_function("a"*1024, exception_str)

def problem_function(substr, bigstr):
    return substr not in bigstr
  • 改为手动检查 pytest 输出以获取该变量的值:例如,
========================================================== FAILURES ===========================================================
______________________________________________ test_truncated_exception_message _______________________________________________

    def test_truncated_exception_message():
        with raises(Exception) as exception_info:
            raise ValueError("a"*1024)
    
        exception_str = str(exception_info.value)
>       assert problem_function("a"*1024, exception_str)
E       AssertionError: assert False
E        +  where False = problem_function(('a' * 1024), 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')

exception_info = <ExceptionInfo ValueError('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa') tblen=1>
exception_str = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaa'

beartype_test/unit/pep/p484/test_p484.py:39: AssertionError

虽然AssertionError 本身仍然被截断,但--showlocals 选项正确地保留了本地exception_str 测试变量的未截断值。 瞧!

这实际上像宣传的那样有效,但需要注意的是,这只适用于可直接分配给测试中的局部变量的字符串(或对象表示,或 whatever)。这通常但并非总是如此——这就是为什么 pytest 真的 需要在其错误报告中开始尊重 -vvvvvvvvvvvvvv 选项。

【讨论】:

  • 消极、情绪化的语气使答案难以理解
【解决方案2】:

你能举个例子吗?这就是输出对我的看法:

    def test_foo():
>       assert "a"*100 == "a"*100 + "b"
E       assert 'aaaaaaaaaaaa...aaaaaaaaaaaaa' == 'aaaaaaaaaaaaa...aaaaaaaaaaaab'
E         Skipping 89 identical leading characters in diff, use -v to show
E         - aaaaaaaaaaa
E         + aaaaaaaaaaab
E         ?            +

我认为差异可以非常清楚地说明什么是失败的 - 但是-v(如消息所示)我得到了完整的差异:

    def test_foo():
>       assert "a"*100 == "a"*100 + "b"
E       assert 'aaaaaaaaaaaa...aaaaaaaaaaaaa' == 'aaaaaaaaaaaaa...aaaaaaaaaaaab'
E         - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
E         + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab
E         ?  

【讨论】:

  • 答案必须是您要添加的“-v”。我会看看我们是否要添加它
  • 你可以试试-vvvv,看看你会得到什么?这就是我们使用的。
  • -vvvv的输出相同。
  • 我自己也遇到过这种情况;我的情况是比较一个对象是否在列表中是自定义对象(在我的情况下为mock.Call 对象)。在 -v 模式下将调用解包到元组中使省略号消失。
  • 这实际上不起作用。 为了证实@NicholasDiPiazza 和@MatthiasUrlichs,Pytest 在截断AssertionError 输出时遗憾地忽略了-v 选项——这不仅仅是温和的真气。 Pytest 开发人员,如果我要求冗长 次,这意味着:“是的,我真的 确实 想要冗长,我非常了解潜在的陷阱,并且可以不太在意,因为完整的错误报告比最小化那些坦率地不适用于现实世界的持续集成的模糊理论危害要重要得多。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 2011-08-30
  • 2017-01-09
  • 2012-10-15
  • 2021-12-22
相关资源
最近更新 更多