【问题标题】:Quickcheck on custom datatype快速检查自定义数据类型
【发布时间】:2016-03-01 23:47:15
【问题描述】:

我成功地对此进行了快速检查:

testaroo = quickCheck $ checkWin

checkWin :: [(Int, ThePlayers)] -> Bool
checkWin [(1,_),(2,_),(3,_)] = True
checkWin [(4,_),(5,_),(6,_)] = True
checkWin [(7,_),(8,_),(9,_)] = True
checkWin [(1,_),(5,_),(9,_)] = True
checkWin [(3,_),(5,_),(7,_)] = True
checkWin [(1,_),(4,_),(7,_)] = True
checkWin [(2,_),(5,_),(8,_)] = True
checkWin [(3,_),(6,_),(9,_)] = True
checkWin _ = False

但是当我尝试运行时

testaroo = quickCheck $ removeFromList

removeFromList :: (Int, ThePlayers) -> [(Int, ThePlayers)] -> [(Int, ThePlayers)]
removeFromList tuple list = delete tuple list

我遇到了以下情况:

No instance for (Arbitrary ThePlayers)
      arising from a use of `quickCheck'
    Possible fix:
      add an instance declaration for (Arbitrary ThePlayers)
    In the expression: quickCheck
    In the expression: quickCheck $ removeFromList
    In an equation for `testaroo':
        testaroo = quickCheck $ removeFromList
Failed, modules loaded: none.

我在 checkWin 上成功运行我的 quickCheck 我做了什么我添加了

instance Arbitrary BoardState
    where
    arbitrary  = arbitrary

但老实说,我不太确定这是做什么的 :)。无论如何我可以在我的removeFromList 函数上运行测试吗?

【问题讨论】:

  • 您似乎没有在checkWin 中使用ThePlayers。为什么不只检查 Int 值的胜利?您可以使用map fst[(Int, ThePlayers)] 转换为[Int]

标签: haskell quickcheck


【解决方案1】:

QuickCheck 必须生成随机案例以针对您的财产进行测试,通过

No instance for (Arbitrary ThePlayers)

它基本上说它不知道如何为测试生成一个随机的ThePlayers 值,你应该实现一个实例Arbitrary ThePlayers


quickCheck 的类型也是

quickCheck :: Testable prop => prop -> IO () 

即使模块可以为您生成随机参数,函数removeFromList 看起来也不像Testable(属性),checkWin 也不像:函数的属性是关于:应该做什么是正确的结果吗?结果应该满足什么?论据和结果之间有什么关系? QuickCheck 模块不会也不能从您的函数中生成属性,您必须自己指定。

(顺便说一句,您在checkWin 上的第一次测试被编译只是因为它有一个返回类型Bool 偶然,它并不表示您的程序的任何属性并且几乎每次都会失败)

例如,Data.List 中的 reverse 函数的一个属性是:reverse 函数不应更改列表的长度,因此基于此事实的检查应为:

prop_length :: [Int] -> Bool
prop_length as = length as == length (reverse as)

然后你可以基于它构建一个测试:

test_propLength = quickCheck prop_length

您可以尝试some tutorials 了解更多信息。

【讨论】:

    【解决方案2】:

    Arbitrary 是一个类型类,只有一个函数arbitrary 你必须实现。正如文档所说:

    arbitrary :: Gen a
    

    给定类型值的生成器。

    Gen 是一个允许您构造“random”值的 monad。 QuickCheck 将使用它来生成随机实例,以便生成随机列表[(Int, ThePlayers)] 来测试属性。

    由于您没有显示data ThePlayers 的定义,我们只能猜测如何生成任意值。

    一个例子可能是:

    data Foo = Positive Int | Coordinate Int Int | Character Char
    
    instance Arbitrary Foo where
        arbitrary = oneof [arbitraryPositive,arbitraryCoordinate,arbitraryCharacter]
            where arbitraryPositive = do
                      p <- arbitrary
                      return $ Positive $ abs p
                  arbitraryCoordinate = do
                      x <- arbitrary
                      y <- arbitrary
                      return $ Coordinate x y
                  arbitraryCharachter = do
                      c <- arbitrary
                      return $ Character c
    

    【讨论】:

      猜你喜欢
      • 2016-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-30
      • 2013-09-14
      • 2015-08-20
      • 2018-12-15
      • 1970-01-01
      相关资源
      最近更新 更多