unit-testing - 如何测试假设其输入来自智能构造函数的函数?
问题描述
tl;博士
我想了解如何使用Test.QuickCheck
来测试其参数被传递给智能构造函数和/或假设为来自智能构造函数的函数。
长版
在一个模块中,我有一个用户定义的类型,如下所示:
newtype SpecialStr = SpecialStr { getStr :: String }
顾名思义,SpecialStr
它很特别,因为被包裹String
的不是“任何”字符串,但它必须满足一些属性。为了强制执行这一点,我不从模块中导出值构造函数,而是导出一个智能构造函数:
specialStr :: String -> SpecialStr
specialStr str = assert (isValid str) $ SpecialStr str
where
isValid :: String -> Bool
isValid = and . map (`elem` "abcdef") -- this is just an example logic
当然,我已经定义了一些与这些 s 一起操作的函数SpecialStr
,例如
someFunc :: String -> [SpecialStr]
someFunc str = -- uses smart constructor
someOtherFunc :: (Int, SpecialStr) -> Whatever
someOtherFunc = -- assumes the input has been created via the smart constructor, i.e. assumes it's valid
其中可能会someFunc
被输入 a String
,然后输出[SpecialStr]
被压缩[1..]
并且结果被输入someOtherFunc
,只是为了做一个随机的例子。
现在我的问题是:如何使用 测试这些功能QuickCheck
?
解决方案
有一个聪明的构造函数?编写一个智能任意实例。
instance Arbitrary SpecialStr where
arbitrary = SpecialStr <$> listOf (choose ('a', 'f'))
shrink (SpecialStr s) = SpecialStr (shrinkList (enumFromTo 'a') s)
然后像往常一样写你的属性。
-- check that someOtherFunc is hypermonotonic in the SpecialStrings
quickCheck (\n1 n2 s1 s2 -> someOtherFunc (n1, min s1 s2) <= someOtherFunc (n2, max s1 s2))
...管他呢。
推荐阅读
- puppet - 在 puppet ensure_packages 包定义中使用命令输出
- snakemake - Snakemake:尝试为多个目录和文件运行规则时出错
- ruby-on-rails - 奇怪的 Rails ActiveRecord 行为
- html - 我的页面上有三列文本,但右列在底部,与其他三列分开
- angular - Angular Ionic - 仅当某个字段是某个值时才验证表单
- c# - 禁用使用 EWS 创建的约会提醒
- c++ - 用户定义类型的 is_floating_point 特化
- firebase - 反应原生导航到基于firebase动态链接的一些参数的页面(可能只是反应原生链接应该以相同的方式工作)
- javascript - 无法将 asp.net mvc 会话值传递给 javascript 变量
- sequelize.js - 续集独特的复合材料失败