首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >小检查中的“`Depth`”参数应该控制多少?

小检查中的“`Depth`”参数应该控制多少?
EN

Stack Overflow用户
提问于 2013-11-20 09:37:11
回答 2查看 414关注 0票数 5

我正在使用smallcheck做我的第一个实际工作,我对如何使用Depth参数感到有点困惑。在我讨论这个问题之前,让我先说明一下我正在使用smallcheck做什么。

在工作中,我们在自己的内部数据库前面构建一个简单的web服务。web服务执行一些查询,并使用序列化为JSON的查询结果进行响应。我目前正在做的是保证:给定一个表示查询结果的对象,该对象将生成预期的JSON。例如:

代码语言:javascript
复制
data Action
  = Action { actionType :: !ActionType 
           , actionDescription :: !Text
           , actionPerformedAt :: !UTCTime
           , actionAgentName :: !Text
           }

必须生成JSON,如:

代码语言:javascript
复制
{
  "type": "Booking",
  "description": "Whatever",
  "performedAt": "2012-01-04",
  "agent": "Tom"
}

对于smallcheck来说,这似乎是一项理想的任务,我将其表述如下:

代码语言:javascript
复制
testAction :: Tasty.TestTree
testAction = Tasty.testGroup "Action"
  [ SmallCheck.testProperty "type" $
      SmallCheck.over actions $ match $
        Aeson.key "type" --> Aeson.toJSON . actionType

  , SmallCheck.testProperty "dateActioned" $
      SmallCheck.over actions $ match $
        Aeson.key "dateActioned" --> expectedUTCTimeEncoding . actionPerformedAt

  -- and so on
  ]

-- (-->) :: Eq a => lens-aeson traversal a -> (b -> a) -> b -> Bool
-- actions :: Monad m => SmallCheck.Series m Action

smallcheck框架中,默认的tasty深度是5,这导致了我尚未看到的测试运行。smallcheckchangeDepthchangeDepth1函数,所以我可以使用它们作为changeDepth (const 3)来确保测试总是在合理的时间内运行。然而,通过这样做,我不禁觉得我在某个地方漏掉了重点?例如,现在不可能通过更改命令行选项来运行测试,可能是在一夜之间运行更长的测试。另一方面,如果我使用changeDepth (- 2),我仍然觉得我在假设测试是如何运行的!也许最好假设5秒的全局测试深度在n秒钟内运行,并由每个属性根据自己认为合适的深度来调整深度?

希望能听到一些关于smallcheck这个更实用的方面的反馈。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-20 10:48:46

虽然smallcheck的“穷竭性”(无论如何对于小案例而言)是一个有趣的特性,但我建议在这种情况下使用quickcheck。虽然JSON有一个轻量级的结构,但从实际数据的角度来看,它相当沉重。

测试时间在很大程度上也取决于您如何定义"size“(深度),以便在Series实例中为您的类型进行小检查。如果您的类型有很多分支(许多构造函数),那么测试的数量将迅速增加。它在“深度”上是指数,而指数的基础是与特定测试案例相关的Series实例中的分支量。

换句话说,如果平均有2个构造函数,则需要运行大约32个测试用例,但如果有20个,则更像是3200000。

但是,您的覆盖率也会受到影响--如果您减少了测试用例中的分支(使深度增加得更快),那么在给定深度的情况下,您将得到较少的覆盖率。有了quickcheck,您就会丢失一些“小”测试案例,转而选择一些更大的示例,而这些示例是您无法用smallcheck获得的。

票数 3
EN

Stack Overflow用户

发布于 2013-12-09 11:15:51

当您使用QuickCheck的随机测试进行测试时,您拥有的唯一标准是测试的,因此尽可能多地进行测试是很自然的。

SmallCheck是不同的,因为您实际上可以关于正在测试的的原因。理想情况下,您不应该仅仅将深度视为与您对测试结果的信心相关的度量,但是您应该对需要的深度有一个很好的了解。

如果我们讨论的是JSON,那么处理JSON 的大多数函数一次使用一层,有时是两层结构,。因此,如果有一个bug,它可以发现在一个深度2或3的结构,粗略地说。(您需要根据Serial实例找到或计算smallcheck的深度,从而为您提供所需的结构深度。)

因此,要回答您的问题,如果深度3是您所能负担的最大深度,那么首先您应该决定这是否足以满足您正在测试的代码类型。

如果它恰好不够,那么您可以用宽度来换取深度(例如,通过降低叶值的深度),或者实际上切换到QuickCheck的随机枚举策略。

我认为,只有当您认为您正在测试的函数可能由于结构的大小而存在bug,而不是结构组件的某些本地组合时,您才应该使用QuickCheck。我能想到的一些例子是:

  • 数值溢出
  • 未被发现的任意硬编码限制(也许在国外C代码中--这是Haskell代码中非常不典型的)。
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20092191

复制
相关文章

相似问题

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