【问题标题】:Controlling how test data is generated in QuickCheck 2控制如何在 QuickCheck 2 中生成测试数据
【发布时间】:2016-05-04 23:57:46
【问题描述】:

我有一个类似于这个问题Controlling how test data is generated in QuickCheck 的问题。下面我将阐述我的具体情况、我正在使用的代码以及我遇到的特定问题。

我编写了一个使用斐波那契数列作为输入的 fizz-buzz 程序。 我想测试两件事。 (1) 我的程序是否在给定满足特定条件的 Int 的情况下发出正确的字符串。 (2) 我的斐波那契生成器是否生成斐波那契数?

我遇到的问题类似于上面的链接。 Ints 的范围太大。如何限制我的测试说前 1000 个斐波那契数?

这是我认为既足够又最少的代码。如果我需要详细说明,请告诉我。

import           Data.Numbers.Primes (isPrime)
import           Test.Hspec  (Spec,hspec,describe,it,shouldBe)
import           Test.Hspec.QuickCheck (prop)

qcheck :: Spec
qcheck = do
  describe "QuickCheck test fiz" $
    prop "QuickCheck test" $ modfiz

  describe "QuickCheck test fib" $
    prop "QuickCheck test fib" $ testfib

modfiz int
  | int <= 0                                 = True  -- code smell, should never generate number less than or equal to zero.
  | int == 3                                 = test3
  | int == 5                                 = test5
  | int `mod` 15 == 0                        = testMod35
  | int `mod` 3 == 0                         = testMod3
  | int `mod` 5 == 0                         = testMod5
  | isPrime int == True                      = testPrime
  | otherwise                                = testRest
      where
        test3     =
          Right "Buzz BuzzFizz"     == fizzbuzz 3
        test5     =
          Right "Fizz BuzzFizz"     == fizzbuzz 5
        testMod3  =
          Right "Buzz "             == fizzbuzz int
        testMod5  =
          Right "Fizz "             == fizzbuzz int
        testMod35 =
          Right "Buzz Fizz "        == fizzbuzz int
        testPrime =
          Right "BuzzFizz"          == fizzbuzz int
        testRest  =
          Right (show int)          == fizzbuzz int

testfib :: Integer -> Bool
testfib n =
  case (fibb n) of
    Left _ -> False
    Right n' -> isFib n'

fibb 接受 Int 并找到第 n 个斐波那契。所以fibb 6 会返回Right 8Left 值与此问题无关。

我注意到答案建议应该写一个newtype,包装一个[Int] 并创建一个新的Arbitrary 实例。但是,我也注意到答案来自 2012 年,QuickCheck 2 有一个 Args datatype 似乎能够满足我的需要。那么,我可以创建一个新的Args 来限制测试的范围(只需要前 1000 个斐波那契数),并且还可以限制运行的测试数量吗?如果不是,上述链接中的解决方案是我必须采取的方法吗?

the entire project here

【问题讨论】:

标签: haskell quickcheck hspec


【解决方案1】:

虽然发现 Bounded 类型类对另一个项目很有用,但我同意 Haskell Cafe 1 邮件列表中的意见 newtype 中的 Int 是严厉的,所以有决定通过以下方式解决问题。

qcheck :: Spec
qcheck = do
  describe "QuickCheck testing fizbuzz"     $
    modifyMaxSuccess (const 1000)           $
    prop  "Lowerbound: 0 Upperbound: 10000" $
    forAll (choose (1, 10000)) modfiz

  describe "QuickCheck test fibonacci generator" $
    modifyMaxSuccess (const 1000)                $
    prop "Lowerbound: 0 Upperbound: 10000"       $
    forAll (choose (1, 10000)) testfib

1 https://groups.google.com/forum/#!topic/haskell-cafe/y81Q5fXil34

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多