你有没有在一个真正的项目中使用Quickcheck
Quickcheck及其变体(甚至Java中有一个)似乎很有趣。 然而,除了学术上的兴趣之外,它在真正的应用程序testing(例如GUI应用程序或客户端/服务器,甚至是StackOverflow本身)中真的有用吗? 你有类似的testing发生器的任何经验,赞赏。
好吧。 其实不是,但我已经研究了最初开发QuickCheck的人,他是一个非常有趣的人。
早在2004年,我们被迫使用QuickCheck来testing我们的Haskell程序,这是好的和坏的结合。 主要是因为Haskell本身有点令人生畏,但是当你得到它的时候从来就不是那么美妙。
从那时起,John便完善了他多年前写的那篇文章,实际上帮助Ericssiontesting了他们复杂的电信硬件,他发现了两千万左右的代码,通过他的方法仅仅通过三个步骤就可以减less错误。 他是一位出色的演讲者,所以总是乐于听他介绍他做得如何,但总而言之,他用QuickCheck做的事对我来说是新的。 所以我问他,他把这个东西带到市场的兴趣是什么。 他对这个想法持开放态度,但是当时他的业务(基于QuickCheck)相对较新,所以还有其他方面需要关注。 现在是2007年。我的观点是,即使你不使用它,你也可以从QuickCheck学习。
但什么是QuickCheck? 这是一个组合testing框架和testing程序的有趣方法。 微软研究院的人员已经build立了类似的Pex 。 Pex通过检查您的IL自动生成testing。 但是,John会为函数的可能input和testing属性编写一个生成器。 一个属性是可以很容易地被testing的东西,它更加正式。 例如颠倒一个列表? 那么,颠倒一个列表,就像把列表分成两部分一样,分别颠倒它们,然后按相反的顺序连接两个相反的部分。
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
这是一个伟大的属性来testingQuickCheck称为规范,结果是相当惊人的。
Pex很好,但不像QuickCheck那么酷,Pex简化了一些东西,QuickCheck的确做了,但是写出一个好的规范需要花费很多精力。
QuickCheck的威力在于,当它发生故障时,会将导致testing失败的input减less到尽可能最小的forms。 留下你详细的描述什么样的进展状态导致你的testing失败。 与其他testing框架相比,这些testing框架只是试图以暴力的方式破坏你的代码。
由于您如何编写testing规范,这成为可能。 QuickCheck依靠伪随机性来发明input,正因为如此,它能够回溯并find真正的小input,而且不能通过testing。
编写QuickCheck属性还有很多工作要做,但最终结果是更好的testing。 正如约翰自己所说的,70%的错误是由unit testing捕获的,但另外30%的错误会导致程序崩溃。 QuickCheck正在testing那些最后的30%。
我做了一个真正的Haskell问题,涉及到一个离散事件模拟。 于是我写了一个基于继续monad的DES库,以及MVars和Channels的等价物。 我需要检查这个工作是否正常,所以我写了一堆QuickCheck属性来演示,例如,写入一个Channel的两个并发数据stream将被正确地合并而不会丢失任何东西。
我也使用QuickCheck来logging和validation我的远程集和十进制库中的属性。
根据我的经验,QuickCheck有时候很棒。 如果您能够以简洁的方式总结一个重要的属性,虽然交付该属性的algorithm是毛茸茸的,然而QuickCheck是一个巨大的胜利。 另一方面,我经常发现algorithm等价于我想validation的属性。 在这种情况下,我寻找更简单的属性。 例如,假设函数“foo”应该是非严格单调的。 然后你可以写
prop_fooMonotonic xy = (x > y) ==> (foo x >= foo y)
我使用QuickCheck的很多个人的东西。 在过去六个月内:
-
冉QuickChecktesting图像压缩器中的颜色变换和离散余弦变换。
-
冉QuickChecktesting一个符号分化模块我掀起了一些数值优化。
-
运行QuickCheck,testingBentley和Sedgewick风格的三元search树。
QuickCheck很less能够满足我所有的unit testing需求,但这是一个很好的入门方式—而且QuickCheck的法律文件也很好。
我用了很多,主要是直接用于testing协议和parsing器的实现。
不过,从我个人的经历来看,这里并不重要: http : //www.haskell.org/haskellwiki/QuickCheck_as_a_test_set_generator
ScalaCheck (用于Scala的QuickCheck )用于testingFunctional Java ,这是一个库,除其他外,它实现了Java的QuickCheck 。
AFAIK XMonad广泛使用QuickCheck进行testing
我只在生产环境中使用Haskell来开发小帮手工具。 主要是因为我是唯一读过Haskell的开发者。 尽pipe我广泛地使用了QuickCheck,并且非常恼火,类似的东西在C#中是不可用的。 所以我决定尝试自己写 。 我也看了Pex,但发现程序探索技术是用来find最less的input比QuickCheck没有那么有趣。
我使用QuickCheck来testing用任何语言编写的命令行程序的行为。
find低级或dynamictypes的程序崩溃的input是特别有用的。
为了方便起见,我写了http://hackage.haskell.org/package/proctest ,其中包括QuickCheck与hspec和HUnit一起使用来testing命令行程序的一些例子。
我们使用FsCheck来检查我们的OCaml到F#翻译是否正确,并且我们的优化版本与未优化版本的工作方式相同。 我也计划使用它来testing词法分析器和parsing器,因为NHol项目使用parsing器组合器。
我们也有帮助函数,允许我们在NUnit (XUnit for .Net)中运行testing。 看assertProp 。
我已经使用QuickCheck在LG Linux Mobile平台上testingSMS PDU编码器和解码器。 当时开发的一个(旧版)软件可以在http://hackage.haskell.org/package/GenSmsPdu-0.1下载。;
这不是我的项目,但containers
包使用QuickCheck相当广泛。 就我个人而言,我试图用它来比较一个我在arithmoi
写的一个愚蠢的小素筛,这使我发现arithmoi
中的一个有时会出现段错误。