Unit testing 如何编写不使用';t模拟函数的实现?

Unit testing 如何编写不使用';t模拟函数的实现?,unit-testing,haskell,testing,quickcheck,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 $ elemI

我正在使用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中编写一个测试来测试函数的用途,而不重复其实现

如何在QuickCheck中编写一个测试来测试函数的用途,而不重复其实现

首先,请注意,有时,表示函数按照其当前实现运行的quickcheck属性并非完全没有价值。如果更改了实现,可以将其用于回归测试。例如,如果您优化了
fn
的定义以使用巧妙的数据结构,那么基于旧的、更直接的实现的Quickcheck属性可能会有所帮助

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

  • 对于点ps和方向d的所有列表,点
    fn ps d
    位于列表ps中

  • 对于点ps、方向d和ps中所有点p的列表,点p在方向d上的距离不超过点
    fn ps d

  • 对于所有点p和所有方向d,
    fn[p,原点]d
    为p


我不能完全确定基本的几何结构,所以我的例子可能很愚蠢。但我希望这些示例传达了一个总体思路:quickcheck属性可以检查规范的属性“在一个方向上走得更远”,而不提及特定的算法。

如果有人觉得问题太广泛,请考虑这个问题,特别是针对函数<代码> fn>代码>。如果你分享了更多关于你的问题的信息,如特定的不充分的测试,你期望的,以及dotPROD类型的来源,这会有帮助。你能为一个点写一个<代码>任意< /代码>吗?方向?如果是这样,随机生成的点的哪些属性不令人满意?请添加更多信息,以便您的代码是正确的。特别是,
DotProd
的定义及其一些实例。如果您添加了您尝试过的快速检查测试,这也会有所帮助。编码提示:查看
Data.List
中的
maximumBy
函数。使用fromJust的
是不安全的,因为它可能引发异常。