我有一个简单的数据结构可以在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接受的答案中给出的解决方案,并在最小的工作示例中实现了它们(谢谢,罗马):
{-# 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)
答案 0 :(得分:3)
我首先要列出美味和控制的控制手段。 smallcheck开箱即用:
--smallcheck-depth
选项来控制«common»depth adjustOption
调整相对于在命令行(或父树)上指定的任何子树的深度localDepth
来调整每个特定字段所需的深度,相对于整个结构的深度。通常它的总深度为1(这是decDepth
在标准定义中的作用),但您可以创建自己的规则。因此,这种控制是可能的,尽管是间接的。通常情况下,这也是你想要的 - 另见this answer。
如果确实希望在运行时控制各个字段的深度......是的,虽然它有点复杂,但它有可能,因为它不是预期的用例。 (尽管如此,它仍然非常酷!)Here's a working example.
如果此功能对您很重要,可以在github上打开一个问题并解释您需要它的原因。 (但首先,请务必阅读我对上面链接的ocharles的回复。很少需要在运行时调整深度。)
答案 1 :(得分:1)
总结和举例说明,假设你想尝试深度为2,你有几个选择。
直接运行测试套件(可执行文件)时:
./test --smallcheck-depth 2
从cabal运行测试套件时:
cabal test --test-options="--smallcheck-depth 2"
通过更改testGroup / TestTree中的深度:
-- Global depth + 1 (usually supplied by command line)
props = adjustOption (+ SmallCheckDepth 1) $
testGroup "some props"
[ SC.testProperty myProp1
, SC.testProperty myProp2
]
-- Local depth = 2
prps2 = localOption (SmallCheckDepth 2) $
testGroup "fixed depth"
[ ... ]
adjustOption和localOption也可用于特定属性。我个人认为adjustOption是首选,因为它只是调整命令行提供的任何内容或任何封闭的TestTree。