如何使用Arbitrary或其他类型类为指定数据类型设置最大生成测试用例数
解决方案
有两种常用的可行方案,都不需要给TooHugeToTestAll额外编写类型类实例:
方案一:使用QuickCheck原生参数修饰函数(最便捷)
直接用QuickCheck提供的withMaxSuccess函数修饰目标属性即可单独设置该属性的最大测试用例数,不同属性可以设置不同值互不影响,示例修改如下:
QC2.testProperty "Law #1" -- 这里的2000就是该属性的最大生成测试用例数 (QC.withMaxSuccess 2000 $ \huge -> ( (not (H.isAnyZeroOrNegative huge)) QC.==> ((H.hugeProduct huge) == ((fromIntegral (H.ra huge)) * (fromIntegral (H.rb huge)) * (fromIntegral (H.rc huge)) * (fromIntegral (H.rd huge)))) ) )
如果需要调整其他QuickCheck运行参数,也可以用对应的修饰函数:
withMaxDiscardRatio:设置最大丢弃用例比例withMaxShrinks:设置失败用例最大收缩次数withDiscardLimit:设置最大丢弃用例数
方案二:使用Test.Framework局部配置覆盖
如果需要批量调整多个QuickCheck运行参数,可以用Test.Framework提供的plusTestOptions给单个测试项绑定局部配置,优先级高于全局配置,示例如下:
首先导入对应配置模块:
import Test.Framework (plusTestOptions) import Test.Framework.Options (testOption'_quickcheck_max_success)
然后给目标测试项包裹配置:
plusTestOptions (mempty { testOption'_quickcheck_max_success = Just 2000 }) $ QC2.testProperty "Law #1" (\huge -> ( (not (H.isAnyZeroOrNegative huge)) QC.==> ((H.hugeProduct huge) == ((fromIntegral (H.ra huge)) * (fromIntegral (H.rb huge)) * (fromIntegral (H.rc huge)) * (fromIntegral (H.rd huge)))) ) )
设计逻辑说明
Test.Framework是统一测试调度框架,本身不感知各测试框架的内部逻辑,仅提供统一的测试树结构、全局/局部配置覆盖能力、标准化结果输出。你之前在defaultMainWithOpts第二个参数传入的是全局配置,作用于所有测试项,plusTestOptions可以给单个子测试项设置更高优先级的局部配置。- QuickCheck的
Testable类型类是对「可被QuickCheck执行的测试」的抽象,不管你的测试是纯Bool值、带前置条件的属性、还是带自定义运行参数的测试,都会被统一包装成Testable实例供运行器调用,withMaxSuccess这类修饰函数本质就是给Testable实例附加运行参数,不需要修改被测类型的任何定义。
内容的提问来源于stack exchange,提问作者Jörg Brüggmann
相关产品推荐
相关产品推荐

