christian wuensche
christian wuensche

Reputation: 1043

How to use QuickCheck in Hspec tests?

I build the initial codebase for my Haskell project with cabal init I have several tests written with Hspec. On cabal test it compiles and runs these tests like expected and gives a message for failing/passing.

Now I included a quickCheck test and even when this test fails the output in terminal don't recognize the quickCheck test.

But in the dist/test/ dir i can see the test log *** Failed! ...

Is there a way to "include" quickCheck tests in the test workflow. So that i don't have to look on the test log after every test run.

import Test.Hspec
import Test.QuickCheck

spec :: Spec
spec = do
    describe "myTest" $ do
        it "Something something" $ do
            myTest "" `shouldBe` False
            quickCheckWith stdArgs { maxSuccess = 1000 } prop_myTest -- <== ?

Upvotes: 5

Views: 947

Answers (2)

Abhijit Sarkar
Abhijit Sarkar

Reputation: 24518

From Hspec docs:

You can use arbitrary QuickCheck properties with Hspec, but they must be of type Property. QuickCheck's property function can be used to turn anything that is a member of the Testable class into a Property. Here is an example:

describe "read" $ do
  it "is inverse to show" $ property $
    \x -> (read . show) x `shouldBe` (x :: Int)

it ".." $ property $ .. is a common pattern. The Test.Hspec.QuickCheck module provides the prop function as a shortcut. With prop, the last example can be written as:

describe "read" $ do
  prop "is inverse to show" $
    \x -> (read . show) x `shouldBe` (x :: Int)

However, the scant documentation doesn't tell you how to use a Generator. Say, for example, you want to generate a non-negative integer. You can do so using the NonNegative modifier as shown below.

describe "splitAt" $ do
  prop "splits empty list into two empty lists" $
    \(NonNegative (n :: Int)) ->
      splitAt n ([] :: [Integer]) `shouldBe` ([], [])

If you want two generators:

prop "splits any list -- any index" $
  \(NonNegative (n :: Int)) (xs :: [Integer]) -> do
    ...

Note that specifying types in the Lambda expression pattern matching will require enabling the ScopedTypeVariables extension.

Upvotes: 2

Cubic
Cubic

Reputation: 15663

You want the property function, see here.

Example:

spec :: Spec
spec = do
    describe "myTest" $ do
        it "Something something" $
            property prop_myTest

Upvotes: 9

Related Questions