Haskell:使用带有大小限制的quickCheckAll(例如quickCheckWith (stdArgs {maxSize = n}))

问题描述 投票:0回答:2

我希望能够使用 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

来定义测试用例,但这似乎很不可行。

    

haskell quickcheck
2个回答
2
投票

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
来处理大数。
    


0
投票

我没有找到将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

就是我一直在寻找的。

© www.soinside.com 2019 - 2024. All rights reserved.