【问题标题】:Hypothesis stateful testing with pytest.raises doesn't report sequence of steps使用 pytest.raises 的假设状态测试不报告步骤顺序
【发布时间】:2018-12-08 21:18:21
【问题描述】:

我想写一个hypothesis.stateful.RuleBasedStateMachine,它断言在某些情况下会引发异常。 pytest 提供 raises 上下文管理器,用于编写有关异常的测试。如果我在hypothesis.stateful.rule 中使用pytest.raises,则会报告导致测试失败的步骤顺序。

在没有pytest.raises 的情况下重写规则会产生所需的行为:显示步骤顺序。

这里是一些示例代码:

from os import getenv

from pytest import raises

from hypothesis.stateful   import RuleBasedStateMachine, rule

SHOW_PROBLEM = getenv('SHOW_PROBLEM') == 'yes'


# A state machine which asserts that an exception is raised in under some condition
class FifthCallShouldRaiseValueError(RuleBasedStateMachine):

    def __init__(self):
        super().__init__()
        self.model = Model()
        self.count = 0

    if SHOW_PROBLEM:

        # This version does NOT report the rule sequence
        @rule()
        def the_rule(self):
            self.count += 1
            if self.count > 4:
                with raises(ValueError):
                    self.model.method()

    else:

        # This version DOES report the rule sequence
        @rule()
        def the_rule(self):
            self.count += 1
            if self.count > 4:
                try:
                    self.model.method()
                except ValueError: assert True
                except           : assert False
                else             : assert False


T = FifthCallShouldRaiseValueError.TestCase


# A model that deliberately fails the test, triggering reporting of
# the sequence of steps which lead to the failure.
class Model:

    def __init__(self):
        self._count = 0

    def method(self):
        self._count += 1
        if self._count > 4:
            # Deliberate mistake: raise wrong exception type
            raise TypeError

要观察行为差异,请使用

执行测试
  • SHOW_PROBLEM=yes pytest <...>
  • SHOW_PROBLEM=no pytest <...>

在第二种情况下,输出将显示

state = FifthCallShouldRaiseValueError()
state.the_rule()
state.the_rule()
state.the_rule()
state.the_rule()
state.the_rule()
state.teardown()

在第一种情况下,输出中缺少此步骤序列。这是我们所希望的:在这两种情况下都应该显示序列。

pytest.raises 提升 Failed: DID NOT RAISE <class 'ValueError'> 而手写版本提升 AssertionError。前者在未能引发所需异常时提供更多信息,但不知何故似乎阻止 hypothesis.stateful 报告步骤顺序,这告诉我们如何进入该状态,并且通常是最有趣的部分输出。

除了不使用pytest.raises之外,还可以做些什么来缓解这种情况,即确保打印出步骤顺序?

【问题讨论】:

    标签: python-hypothesis


    【解决方案1】:

    事实证明,如果规则引发BaseException 或非Exception 子类,则不会打印这些步骤。 pytest.raises(...) 如果没有得到预期的异常,就会引发这样的错误,而你就是这样。

    https://github.com/HypothesisWorks/hypothesis/issues/1372

    现在它已经被识别出来,这不是一个特别棘手的错误 - 感谢您在其中的贡献,通过报告可重现的案例! - 所以我们应该尽快解决问题。

    更新:此错误已于 2018 年 7 月 3 日在 Hypothesis 3.65.1 中修复。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-23
      • 1970-01-01
      • 1970-01-01
      • 2016-04-19
      • 1970-01-01
      • 2021-03-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多