我正在使用smallcheck进行第一部分实际工作,并且对如何使用Depth参数有些困惑。在开始之前,请先说明一下我使用smallcheck的目的。

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

data Action
  = Action { actionType :: !ActionType
           , actionDescription :: !Text
           , actionPerformedAt :: !UTCTime
           , actionAgentName :: !Text
           }

必须产生JSON,例如:
{
  "type": "Booking",
  "description": "Whatever",
  "performedAt": "2012-01-04",
  "agent": "Tom"
}

对于smallcheck来说,这看起来像是一项理想的任务,我将其表述为:
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,这导致测试运行尚未完成。 smallcheck具有changeDepthchangeDepth1函数,因此我可以将它们用作changeDepth (const 3)以确保我的测试始终在合理的时间内运行。但是,这样做会让我不禁感到自己在某处错过了重点吗?例如,现在不可能仅通过更改命令行选项来运行测试来运行更长的测试,也许在一夜之间。另一方面,如果我使用changeDepth (- 2),仍然感觉好像我在假设测试的运行方式!也许最好假设全局测试深度为5,可以在n秒内运行,并且取决于每个属性是否根据需要调整深度?

希望听到有关smallcheck的这一更实际方面的反馈。

最佳答案

尽管小支票的“穷尽性”(无论如何对于小情况而言)是一个吸引人的属性,但我还是建议在这种情况下进行快速支票。虽然JSON具有轻量级的结构,但从实际数据位的角度来看,它非常繁重。

测试时间也非常关键地取决于您如何在类型的Series实例中为smallcheck定义“大小”(深度)。如果您的类型有很多分支(许多构造函数),则测试数量将迅速增加。它是“深度”的指数,而指数的底数是与特定测试用例相关的Series实例中的分支数量。

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

但是,覆盖范围也会受到影响-如果您减少测试用例中的分支(使深度增加得更快),则在给定深度下覆盖范围会减少。使用quickcheck,您会损失一些“小的”测试用例,而倾向于对一些较大的示例进行采样,而这些示例是您使用smallcheck无法实现的。

关于haskell - 在smallcheck中应该控制多少个 `Depth`参数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20092191/

10-12 16:36