您是否在实际项目中使用过Quickcheck?

时间:2009-02-23 08:33:05

标签: java haskell testing quickcheck

Quickcheck及其变体(即使Java中有一个),似乎很有趣。但是,除了学术兴趣之外,它是否真正适用于真正的应用程序测试(例如,GUI应用程序或客户端/服务器,甚至是StackOverflow本身)?您对类似测试生成器的任何经验都表示赞赏。

11 个答案:

答案 0 :(得分:48)

是的,好吧。实际上没有,但我已经研究过最初开发QuickCheck的人,他是一个非常有趣的人。

早在2004年,我们被迫使用QuickCheck来测试我们的Haskell程序,它是好的和坏的组合。非常糟糕,因为Haskell本身有点令人生畏,但是当你开始工作时,它就不那么精彩了。

从那时起,John就完善了他多年前所写的内容,实际上帮助Ericssion测试了他们复杂的电信硬件,并且他发现了大约20百万行代码中的错误,通过他的方法将其减少到仅仅三步。他是一位出色的演讲者,所以听他讲述他的表现总是令人高兴,但总而言之,他对QuickCheck的所作所为对我来说是新的。所以我问他,他对将它推向市场的兴趣是什么。他对这个想法持开放态度,但当时他的业务(以QuickCheck为基础)相对较新,因此他会关注其他领域。现在是2007年。我的观点是,即使你最终没有使用它,你也可以向QuickCheck学习。

但是什么是QuickCheck?它是一个组合测试框架,也是测试程序的有趣方式。微软研究院的人员建立了Pex,这有点类似。 Pex通过检查您的IL自动生成测试。但是,John会为函数的可能输入和测试属性编写一个生成器。属性是可以轻松测试的东西,而且更正式。例如扭转名单?好吧,反转一个列表,就像将一个列表分成两半一样,将它们各自单独反转,然后以相反的顺序连接两个反向的一半。

1,2,3,4 // original
1,2 3,4 // split into A and B
2,1 4,3 // reverse A and B
4,3,2,1 // concat B and A

使用称为规范的QuickCheck测试这是一个很好的属性,结果非常惊人。

Pex很好,但不像QuickCheck那么酷,Pex简化了事情,QuickCheck做了,但是编写一个好的规范需要花费很多精力。

QuickCheck的强大之处在于,当它遇到故障时,它会将导致测试失败的输入减少到尽可能小的形式。让您详细了解状态的进展导致您的测试失败。与其他测试框架相比,它只是试图以暴力方式破坏您的代码。

由于您编写测试规范的方式,这是可能的。 QuickCheck依赖于伪随机性来发明输入,因此,它能够回溯并找到不能通过测试的非常小的输入。

编写QuickCheck属性要做的工作要多得多,但最终的结果是更好的测试。正如John自己所说,70%的错误都是通过单元测试来捕获的,但是其他30%会导致程序崩溃。 QuickCheck正在测试最后30%。

答案 1 :(得分:8)

我做了一个真正的Haskell问题,涉及离散事件模拟。所以我写了一个基于continuation monad的DES库,以及MVars和Channels的等价物。我需要检查这是否正常,所以我写了一堆QuickCheck属性来证明,例如,写入Channel的两个并发数据流将被正确合并而不会丢弃任何内容。

我还使用QuickCheck来记录和验证我的Ranged SetsDecimal库中的属性。

根据我的经验,QuickCheck有时很棒。如果你能够以简洁的方式总结一个重要的属性,虽然提供该属性的算法是毛茸茸的,但QuickCheck是一个巨大的胜利。另一方面,我经常发现该算法等同于我想要验证的属性。在那种情况下,我寻找更简单的属性。例如,假设函数“foo”应该是非严格单调的。然后你可以写

prop_fooMonotonic x y = (x > y) ==> (foo x >= foo y)

答案 2 :(得分:7)

我使用QuickCheck来处理很多个人的事情。在过去六个月内:

  • 使用QuickCheck测试图像压缩器中的颜色变换和离散余弦变换。

  • 使用QuickCheck测试一个符号微分模块,我进行了一些数值优化。

  • 使用QuickCheck测试Bentley和Sedgewick风格的三元搜索树。

QuickCheck很少满足所有我的单元测试需求,但这是一个很好的入门方式 - 而且QuickCheck法律可以提供良好的文档。

答案 3 :(得分:5)

我已经使用了很多,主要是以直接的方式,主要用于测试协议和解析器实现。

但是,根据我的个人经验,这里不那么简单:http://www.haskell.org/haskellwiki/QuickCheck_as_a_test_set_generator

答案 4 :(得分:5)

ScalaCheck(针对Scala的QuickCheck)用于测试Functional Java,这是一个实现a QuickCheck for Java的库。

答案 5 :(得分:3)

AFAIK XMonad使用QuickCheck

进行了广泛测试

答案 6 :(得分:2)

我只在生产环境中使用Haskell来开发小帮助工具。主要是因为我是我认识的唯一一个读Haskell的开发人员。我曾经广泛使用过QuickCheck,并且非常恼火,C#中没有类似的东西。所以我决定试试write it myself。我也看了Pex,但发现用于查找最小输入的程序探索技术不像QuickCheck那样有趣。

答案 7 :(得分:2)

我使用QuickCheck来测试用任何语言编写的命令行程序的行为。

查找低级别或动态类型程序崩溃的输入特别有用。

为方便起见,我写了http://hackage.haskell.org/package/proctest,其中包括一些与hspec和HUnit一起使用的QuickCheck示例,以此方式测试命令行程序。

答案 8 :(得分:1)

我们使用FsCheck检查我们的OCaml到F#转换是否正确,以及我们的优化版本与未优化版本的工作方式相同。我还打算用它来测试词法分析器和解析器,因为NHol项目使用parser组合器。

我们还有辅助函数,允许我们在NUnit(XUnit for .Net)中运行测试。请参阅assertProp

答案 9 :(得分:0)

我在LG Linux Mobile平台上使用QuickCheck测试SMS PDU编码器和解码器。我当时开发的一个软件的(旧)版本可以在http://hackage.haskell.org/package/GenSmsPdu-0.1

下载

答案 10 :(得分:0)

这不是我的项目,但containers包使用了相当广泛的QuickCheck。就个人而言,我尝试使用它来比较我在arithmoi写的一个愚蠢的小素数筛,这让我发现arithmoi中的一个有时会出现段错误。