代码之家  ›  专栏  ›  技术社区  ›  Haleemur Ali

是否可以在quickcheck中生成任意函数

  •  1
  • Haleemur Ali  · 技术社区  · 6 年前

    我试着写一个快速的身份检查测试

    f $ y = f y
    

    我最初的计划是编写一个任意的生成器,它返回具有签名的函数&integer 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))
    

    所以,我修正了错误,通过应用任意函数并返回 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)
    

    我的问题是:

    1. 是否由于没有 Show ?
    2. 我能为 Show (Int -> Int) 使 # 1 可能吗?
    3. 可以在给定类型签名的情况下快速检查生成任意函数,在这种情况下,我将测试所有函数(给定类型)的真实身份。上面,我手动指定了3个测试函数,我希望以某种方式实现自动化,理想情况下是这样 f <- arbitrary :: Gen (Int -> Int)
    2 回复  |  直到 6 年前
        1
  •  3
  •   Li-yao Xia    6 年前

    QuickCheck支持使用 Fun 类型。 CoArbitrary 启用函数的生成。然后,它被转换成一个(可能是无限的)trie样结构,可以被检查并缩小到一个有限值(因为测试失败只依赖于有限的多个输入),然后可以作为反例来显示。

    具体地说,您可以将属性编写为 乐趣 参数,它是一个包装器 (->) 使用我描述的机制。用解构它 Fn 获取函数的模式。

    prop_dollarDoesNothing :: Property
    prop_dollarDoesNothing = property $ \(Fn (f :: Int -> Int)) x ->
      (f $ x) === f x
    

    了解更多信息

        2
  •  1
  •   leftaroundabout    6 年前

    Arbitrary 可以很好地生成函数(前提是参数是 CoArbitrary ),只是表演部分不起作用。没有真正好的方法来显示函数。

    这是一个常见的问题,因此quickcheck提供了 Blind 修饰语。基本上是假的 Show 任何类型的实例,实际上不显示有关该值的任何信息。当然,这在一定程度上降低了失败测试用例的调试有用性,但对此却无能为力。