如何编写不模仿函数实现的QuickCheck测试?

时间:2014-02-16 02:08:46

标签: unit-testing haskell testing quickcheck

我正在使用Haskell和QuickCheck为以下函数编写测试:

{-| Given a list of points and a direction, find the point furthest
along in that direction. -}

fn :: (Eq a, Ord a, DotProd a) => [a] -> a -> a
fn pnts dir = pnts !! index
    where index = fromJust $ elemIndex (maximum dotproducts) dotproducts
          dotproducts = map (dot dir) pnts

我认为这个实现是正确的,因为它不是太复杂的功能。但是,我想使用QuickCheck来测试一些边缘情况。

然而,我遇到的问题是,当我定义我的QuickCheck测试时,它们与我正在测试的功能相同。

如何在QuickCheck中编写一个测试功能目的而不重复实现的测试?

1 个答案:

答案 0 :(得分:14)

  

如何在QuickCheck中编写一个测试功能目的而不重复实现的测试?

首先,请注意,有时候,一个表示某个函数根据其当前实现行为的quickcheck属性并非完全没用。如果您更改了实现,则可以将其用于回归测试。例如,如果优化fn的定义以使用聪明的数据结构,则基于旧的,更直接的实现的Quickcheck属性可能会有所帮助。

第二,您经常希望Quickcheck属性检查函数的高级和声明属性,而实现通常是较低级别且可直接执行。在这种情况下,您可以指定以下属性:

  • 点ps和方向d的列表,点fn ps d在列表ps中。

  • 以ps为单位的点ps,方向d和forall点p的列表,点p在方向d上不比点fn ps d更远。

  • forall p和forall direction d,fn [p, origin] d是p。

我不完全确定基础几何,所以我的例子可能是愚蠢的。但我希望这些例子能够传达一般的想法:快速检查属性可以检查规范的属性“在一个方向上更进一步”,而不提及特定的算法。