Hypothesis项目中的策略收缩设计指南

Hypothesis项目中的策略收缩设计指南

hypothesis Hypothesis is a powerful, flexible, and easy to use library for property-based testing. hypothesis 项目地址: https://gitcode.com/gh_mirrors/hy/hypothesis

引言

在自动化测试领域,Hypothesis项目以其强大的属性测试功能而闻名。其中一个关键特性是其出色的测试用例收缩(shrinking)能力——能够自动将触发错误的复杂测试用例简化为最小可重现示例。本文将深入探讨如何设计策略(strategy)以获得最佳的收缩效果。

何时需要考虑收缩设计

对于大多数用户来说,Hypothesis内置的收缩机制已经足够优秀,不需要额外优化。但在以下两种情况下,投入精力优化策略的收缩行为是值得的:

  1. 广泛使用的自定义策略:当你的策略将被大量用户使用时,优化收缩行为的收益会被放大
  2. 重复调试复杂失败案例:当你发现自己经常需要手动简化测试用例来调试问题时

如果以上情况都不适用,建议直接使用Hypothesis提供的默认策略,它们已经经过精心设计,能够提供优秀的收缩效果。

第三方策略的收缩设计

收缩的复合原则

Hypothesis采用"自底向上"的收缩方式。这意味着策略的每个组成部分都应该能够独立收缩,且组成部分的简化应该导致整体结果的简化。

以复数生成策略为例,我们希望在收缩时虚部先趋于零,因为我们认为纯实数比纯虚数更"简单"。这需要在策略设计时就考虑收缩顺序。

让生成变得"幸运"

有时,我们需要主动寻找某些特殊值进行测试。一个技巧是在策略中加入条件分支,让收缩器可以选择是否采用这些特殊值。

例如,在生成时区感知的日期时间时,我们希望更频繁地生成由于夏令时转换而被跳过或重复的时刻。传统二分查找方法收缩成本较高,而采用随机点查找方法可以让收缩器删除中间步骤,看起来就像"幸运地"一次就找到了目标时刻。

保持数据局部性

Hypothesis将每个测试用例视为带标签的选择树,收缩操作就是对这些树的修改。为了获得最佳收缩效果,应该:

  1. 避免先绘制大小再绘制集合的模式,这会破坏局部性
  2. 将过滤条件尽可能靠近相关策略部分
  3. 一次性绘制对象的所有属性或输入

例如,以下两种生成列表的方式虽然结果相同,但后者具有更好的收缩性能:

# 不推荐的方式
integers(0, 10).flatmap(lambda n: st.lists(..., min_size=n, max_size=n))

# 推荐的方式
st.lists(..., min_size=1, max_size=10)

Hypothesis内部的收缩技巧

这部分内容主要针对Hypothesis贡献者,涉及一些内部API的使用技巧。

内部API的优势

使用低级内部API可以:

  1. 在比特流级别操作,更清晰地看到值与缓冲区的对应关系
  2. 看到表示变换子集的缓冲区范围
  3. 处理一些极端情况下的性能问题

创造自己的"幸运"

这个技巧用于避免过滤导致的性能问题,同时为收缩器提供相同的低级表示。基本步骤是:

  1. 首先尝试从完整列表中随机选择
  2. 如果不符合条件,再从符合条件的子列表中选择
  3. 将子列表中选择项在完整列表中的索引写入缓冲区

这样收缩器删除前几步后,缓冲区会直接指向有效选项。

"收缩开放"的标志

受"群体测试"概念启发,随机禁用某些特性实际上可能更快发现错误。实现时需要注意:

  1. 标志应该能够"收缩开放",最终所有标志都会被启用
  2. 对收缩器来说应该像使用了拒绝采样

例如在Unicode字符串生成中,可以先禁止某些字符类别,收缩时再逐步放开限制。

显式的示例边界

有时需要显式标记应该同时删除的绘制操作。这可用于:

  1. 分组相关值(如浮点数的值和符号)
  2. 界定可变大小的绘制
  3. 标记难以区分的绘制以便交换

总结

设计良好的策略收缩行为需要考虑多方面因素。对于大多数用户,使用Hypothesis内置策略已经足够。当需要自定义复杂策略时,遵循本文提出的原则可以确保获得与内置策略同样优秀的收缩效果。记住,保持数据局部性和"自底向上"的收缩视角是关键所在。

hypothesis Hypothesis is a powerful, flexible, and easy to use library for property-based testing. hypothesis 项目地址: https://gitcode.com/gh_mirrors/hy/hypothesis

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

徐含微

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值