【发布时间】:2013-12-14 11:36:08
【问题描述】:
我有一个简单的数据结构要在 smallcheck 中进行测试。
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
{-# LANGUAGE DeriveGeneric #-}
import Test.Tasty
import Test.Tasty.SmallCheck
import Test.SmallCheck.Series
import GHC.Generics
data T1 = T1 { p1 :: Int,
p2 :: Char,
p3 :: [Int]
} deriving (Eq, Show, Generic)
instance Monad m => Serial m T1
main :: IO ()
main = defaultMain tests
tests :: TestTree
tests = testGroup "Tests" [scProps]
scProps = testGroup "(checked by SmallCheck)"
[ testProperty "Test1" prop_test1
]
prop_test1 x = x == x
where types = (x :: T1)
在运行测试时,是否有任何通用解决方案可以为(单个)测试设置 Depth 参数,或者更好的是,为单个字段设置 Depth 参数的细粒度解决方案,例如将p3的深度限制为2,避免搜索空间的组合爆炸?
非常感谢!
朱尔斯
信息: 一个有点相关的问题是here。
编辑:
我采用了Roman Cheplyaka 接受的答案中给出的解决方案,并在一个最小的工作示例中实现了它们(感谢 Roman):
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
import Test.Tasty
import Test.Tasty.Options
import Test.Tasty.SmallCheck
import Test.SmallCheck.Series
import Data.Functor
-- =============================================================================
main :: IO ()
main = defaultMain tests
-- =============================================================================
-- the data structure to be tested
data T1 = T1 { p1 :: Int,
p2 :: Char,
p3 :: Int,
p5 :: [Int]
} deriving (Show, Eq)
-- =============================================================================
-- some test-properties
prop_test1 x y = x == y
where types = (x :: T1, y :: T1)
prop_test2 x = x == x
where types = (x :: T1)
-- =============================================================================
-- how to change the depth of the search spaces?
{-| I Possibility: Command Line |-}
-- foo@bar$ runhaskell Test.hs --smallcheck-depth 2
-- -----------------------------------------------------------------------------
{-| II Possibility: |-}
-- normal:
-- tests :: TestTree
-- tests = testGroup "Tests" [scProps]
-- custom:
tests :: TestTree
tests = localOption d $ testGroup "Tests" [scProps]
where d = 3 :: SmallCheckDepth
scProps = testGroup "(checked by SmallCheck)"
[ testProperty "Test1" prop_test1,
testProperty "Test2" prop_test2
]
-- -----------------------------------------------------------------------------
{-| III Possibility: Adjust Depth when making the type instance of Serial |-}
-- normal:
-- instance (Monad m) => Serial m T1 where
-- series = T1 <$> series <~> series <~> series <~> series
-- custom:
instance (Monad m) => Serial m T1 where
series = localDepth (const 4) $ T1 <$> (localDepth (const 2) series) <~> series <~> series <~> (decDepth series)
-- (a few more examples):
-- instance (Monad m) => Serial m T1 where
-- series = decDepth $ T1 <$> series <~> series <~> series <~> (decDepth series )
-- instance (Monad m) => Serial m T1 where
-- series = localDepth (const 3) $ T1 <$> series <~> series <~> series <~> series
-- instance (Monad m) => Serial m T1 where
-- series = localDepth (const 4) $ T1 <$> series <~> series <~> series <~> (decDepth series)
【问题讨论】:
-
见stackoverflow.com/questions/15959357/…——几个小时前我正在寻找这个问题的答案,偶然发现了这个链接。
-
@jules 关于您的编辑,我想指出的是,没有必要只选择一种方式并确定深度(尽管您可以根据需要)。如果您使用相关函数(
adjustOption、localDepth没有const),这些控件可以很好地组合。特别是,在 SmallCheck 中使用localDepth . const并不是一个好主意。
标签: testing haskell automated-tests smallcheck