简体   繁体   English

如何从QuickCheck中获得好(小)缩小?

[英]How do I get good (small) shrinks out of QuickCheck?

I'm trying to run QuickCheck on some nested lists, something that looks like this: 我试图在一些嵌套列表上运行QuickCheck,看起来像这样:

type Constraint = Text
data Value = Value [Constraint]
data Literal = Literal Value [Value]
type Formula = [Literal]

So a formula is a list of literals, each of which contains a predicate and some arguments; 所以公式是一个文字列表,每个文字都包含一个谓词和一些参数; predicate/arguments are values which are a disjunction of constraints in string form each. 谓词/参数是每个字符串形式的约束分离的值。 That gives us a list of lists of lists of lists, phew! 这给了我们一份列表清单列表,p!

If one of my QuickCheck properties fails, I tend to get an incomprehensible pageful of output. 如果我的一个QuickCheck属性失败,我倾向于得到一个难以理解的页面输出。 Before experimenting with shrink, I used to get around this by having arbitrary instances that could only generate a small set of (small) values. 在尝试收缩之前,我曾经通过使用只能生成一小组(小)值的任意实例来解决这个问题。 Implementing the shrink function for each of my types seems to help a little, but not as much as I'd like. 为我的每个类型实现收缩功能似乎有点帮助,但没有我想要的那么多。 I still get a pageful of output. 我仍然得到一页输出。

I think what I want from shrink is a small list of literals, where each literal has a small list of values, which in turn has few constrains, each of which is as short as possible. 我认为我想要收缩的是一个小文字列表,其中每个文字都有一个小的值列表,而这些值又有很少的约束,每个约束都尽可能短。 But in my current efforts, at least of these lists gets big enough to make the output horrible. 但在我目前的努力中,至少这些列表变得足够大,使输出变得可怕。 If I try to tune my shrink implementations, I also find that QC starts taking a very long time (searching for shrinks?), which kind of dampens my efforts to shrink effectively. 如果我尝试调整缩小实现,我也发现QC开始花费很长时间(寻找收缩?),这会削弱我有效收缩的努力。

How do you improve your chances of understanding QuickCheck failures when you have nested data like this? 当您嵌套这样的数据时,如何提高理解QuickCheck失败的几率?

FWIW,请看https://github.com/leepike/SmartCheck ,它声称可以获得比人们通常手动更好的收缩。

I had a similar problem, but I was using C and home made example generator :) I had slow and correct, and fast and incorrect implementation. 我有类似的问题,但我使用C和自制的示例生成器:)我有慢和正确,快速和不正确的实现。

Using random examples, when you find incorrect example, I would suggest shrinking of example itself. 使用随机示例,当您找到不正确的示例时,我建议缩小示例本身。 (This, of course, could or should, be done by program, instead of by computer) (当然,这可以或应该由程序而不是计算机来完成)

If you have predicate for this test, and you have example that does not work, try eliminating elements form lists, of all orders (this should be linear order of magnitude of callings) and for each try if it fails the test. 如果您有此测试的谓词,并且您有不起作用的示例,请尝试删除所有订单的元素表单列表(这应该是调用的线性数量级),并且如果测试失败则尝试每次尝试。

If it is still failing, there is no reason for keeping this in example. 如果仍然失败,则没有理由将此保留在示例中。

If it starts passing, then this element should stay in reduced example. 如果它开始传递,那么这个元素应该保留在缩减的例子中。

(This is greedy and not optimal, but it does execute in poly, instead of exponential time, and it worked for me) (这是贪婪的,不是最优的,但它确实在poly中执行,而不是指数时间,它对我有效)

For more scientific look, I suggest chapter "Simplifying problems" from the book "WHY PROGRAMS FAIL: A Guide to Systematic Debugging" by A.Zeller. 为了更科学地看,我建议A.Zeller出版的“为什么程序失败:系统调试指南 ”一书中的“简化问题”一章。

Note: this is mostly what shrink does... 注意:这主要是收缩的...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM