Joe*_*inz 6 haskell quickcheck
我是Haskell的新手.到目前为止,这是非常好的,但我正在尝试复制粘贴我的QuickCheck属性,我想解决这个问题.
这是一个简单的例子:
prop_Myfunc :: [Int] -> (Int,Int) -> Bool
prop_Myfunc ints (i,j) = ints !! i == ints !! j
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为QuickCheck生成负数,所以我得到
*** Failed! (after 2 tests and 2 shrinks):
Exception:
Prelude.(!!): negative index
Run Code Online (Sandbox Code Playgroud)
我试图谷歌寻求解决方案,我发现例如NonNegative和==>,但我不明白它们是如何工作的.
我怎样才能限制上面的例子,以便i和j永远不会消极?而且,既不是太高了?那是:0 <= i,j < length ints
Eri*_*ikR 10
首先,请参阅此SO答案,了解如何编写自定义Gen ...函数以及如何使用forAll组合子的示例.
以下是如何为列表中的非空列表和两个有效的非负索引编写生成器:
import Test.QuickCheck
genArgs :: Gen ( [Int], Int, Int )
genArgs = do
x <- arbitrary
xs <- arbitrary
let n = length xs
i <- choose (0,n)
j <- choose (0,n)
return ( (x:xs), i, j) -- return a non-empty list
test = quickCheck $ forAll genArgs $ \(xs,i,j) -> prop_myfunc xs (i,j)
Run Code Online (Sandbox Code Playgroud)
约束包装器(Test.QuickCheck.Modifiers如果它们不是隐式重新导出的话)可以这样使用:
prop_Myfunc :: [Int] -> (NonNegative Int, NonNegative Int) -> Bool
prop_Myfunc ints (NonNegative i, NonNegative j) = ints !! i == ints !! j
Run Code Online (Sandbox Code Playgroud)
您可以SomeWrapper a像a修改分发一样对待.例如,NonNegative a确保a >= 0.生成包装器后,可以使用模式匹配或显式访问器(getNonNegative在本例中)获取值.
至于约束索引的上边距,我认为使用包装器是不可能的(在Haskkell类型系统中不可能使用值来参数化类型,在这种情况下是列表长度).但是,使用==>运算符,您可以为测试添加任意布尔约束:
prop_Myfunc ints (NonNegative i, NonNegative j) = i < l && j < l ==> ints !! i == ints !! j where
l = length ints
Run Code Online (Sandbox Code Playgroud)
它以其他方式工作:当条件不成立时,它只是丢弃当前的测试用例.但要小心:如果抛出的案例太多(条件限制太多),那么测试就变得不那么有用了.使用shrink测试数据通常可以实现"无损"行为,但这是另一个主题.
| 归档时间: |
|
| 查看次数: |
1521 次 |
| 最近记录: |