我是hypothesis的新手,我正在寻找一种生成一对相似的递归对象的方法。
我对单个对象的策略类似于假设文档中的example。
我想测试一个带有一对递归对象A和B的函数,并且此函数的副作用应该是A==B
。
我的第一种方法是编写一个获取两个独立对象的测试,例如:
@given(my_objects(), my_objects())
def test_is_equal(a, b):
my_function(a, b)
assert a == b
但是不利的一面是,假设不知道这两个对象之间存在依赖关系,因此它们可以完全不同。那是一个有效的测试,我也想对此进行测试。
但是我还想测试仅稍有不同的复杂递归对象。
也许这个假设能够将测试失败的一对非常不同的对象缩小为测试失败的一对仅有一点不同的对象,以相同的方式进行。
答案 0 :(得分:1)
这是一个棘手的问题-老实说,我将通过编写上面已经存在的相同测试开始,然后将max_examples设置调大一点。然后,我可能会写一些传统的单元测试,因为明显不支持从假设中获取特定的数据分布(即,我们尝试使用启发式方法和一些反馈来打破假定特定分布的所有内容)。
我实际上如何生成类似的递归结构?我会使用@composite
策略同时构建它们,并且对于每个元素或子树,我会绘制一个布尔值(或integers(0, 255).map(lambda n: n == 0)
),如果True,则绘制一个不同的元素或子树来使用在第二个对象中。请注意,这将为您提供一个包含两个对象的元组的策略,您需要在测试中将其拆包。如果您希望它们相互关联,这是不可避免的。
尽管确实要先尝试仅仅在朴素的方法上破解max_examples,但是运行假说一个小时会非常有效,我什至希望它可以很好地缩小输出。