我遇到与此问题类似的问题Controlling how test data is generated in QuickCheck。下面我将阐述我的具体细节,我正在使用的代码,以及我所遇到的具体问题。
我写过一个使用Fibonacci序列作为输入的fizz-buzz程序。 我想测试两件事。 (1)给定符合特定条件的Int,我的程序是否发出正确的字符串。 (2)我的Fibonacci发生器是否产生Fibonacci数?
我遇到的问题与上面的链接类似。 Int
s的范围太大。我如何限制我的测试说,前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个Fibonacci。因此fibb 6
将返回Right 8
。 Left
值与此问题无关。
我注意到答案表明应该写一个newtype
,包装[Int]
并创建一个新的Arbitrary
实例。但是,我也注意到答案是从2012年开始的,QuickCheck 2
有一个Args
datatype
似乎可以做我需要的事情。那么,我可以创建一个新的Args
来限制测试范围,(只需要前1000个斐波那契数字),还可以限制运行的测试数量?如果不是上述链接的解决方案,我将采取的方法?
答案 0 :(得分: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