Этот вопрос берет начало, где Haskell QuickCheck best practices (especially when testing type classes) остановился.Определение набора тестов для класса
У меня есть класс и множество реализаций этого класса. Что-то вроде этого:
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
]
Но в моем случае, у меня есть десятки свойств, чтобы проверить, и десяток или около того классов, так что подход к ошибкам, и хлопот. (частая ошибка я сделать это, чтобы вырезать и вставить тесты, но забудьте изменить имя типа, так что я в конечном итоге тестирует два раза для этого свойства, не испытывая B.)
У меня есть решение, которое Я опубликую ниже, если кто-то найдет это полезным.