在假设中跳过伪造的例子

ale*_*cxe 7 python testing unit-testing property-based-testing python-hypothesis

故事:

我目前正在使用单元测试函数hypothesis自定义生成策略试图找到一个特定的输入来"打破"我当前的解决方案.以下是我的测试结果:

from solution import answer

# skipping mystrategy definition - not relevant

@given(mystrategy)
def test(l):
    assert answer(l) in {0, 1, 2}
Run Code Online (Sandbox Code Playgroud)

基本上,当answer()函数没有返回0或1或2 时,我正在寻找可能的输入.

以下是我当前工作流程的样子:

  • 运行测试
  • hypothesis找到一个产生以下内容的输入AssertionError:

    $ pytest test.py 
    =========================================== test session starts ============================================
    ...
    ------------------------------------------------ Hypothesis ------------------------------------------------
    Falsifying example: test(l=[[0], [1]])
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用此特定输入调试函数,尝试了解此输入/输出是否合法,并且函数正常工作

问题:

如何跳过这个伪造生成的例子([[0], [1]]在这种情况下)并要求hypothesis生成另一个?


问题也可以解释为:hypothesis如果找到伪造的例子并且生成更多伪造的例子,我可以要求不终止吗?

DRM*_*ver 6

目前还没有办法让假设在发现失败后继续尝试(它可能会在某个时刻发生,但它不是很清楚这个应该是什么样的正确行为并且它不是优先考虑的事情),但是你可以使用假设功能让它忽略特定的失败类.

例如,您可以跳过此示例:

@given(mystrategy)
def test(l):
    assume(l != [[0], [1]])
    assert answer(l) in {0, 1, 2}
Run Code Online (Sandbox Code Playgroud)

假设将跳过您使用False参数调用假设的任何示例,并且不计入它运行的示例的预算.

您可能会发现这只会导致示例中的微不足道的变化,但您可以传递更复杂的表达式来假设忽略示例类.

你的实际用例是什么?正常的预期使用模式是她将修复导致假设失败的错误并让它以这种方式找到新的错误.我知道这并不总是实用,但我对其原因很感兴趣.

  • 你尝试过使用find()而不是given()吗?如果你对产生的价值感兴趣而不是测试本身,它可能是一个更好的工具 (2认同)