Cabal is the build system for Haskell, it also doubles as a package manager. Create a .cabal file:
-- samples-quickcheck.cabal
Name: samples-quickcheck
Version: 0.0.0
Cabal-Version: >= 1.10
Build-Type: Simple
Library
Default-Language: Haskell2010
HS-Source-Dirs: tests
GHC-Options: -Wall
Build-Depends: base
, hspec
, QuickCheck
Test-Suite spec
Type: exitcode-stdio-1.0
Default-Language: Haskell2010
Hs-Source-Dirs: tests
Ghc-Options: -Wall
Main-Is: Spec.hs
Build-Depends: base
, hspec
, QuickCheck
Enable automatic Hspec discovery, so that each module ending with Spec can be automatically considered as a test module:
-- tests/Spec.hs
{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
Add a simple (icebreaker) test, because there’s always a bit of work involved in getting everything up and running:
-- tests/GettingStartedSpec.hs
module GettingStartedSpec (spec) where
import Test.Hspec
import Test.Hspec.QuickCheck
spec :: Spec
spec = do
describe "icebreaker" $ do
prop "icebreaker" $ \x y ->
add x y == add y x
add :: Int -> Int -> Int
add x y = x + y
Create a Cabal sandbox, install dependencies, build the package, and enable the tests, by running the following commands in a terminal:
cabal update # Download the most recent list of packages
cabal install cabal-install # Optional, can be prompted by cabal update
cabal sandbox init # Initialise the sandbox
cabal install --only-dependencies # Install dependencies into the sandbox
cabal build # Build your package inside the sandbox
cabal configure --enable-tests # Enable the test suites
Run the tests via Cabal’s built-in test runner:
cabal test
Building samples-quickcheck-0.0.0...
Preprocessing library samples-quickcheck-0.0.0...
In-place registering samples-quickcheck-0.0.0...
Preprocessing test suite 'spec' for samples-quickcheck-0.0.0...
[1 of 2] Compiling GettingStartedSpec (tests\GettingStartedSpec.hs, dist\buil...
[2 of 2] Compiling Main (tests\Spec.hs, dist\build\spec\spec-tmp\Main.o)...
Linking dist\build\spec\spec.exe ...
Running 1 test suites...
Test suite spec: RUNNING...
Test suite spec: PASS
Test suite logged to: dist\test\samples-quickcheck-0.0.0-spec.log
1 of 1 test suites (1 of 1 test cases) passed.
See the test failing, as a form of Double Entry Bookkeeping:
-- Change:
add x y == add y x
-- To:
add x y == add 0 1
cabal test
Building samples-quickcheck-0.0.0...
Preprocessing library samples-quickcheck-0.0.0...
In-place registering samples-quickcheck-0.0.0...
Preprocessing test suite 'spec' for samples-quickcheck-0.0.0...
[1 of 2] Compiling GettingStartedSpec (tests\GettingStartedSpec.hs,...
[2 of 2] Compiling Main (tests\Spec.hs, dist\build\spec\spec-tmp\Main.o)...
Linking dist\build\spec\spec.exe ...
Running 1 test suites...
Test suite spec: RUNNING...
GettingStarted
icebreaker
icebreaker FAILED [1]
Failures:
1) GettingStarted.icebreaker icebreaker
Falsifiable (after 1 test and 1 shrink):
0
0
Randomized with seed 1531351472
Finished in 0.0000 seconds
1 example, 1 failure
Test suite spec: FAIL
Test suite logged to: dist\test\samples-quickcheck-0.0.0-spec.log
0 of 1 test suites (0 of 1 test cases) passed.
To use QuickCheck interactively, start a REPL by doing:
cabal repl spec
In the above command, spec
is just the name of the test-suite, as declared in the .cabal file.
For convenience, all the above are also available on GitHub.