我希望能够使用 fastCheckAll 一起运行多个测试。同时,我需要指定测试的大小限制。
在下面的程序中,有两个测试在没有大小限制的情况下是不切实际的。获取一个非常大的整数的所有分区超出了该算法的计算能力,并且测试严格正整数的随机列表将需要丢弃太多列表。
{-# LANGUAGE TemplateHaskell #-}
module Partitions where
import Test.QuickCheck
import Test.QuickCheck.All
import Data.List (sort)
sizeCheck n = quickCheckWith (stdArgs {maxSize = n})
partitions :: Int -> [[Int]]
partitions 0 = [[]]
partitions n | n > 0
= [k:xs | k <- [1..n], xs <- partitions (n - k), all (k <=) xs]
-- "adding up all of the numbers in each partition should give 𝑛"
prop_partitions :: Int -> Property
prop_partitions n =
n >= 0 ==> all ((== n) . sum) (partitions n)
-- "sorting any list of strictly positive integers gives one of the
-- partitions of its sum"
prop_partitions' :: [Int] -> Property
prop_partitions' xs =
all (>0) xs ==> sort xs `elem` partitions (sum xs)
return []
runTests = $quickCheckAll
通常我会使用
quickCheckAll
使用编译指示 {-# LANGUAGE TemplateHaskell #-}
来运行所有测试,将所有类型为 Property
的测试命名为以 prop_
开头,以 return []
和 runTests = $quickCheckAll
结束程序,然后运行runTests
。
我正在使用的教科书提供了一种使用
quickCheckWith
指定大小约束的便捷方法: sizeCheck n = quickCheckWith (stdArgs {maxSize = n})
(计算简介:Haskell、逻辑和自动机;Sanella、Fourman、Peng 和 Wadler;第 272 页)。
我没有找到将
quickCheckAll
与 quickCheckWith
结合起来的方法。
我尝试使用
$allProperties
(来自 QuickCheck 模块)收集测试,然后用 map
(quickCheckWith
) 覆盖它们,但这不起作用。我想我可以使用 runTests n = map (quickCheckWith (stdArgs {maxSize=n}) . snd) $allProperties
来定义测试用例,但这似乎很不可行。
arbitrary
功能并通过
mapSize :: Testable prop => (Int -> Int) -> prop -> Property
设置尺寸,如下所示:
mapSize (max 10)
但这不是一个好的解决方案,因为通常大小应该是可调整的,这样您就可以在一夜之间运行计算密集型测试。因此,最好使用
prop_partitions :: Property
prop_partitions = mapSize (max 10) $ \n ->
n >= 0 ==> all ((== n) . sum) (partitions n)
或类似的东西(您可能不想在 10% 的情况下生成
mapSize (`div` 10)
,这样您可以使逻辑更奇特)。请注意,除非确实必须,否则不应该引入 0
,因为丢弃生成的案例只是浪费计算。在你的情况下,避免条件是微不足道的:
cond ==> prop
与
prop_partitions :: Property
prop_partitions = mapSize (`div` 10) $ \nPre ->
let n = abs nPre
in all ((== n) . sum) (partitions n)
类似,您可以使用
prop_partitions'
来处理负数和/或map abs
来处理大数。我没有找到将quickCheckAll 与quickCheckWith 结合起来的方法。
我在这里走上了正确的道路:
我尝试使用 $allProperties (来自 QuickCheck 模块)收集测试,然后使用 QuickCheckWith (runTests n = map (quickCheckWith (stdArgs {maxSize=n}) . snd) $allProperties) 映射它们,但这不起作用.
我找到了我正在寻找的内容,阅读模块的源代码
map (`rem` 10)
:
Test.QuickCheck.All
[一定喜欢 Haskell 库源代码都像这样随时可用
我需要的是<3]
-- | Test all properties in the current module, using a custom
-- 'quickCheck' function. The same caveats as with 'quickCheckAll'
-- apply.
--
-- @$'forAllProperties'@ has type @('Property' -> 'IO' 'Result') -> 'IO' 'Bool'@.
-- An example invocation is @$'forAllProperties' 'quickCheckResult'@,
-- which does the same thing as @$'quickCheckAll'@.
--
-- 'forAllProperties' has the same issue with scoping as 'quickCheckAll':
-- see the note there about @return []@.
forAllProperties :: Q Exp -- :: (Property -> IO Result) -> IO Bool
forAllProperties = [| runQuickCheckAll |] `appE` allProperties
和
allProperties
,而不是quickCheckWith
和forAllProperties
。使用 quickCheckWithResult
,无需像我尝试那样手动 forAllProperties
操作属性。输出结果需要函数map
。因此,
checkWithResult
就是我一直在寻找的。