这个问题涉及到Haskell QuickCheck 最佳实践(尤其是在测试类型类时)停止的地方。
我有一个类和该类的一堆实现。像这样的东西:
import Test.QuickCheck
import Control.Applicative
import Test.Framework
import Test.Framework.Providers.QuickCheck2
class C c where
f :: c -> Int
data A = A Int deriving Show
instance C A where
f (A a) = 2*a
data B = B Int deriving Show
instance C B where
f (B b) = 2*b
我所有的实现都应该满足某个属性。例如:
prop_f_is_even :: C c => c -> Property
prop_f_is_even x = property $ even (f x)
我想为每个实现测试该属性。我可以做这样的事情。(我正在使用 Test.Framework。)
instance Arbitrary A where
arbitrary = A <$> arbitrary
instance Arbitrary B where
arbitrary = B <$> arbitrary
test :: Test
test = testGroup "Whole buncha tests"
[
testProperty "prop_f_is_even - A" (prop_f_is_even :: A -> Property),
testProperty "prop_f_is_even - B" (prop_f_is_even :: B -> Property)
-- continue on for all combinations of properties and implementations
]
但就我而言,我有几十个属性要测试,还有十几个类,所以这种方法容易出错,而且很麻烦。(我犯的一个常见错误是剪切和粘贴测试,但忘记更改类型名称,所以我最终为该属性测试 A 两次,而没有测试 B。)
我有一个解决方案,我会在下面发布,以防其他人觉得它有帮助。