如何在假设中定义一个策略来生成一对相似的递归对象

How to define a strategy in hypothesis to generate a pair of similar recursive objects

我是 hypothesis 的新手,我正在寻找一种方法来生成一对相似的递归对象。

我对单个对象的策略类似于假设文档中的这个example

我想测试一个接受一对递归对象 A 和 B 的函数,这个函数的副作用应该是 A==B.

我的第一种方法是编写一个获取两个独立对象的测试,例如:

@given(my_objects(), my_objects())
def test_is_equal(a, b):
    my_function(a, b)
    assert a == b

但缺点是假设不知道这两个对象之间存在依赖关系,因此它们可能完全不同。这是一个有效的测试,我也想测试一下。

但我也想测试仅略有不同的复杂递归对象。

也许该假设能够将测试失败的一对非常不同的对象缩小为测试以相同方式失败的一对仅略有不同的对象。

这很棘手 - 老实说,我会先编写与上面相同的测试,然后将 max_examples 设置调大一点。然后我可能会编写一些传统的单元测试,因为明确不支持从假设中获取特定的数据分布(即我们尝试使用启发式和一些反馈的某种组合来打破假设特定分布的所有内容)。

我实际上如何生成类似的递归结构?我将使用 @composite 策略同时构建它们,并且为每个元素或子树绘制一个布尔值,如果为真,则绘制不同的元素或子树以用于第二个对象。请注意,这将为您提供一个包含两个对象的元组的策略,您需要在测试中将其解包;如果你想让它们有关联,那是不可避免的。

认真地尝试先尝试 max_examples 天真的方法,运行 一个小时的假设非常有效,我什至希望它能很好地缩小输出。