【问题标题】:Pytest checking messages returned by errorsPytest 检查错误返回的消息
【发布时间】:2021-07-23 00:49:20
【问题描述】:

关于 pytest、str() 和 python 错误类型之间的交互的一些事情会破坏完整的错误测试,我们想要确认错误返回的 EXACT TEXT。

下面的例子:

def erroring_func(name, required_item_list):
   # skip boring bit. Just throw an error.
   raise KeyError(f'{name} is missing required item(s): {required_item_list')

def test_erroring_func()
    with pytest.raises(KeyError) as err:
        name = 'This dataframe'
        required_item_list = ['a column']
        _ = erroring_func(name, required_item_list)
    assert str(err.value) == f"{name} is missing required item(s): {required_item_list}"

这看起来很合理,但会返回错误:

assert '"This dataframe is missing required item(s): [\'lat\']"' == "This dataframe is missing required item(s): ['lat']

不知何故,str(err.value) 在输出中创建了单个反斜杠,很难在 f 字符串 (actually impossible) 中重新创建或在创建后插入到字符串中。

【问题讨论】:

  • 所以,问题是KeyError 有一个自定义__str__ 并且KeyError 的构造函数是缺失的键,这就是你看到它被引用的原因。反斜杠实际上并不存在,它只是字符串的表示以单引号开头,因此嵌入的单引号将在代码中以这种方式显示。 KeyError 也可能是错误的异常类型
  • 断言中的字符串不匹配,因此为KeyError 定义的__str__ 方法肯定改变了一些东西。我很想相信实际的错误日志是反斜杠,但它可能是别的东西?至于为什么 KeyError,这是一个自定义检查,用于在昂贵的计算之前确认 df 列,从而提出后来成为关键错误的内容(并使错误消息真正有用)。可以创建一个自定义错误类,但我很想了解为什么默认类在 pytest 中表现不佳。
  • 更改您的断言以使用 '"message"',就像 KeyError 所做的那样——注意引用是 both 类型的引号(您传入的字符串的代表)。比较 str(KeyError("foo'bar"))str(ValueError("foo'bar")),你会更好地看到 KeyError__str__ 在做什么
  • 我还强烈建议在测试中使用逻辑——它会掩盖你的问题并使你感到困惑:testing.googleblog.com/2014/07/…
  • 感谢您的帮助!需要在适当类型和顺序的引号中双重换行文本字符串 (yuck)。 Google thinkpiece 很有趣,谢谢。总的来说,我不同意这种想法,因为这种想法使单元测试很难维护,尽管我可以看到规格变化较慢的大型组织可能会这样想(即,如果您不更改单元测试,谁会关心可维护性)。根据对此的回复:andrewtrumper.com/2014/08/complex-logic-in-unit-tests.html

标签: python-3.x pytest f-string


【解决方案1】:

一个不完整的补丁(缺少详细错误的主要值)是测试返回的错误中是否存在固定的子字符串。

def test_erroring_func()
    with pytest.raises(KeyError) as err:
        name = 'This dataframe'
        required_item_list = ['a column']
        _ = erroring_func(name, required_item_list)
    assert "is missing required item(s):" in str(err.value)

【讨论】:

    【解决方案2】:

    您可以通过匹配KeyError 更改文本的方式来完全解决。这可以使用带有单引号的 f 字符串,然后是双引号 f'"your text {here}"'

    assert str(err.value) == f'"{name} is missing required item(s): {required_item_list}"'
    

    (感谢 Anthony Sotile)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-19
      • 2020-11-30
      • 1970-01-01
      • 1970-01-01
      • 2017-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多