关于在Hypothesis中选择条件代码路径的若干技术疑问
关于Hypothesis策略中代码路径选择的问题
大多数条件策略似乎都是数据驱动的,但如果我想独立于任何生成的数据选择代码路径该怎么办?
举个例子,我们把语法rule_a = rule_optional? rule_b转换成策略:
@strategy.composite def rule_a(draw): elem_b = draw(rule_b()) if draw(strategy.sampled_from([False, True])): elem_opt = draw(rule_optional()) elem_b = combine(elem_opt, elem_b) return elem_b
再比如,我要从语法生成一个数据结构,为测试特定行为,想通过替换语法树中特定位置子集里的随机选中节点来修改这个结构。重写语法生成修改后的数据太复杂,所以我直接修改生成的结构:
@strategy.composite def generate_maybe_modified(draw): data = draw(generate()) locations = [] for location, node in iterate(data): if match_specific(data, location, node): locations.append(location) if not draw(strategy.sampled_from([False, True])): return data modified = draw(modified()) location = draw(strategy.sampled_from(locations)) data = replace(location, data, modified) return data
问题1:上述实现的核心思路是通过从[False, True]中随机选择来挑选代码路径,其中将False放在首位是为了向最短代码路径收缩。这是最有效的解决方案吗?
问题2:draw(strategy.sampled_from([False, True]))与使用Hypothesis管理的random.choice([False, True])(即HypothesisRandom子类实例)之间有什么区别?
问题3:我能否在Hypothesis之外管理概率?即能否通过使用random.choices([False, True], [90, 10])[0]来提高简单代码路径被选中的概率?
回答
问题1:这是不是最有效的解决方案?
是,这是Hypothesis推荐的标准做法,优势很明确:
- Hypothesis会全程追踪
draw(strategy.sampled_from(...))的选择结果,测试失败时能通过回溯缩减精准定位触发问题的最小代码路径; - 把
False放在sampled_from的首位,Hypothesis会优先尝试这条更简单的路径,符合你“向最短代码路径收缩”的需求,同时它也会在后续测试中逐步覆盖复杂路径,不会遗漏边缘场景。
问题2:两种随机选择方式的区别
核心差异在于Hypothesis是否能干预和控制选择逻辑:
draw(strategy.sampled_from([False, True])):这个选择完全处于Hypothesis的管控范围内,测试失败时,Hypothesis可以通过缩减过程调整这个选择的值,找到最小的失败触发案例;同时Hypothesis会自动平衡选择概率,确保两种路径都被充分测试。- 使用Hypothesis管理的
random.choice([False, True]):虽然用的是Hypothesis提供的随机实例,但这个选择不会被Hypothesis的测试逻辑追踪,只是普通的随机值。Hypothesis无法在缩减时修改这个值,也不会主动保证两种路径的覆盖度,相当于把这部分逻辑从Hypothesis的控制体系中剥离了。
问题3:能不能在Hypothesis之外管理概率?
不建议这么做,原因有二:
- 用
random.choices([False, True], [90, 10])[0]这类外部随机逻辑,Hypothesis无法追踪选择结果,测试失败后没法通过缩减简化案例,会大幅增加调试难度; - 如果想调整路径选择的概率,正确的做法是用
strategy.sampled_from的权重参数,比如strategy.sampled_from([False, True], weights=[0.9, 0.1]),这样既满足你提高简单路径概率的需求,又能让Hypothesis全程管控选择逻辑,保证测试的可复现性和缩减能力。
内容的提问来源于stack exchange,提问作者user19087
相关产品推荐
相关产品推荐

