是否可以在 QuickCheck 中生成任意函数
Is it possible to generate arbitrary functions in QuickCheck
我正在尝试为身份编写 QuickCheck 测试
f $ y = f y
我最初的计划是编写一个 return 函数和整数的任意生成器,签名为 Gen (Int -> Int, Int)
并且在 prop_DollerDoesNothing
测试中,使用/不使用 $
的函数应用程序给出相同的结果。
这是我的代码:
prop_DollarDoesNothing :: Property
prop_DollarDoesNothing =
forAll arbitraryFuncInt (\(f, y) -> (f $ y) == (f y))
arbitraryFuncInt :: Gen (Int -> Int, Int)
arbitraryFuncInt = do
f <- elements [(\x -> x*2), (\x -> x+3), (\x -> x-2)]
y <- arbitrary :: Gen Int
return (f, y)
它生成了以下有用的错误消息:
* No instance for (Show (Int -> Int))
arising from a use of `forAll'
(maybe you haven't applied a function to enough arguments?)
* In the expression:
forAll arbitraryFuncInt (\ (f, y) -> (f $ y) == (f y))
In an equation for `prop_DollarDoesNothing':
prop_DollarDoesNothing
= forAll arbitraryFuncInt (\ (f, y) -> (f $ y) == (f y))
因此,我修复了错误并通过应用任意函数和 returning 来自 arbitraryFuncInt
的一对整数来使测试正常工作
prop_DollarDoesNothing :: Property
prop_DollarDoesNothing =
forAll arbitraryFuncInt (\(x, y) -> x == y)
arbitraryFuncInt :: Gen (Int, Int)
arbitraryFuncInt = do
f <- elements [(\x -> x*2), (\x -> x+3), (\x -> x-2)]
y <- arbitrary :: Gen Int
return (f $ y, f y)
我的问题是:
- 是否根本不可能 return 由于没有
Show
的实例而未完全应用的任意函数?
- 我可以为
Show (Int -> Int)
编写实例以使 # 1
成为可能吗?
- QuickCheck 能否在给定类型签名的情况下生成任意函数,如果我正在测试对所有函数(给定类型)都是真实的身份。上面,我手动指定了 3 个测试函数,我想以某种方式自动化,理想情况下是这样
f <- arbitrary :: Gen (Int -> Int)
Arbitrary
可以很好地生成函数(前提是参数是 CoArbitrary
的实例),只是显示部分不起作用。没有真正显示功能的好方法。
这是一个常见问题,因此 QuickCheck 提供了 Blind
修饰符。它基本上为任何类型伪造了一个 Show
实例,实际上并没有显示有关该值的任何信息。当然,这在一定程度上降低了失败测试用例的调试有用性,但对此无能为力。
QuickCheck 支持生成、收缩和显示函数,使用 Fun
类型。 CoArbitrary
启用函数生成。然后将其转换为(可能是无限的)类似 trie 的结构,可以对其进行检查并将其缩小为有限值(因为测试失败仅取决于有限多个输入),然后可以将其显示为反例。
具体来说,您可以将属性编写为带有 Fun
参数的函数,它是使用我描述的机制的 (->)
的包装器。用Fn
模式解构它得到一个函数。
prop_dollarDoesNothing :: Property
prop_dollarDoesNothing = property $ \(Fn (f :: Int -> Int)) x ->
(f $ x) === f x
了解更多信息
QuickCheck 实现:https://hackage.haskell.org/package/QuickCheck-2.11.3/docs/Test-QuickCheck-Function.html
Koen Claessen 的论文 "Shrinking and showing functions",似乎是付费专区,但他的演讲是在线的:https://www.youtube.com/watch?v=CH8UQJiv9Q4
我正在尝试为身份编写 QuickCheck 测试
f $ y = f y
我最初的计划是编写一个 return 函数和整数的任意生成器,签名为 Gen (Int -> Int, Int)
并且在 prop_DollerDoesNothing
测试中,使用/不使用 $
的函数应用程序给出相同的结果。
这是我的代码:
prop_DollarDoesNothing :: Property
prop_DollarDoesNothing =
forAll arbitraryFuncInt (\(f, y) -> (f $ y) == (f y))
arbitraryFuncInt :: Gen (Int -> Int, Int)
arbitraryFuncInt = do
f <- elements [(\x -> x*2), (\x -> x+3), (\x -> x-2)]
y <- arbitrary :: Gen Int
return (f, y)
它生成了以下有用的错误消息:
* No instance for (Show (Int -> Int))
arising from a use of `forAll'
(maybe you haven't applied a function to enough arguments?)
* In the expression:
forAll arbitraryFuncInt (\ (f, y) -> (f $ y) == (f y))
In an equation for `prop_DollarDoesNothing':
prop_DollarDoesNothing
= forAll arbitraryFuncInt (\ (f, y) -> (f $ y) == (f y))
因此,我修复了错误并通过应用任意函数和 returning 来自 arbitraryFuncInt
prop_DollarDoesNothing :: Property
prop_DollarDoesNothing =
forAll arbitraryFuncInt (\(x, y) -> x == y)
arbitraryFuncInt :: Gen (Int, Int)
arbitraryFuncInt = do
f <- elements [(\x -> x*2), (\x -> x+3), (\x -> x-2)]
y <- arbitrary :: Gen Int
return (f $ y, f y)
我的问题是:
- 是否根本不可能 return 由于没有
Show
的实例而未完全应用的任意函数? - 我可以为
Show (Int -> Int)
编写实例以使# 1
成为可能吗? - QuickCheck 能否在给定类型签名的情况下生成任意函数,如果我正在测试对所有函数(给定类型)都是真实的身份。上面,我手动指定了 3 个测试函数,我想以某种方式自动化,理想情况下是这样
f <- arbitrary :: Gen (Int -> Int)
Arbitrary
可以很好地生成函数(前提是参数是 CoArbitrary
的实例),只是显示部分不起作用。没有真正显示功能的好方法。
这是一个常见问题,因此 QuickCheck 提供了 Blind
修饰符。它基本上为任何类型伪造了一个 Show
实例,实际上并没有显示有关该值的任何信息。当然,这在一定程度上降低了失败测试用例的调试有用性,但对此无能为力。
QuickCheck 支持生成、收缩和显示函数,使用 Fun
类型。 CoArbitrary
启用函数生成。然后将其转换为(可能是无限的)类似 trie 的结构,可以对其进行检查并将其缩小为有限值(因为测试失败仅取决于有限多个输入),然后可以将其显示为反例。
具体来说,您可以将属性编写为带有 Fun
参数的函数,它是使用我描述的机制的 (->)
的包装器。用Fn
模式解构它得到一个函数。
prop_dollarDoesNothing :: Property
prop_dollarDoesNothing = property $ \(Fn (f :: Int -> Int)) x ->
(f $ x) === f x
了解更多信息
QuickCheck 实现:https://hackage.haskell.org/package/QuickCheck-2.11.3/docs/Test-QuickCheck-Function.html
Koen Claessen 的论文 "Shrinking and showing functions",似乎是付费专区,但他的演讲是在线的:https://www.youtube.com/watch?v=CH8UQJiv9Q4