2016-05-02 6 views
2

Ich habe ein Problem ähnlich dieser Frage Controlling how test data is generated in QuickCheck. Im Folgenden werde ich meine Besonderheiten, den Code, den ich verwende, und die spezielle Frage, die ich habe, artikulieren.Steuern, wie Testdaten in QuickCheck 2 generiert werden

Ich habe ein Fizz-Buzz-Programm geschrieben, das eine Fibonacci-Sequenz als Eingabe verwendet. Ich möchte zwei Dinge testen. (1) Liefert mein Programm die richtige Zeichenkette, wenn ein Int eine bestimmte Bedingung erfüllt. (2) Generiert mein Fibonacci-Generator Fibonacci-Zahlen?

Das Problem, das ich habe, ist ähnlich dem obigen Link. Der Bereich Int ist zu groß. Wie beschränke ich meine Tests, um die ersten 1000 Fibonacci-Zahlen zu sagen?

Hier ist Code, der meiner Meinung nach sowohl angemessen als auch minimal ist. Bitte lassen Sie mich wissen, wenn ich es ausarbeiten muss.

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 nimmt eine Int und findet, dass n-te Fibonacci. So würde fibb 6Right 8 zurückgeben. Der Wert Left ist für dieses Problem nicht relevant.

Was ich bemerkte, war die Antwort schlug vor, dass man eine newtype schreiben sollte, eine [Int] einwickeln und eine neue Arbitrary Instanz machen sollte. Allerdings habe ich auch festgestellt, dass die Antwort von 2012 ist, und QuickCheck 2 hat eine Argsdatatype, die scheint zu tun, was ich brauche. Also, kann ich eine neue Args erstellen, um den Bereich der Tests zu begrenzen, (nur wollen die ersten 1000 Fibonacci-Nummern), und auch die Anzahl der Tests zu begrenzen? Wenn nicht, ist die Lösung von der obigen Verbindung der Ansatz, den ich nehmen müsste?

the entire project here

+1

Könnten Sie wickeln 'Int' in einem' newtype' und bieten eine 'Bounded' Instanz mit Ihrem eigenen Grenzen? Dann könnten Sie wahrscheinlich QuickChecks ['arbitraryBoundedIntegral :: (Bounded a, Integral a) => Gen a]] (http://haddock.stackage.org/lts-5.15/QuickCheck-2.8.1/Test-QuickCheck-Arbitrary) verwenden .html # g: 2). –

+0

Ich werde es versuchen. –

Antwort

1

während herauszufinden, über die Bounded typeclass nützlich für ein anderes Projekt war, habe ich mit Meinungen von Haskell Cafe Mailingliste Int in einem newtype vereinbart ist plump und so entschieden haben, zu lösen das Problem auf folgende Weise.

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 

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