首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell / SmallCheck:如何控制“`Depth`”参数?

Haskell / SmallCheck:如何控制“`Depth`”参数?
EN

Stack Overflow用户
提问于 2013-12-14 11:36:08
回答 2查看 433关注 0票数 4

我有一个简单的数据结构可以在smallcheck中测试。

代码语言:javascript
复制
{-# 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,以避免搜索空间的组合爆炸?

事先非常感谢!

jules

信息:一个有点相关的问题是这里

编辑:

我采用了罗曼·切普里亚卡接受的答案中给出的解决方案,并在一个最小的工作示例中实现了这些解决方案(谢谢,罗曼):

代码语言:javascript
复制
{-# 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) 
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-14 17:37:43

首先,我将列出美味和smallcheck提供的控制方法:

  • 在运行测试套件时,可以通过--smallcheck-depth选项来控制公共深度。
  • 在编写测试套件时,可以使用adjustOption来调整任何子树的深度(相对于命令行(或父树)上指定的内容)。
  • 最后,在编写串行实例时,可以使用localDepth来调整每个特定字段的深度,相对于整个结构的深度。通常是总的深度-1(这是decDepth在标准定义中所做的),但是您可以发明自己的规则。

因此,这种控制是可能的,尽管是间接的。通常情况下,这都是你想要的--参见这个答案

如果您真的想在运行时控制各个字段的深度.是的,这是可能的,尽管它有点复杂,因为它不是一个预期的用例。(尽管如此,这是很酷的,它是可能的!) 下面是一个有用的例子。

如果此功能对您很重要,请在github上打开一个问题并解释为什么需要它。(但首先,一定要读一读我对上面提到的ocharles的回应。很少需要在运行时调整深度。)

票数 3
EN

Stack Overflow用户

发布于 2014-06-04 18:50:21

为了总结和举例说明,假设你想尝试两种深度,你有几种选择。

当直接运行测试套件(可执行文件)时:

代码语言:javascript
复制
./test --smallcheck-depth 2

在从阴谋集团运行测试套件时:

代码语言:javascript
复制
cabal test --test-options="--smallcheck-depth 2"

通过更改testGroup/TestTree中的深度:

代码语言:javascript
复制
-- 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"
        [ ... ]

adjustOptionlocalOption也可以用于特定的属性。我个人认为adjustOption更好,因为它只是调优命令行提供的任何内容或任何包含TestTree的内容。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20582795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档