温馨提示:本文翻译自stackoverflow.com,查看原文请点击:haskell - How to write EqProp instances for quickBatch tests?
haskell quickcheck

haskell - 如何为quickBatch测试编写EqProp实例?

发布于 2020-04-10 10:23:48

我遇到了两个例子:

data List a = 
    Nil 
  | Cons a (List a) 
  deriving (Eq, Show) 

instance Eq a => EqProp (List a) where
  (=-=) = eq
newtype ZipList' a = 
  ZipList' (List a) 
  deriving (Eq, Show)

instance Eq a => EqProp (ZipList' a) where 
  xs =-= ys = xs' `eq` ys' 
    where xs' = let (ZipList' l) = xs 
                in take' 3000 l 
          ys' = let (ZipList' l) = ys 
                in take' 3000 l 

take' :: Int -> List a -> List a
take' n (Cons a as) = Cons a (take' (n - 1) as)

(还有FunctorApplicative实例正在测试中):

main :: IO ()
main =
  hspec $ do
    describe "List" $ do
      it "Functor" $
        property (quickBatch $ functor (undefined :: List (Int, Float, String)))
      it "Applicative" $
        property
          (quickBatch $ applicative (undefined :: List (Int, Float, String)))
    describe "ZipList'" $ do
      it "Functor" $
        property
          (quickBatch $ functor (undefined :: ZipList' (Int, Float, String)))
      it "Applicative" $
        property
          (quickBatch $ applicative (undefined :: ZipList' (Int, Float, String)))

据我了解,我们采用3000个值,因为否则测试将永远追逐无限列表。但是在第一个示例中,也有一个无限的列表,不是吗?那么为什么EqProp在这种情况下琐碎呢?

查看更多

提问者
kirill fedorov
被浏览
118
Fresheyeball 2020-02-01 20:14

您的属性测试库(我知道quickCheck,但不知道quickBatch)应该在生成值时(而不是在比较值时)管理数据大小。在相等性检查中限制大小是一个坏主意,因为这意味着

  1. 数据生成可能是无限的,因此在进行相等性检查之前,您的测试可以不终止
  2. 3001st元素不同时,您可能会产生误报

既然已经有和的实例,[]并且ZipList是一个,newtype我们可以像这样免费获得实例。

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StandaloneDeriving #-}

deriving instance Eq a => EqProp (ZipList' a)