och*_*les 5 haskell smallcheck
我正在做第一部分真正的工作smallcheck,我对如何使用Depth参数感到有些困惑.在我进入之前,让我说明我正在使用smallcheck的内容.
在工作中,我们正在我们自己的内部数据库前构建一个简单的Web服务.Web服务执行一些查询,并将查询结果序列化为JSON进行响应.我目前正在研究的是保证:给定一个表示查询结果的对象,该对象产生预期的JSON.例如:
data Action
= Action { actionType :: !ActionType
, actionDescription :: !Text
, actionPerformedAt :: !UTCTime
, actionAgentName :: !Text
}
Run Code Online (Sandbox Code Playgroud)
必须生成JSON,例如:
{
"type": "Booking",
"description": "Whatever",
"performedAt": "2012-01-04",
"agent": "Tom"
}
Run Code Online (Sandbox Code Playgroud)
这看起来像是一个理想的任务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
Run Code Online (Sandbox Code Playgroud)
框架中的默认smallcheck深度tasty为5,这导致我尚未完成的测试运行.smallcheck具有changeDepth和changeDepth1功能,所以我可以使用它们changeDepth (const 3)来确保我的测试总是在合理的时间内运行.然而,通过这样做,我不禁感到我在某处错过了这一点?例如,现在无法通过更改命令行选项来运行测试来运行更长的测试(可能是一夜之间).另一方面,如果我使用changeDepth (- 2),它仍然感觉好像我正在考虑如何运行测试!也许最好假设在n秒内运行5的全局测试深度,并且由每个属性调整深度以适应它?
很想在这个更实际的方面听到一些反馈smallcheck.
当您使用QuickCheck的随机测试进行测试时,您所拥有的唯一指标就是测试次数,因此您可以尽可能多地进行测试.
SmallCheck的不同之处在于您可以实际推断出正在测试的内容.理想情况下,您不应将深度视为与您对测试结果的信心相关的指标,但您应该对所需的深度有一个很好的了解.
如果我们谈论的是JSON,那么处理JSON的大多数函数一次只能使用一层,有时两层结构.因此,如果存在错误,可以在深度为2或3的结构上发现它.(您需要找到或计算smallcheck的深度,根据您的Serial实例,它将为您提供所需的结构深度.)
所以,要回答你的问题,如果深度3是你能承受的最大值,那么首先你应该决定这对你正在测试的那种代码是否足够.
如果它恰好是不够的,那么你可以交换广度以获得深度(例如通过减小叶子值的深度),或者确实切换到QuickCheck的随机枚举策略.
我认为只有当您认为您正在测试的功能可能由于结构的大小而存在错误时才应使用QuickCheck,而不是结构组件的某些本地组合.我能想到的一些例子是:
虽然smallcheck(无论如何对于小案例)的“详尽性”是一个有趣的特性,但我宁愿建议在这种情况下使用quickcheck。虽然 JSON 具有轻量级结构,但从实际数据位的角度来看,它相当重。
测试时间也非常关键地取决于您如何在您的类型的系列实例中定义smallcheck的“大小”(深度)。如果您的类型有很多分支(很多构造函数),测试的数量将会快速增长。它的“深度”是指数的,而指数的底数是与特定测试用例相关的系列实例中的分支数量。
换句话说,如果平均有 2 个构造函数,则需要运行 32 个测试用例,但如果有 20 个,则更像是 3200000 个。
但是,您的覆盖范围也会受到影响 - 如果您减少测试用例中的分支(使深度增加得更快),则在给定深度下您将获得更少的覆盖范围。使用quickcheck,您可以放弃一些“小”测试用例,转而采样一些使用smallcheck 无法达到的较大示例。