Haskell QuickCheck最佳实践(特别是在测试类型类时)

So8*_*res 19 testing haskell

我刚开始使用QuickCheck和一堆Haskell代码.我知道,我落后于时代.这个问题是两个部分:

首先,快速检查的一般最佳实践是什么?到目前为止,我已经选择了以下内容:

  • 将你的测试命名为prop_*(很烦人,因为其他一切都是camelCase)
  • 测试导出的代码(如果你正在测试内部,你可能做错了)
  • 测试属性,而不是示例
    • 不要说 X is out of range, Y is in range
    • 相反,说if x is out of range, normalize x ? x(或其他一些这样的财产)

但我仍然在抓住其他最佳实践.尤其:

  • 物业保存在哪里?
    • 同一档案?
    • 在一个test/目录?(如果是这样,那你如何导入这些东西src/?)
    • 在一个Properties/目录下src

最重要的是,我们如何倾向于测试类型类的属性?例如,考虑以下(简化)类型类:

class Gen a where
    next :: a -> a
    prev :: a -> a
Run Code Online (Sandbox Code Playgroud)

我想测试一下这个属性? x: prev (next x) == x.当然,这涉及为每个实例编写测试.为每个实例编写相同的属性是很繁琐的,特别是当测试更复杂时.推广此类测试的标准方法是什么?

Nor*_*sey 19

为每个实例编写相同的属性是很繁琐的

你不这样做.你为这个类写了一次属性:

class Gen a where
    next :: a -> a
    prev :: a -> a

np_prop :: (Eq a, Gen a) => a -> Bool
np_prop a = prev (next a) == a
Run Code Online (Sandbox Code Playgroud)

然后测试它,你转换为特定类型:

quickCheck (np_prop :: Int -> Bool)
quickCheck (np_prop :: String -> Bool)
Run Code Online (Sandbox Code Playgroud)

你提出的其他问题我无能为力.


iva*_*anm 10

我相信prop_会议来自QC,附带一个脚本,该脚本运行所有prop_以测试开头的功能.所以没有真正的理由这样做,但它确实在视觉上脱颖而出(所以函数的属性fooprop_foo).

测试内部结构并没有错.有两种方法:

  • 将属性放在与内部相同的模块中.这使得模块更大,并且需要对项目的QC无条件依赖(除非您使用CPP hackery).

  • 在非导出模块中具有内部功能,实际导出的功能从另一个模块重新导出.然后,您可以将内部模块导入到定义QC属性的模块中,并且如果使用.cabal文件中指定的标志,则仅构建该模块(并具有QC依赖性).

如果你的项目非常大,则有独立src/test/目录可能是有用的(虽然有区别可能会阻止您测试内部).但是如果你的项目不是那么大(并且无论如何都位于一个整体模块层次结构下),那么就没有必要像这样拆分它.

诺曼拉姆齐在他回答说,对于类型类你可以定义属性为的类型类,并相应地使用.