Hspec: A Testing Framework for Haskell

Contents

Interoperability with HUnit

Using HUnit assertions

Hspec's expectation language is built on top of HUnit, hence it is possible to use HUnit assertions instead. E.g. shouldBe is just another name for HUnit's @?=. You can use whatever you prefer and it will work seamlessly.

Example code:
-- file Spec.hs
import Test.Hspec
import Test.HUnit

main :: IO ()
main = hspec $ do
  describe "reverse" $ do
    it "reverses a list" $ do
      reverse [1, 2, 3] @?= [3, 2, 1 :: Int]
runhaskell Spec.hs

reverse
  reverses a list []

Finished in 0.0005 seconds
1 example, 0 failures

Running a HUnit test suite with Hspec

fromHUnitTest from the hspec-contrib package can be used to convert a HUnit test suite to a Spec. This can be used to run existing HUnit tests with Hspec. Ordinary spec items and HUnit tests can be freely intermixed.

Example code:
-- file Spec.hs
import Test.Hspec
import Test.Hspec.Contrib.HUnit (fromHUnitTest)
import Test.HUnit

main :: IO ()
main = hspec $ do
  describe "some ordinary spec items" $ do
    it "returns the first element of a list" $ do
      head [23 ..] `shouldBe` (23 :: Int)

  describe "some legacy HUnit tests" $ do
    fromHUnitTest testSuite


-- | A HUnit test suite
testSuite :: Test
testSuite = TestList [
    TestLabel "test_read_is_inverse_to_show" test_read_is_inverse_to_show
  , TestLabel "test_23_is_equal_to_42" test_23_is_equal_to_42
  ]

test_read_is_inverse_to_show :: Test
test_read_is_inverse_to_show = TestCase $ do
  (read . show) (23 :: Int) @?= (23 :: Int)

-- a failing test case
test_23_is_equal_to_42 :: Test
test_23_is_equal_to_42 = TestCase $ do
  23 @?= (42 :: Int)
runhaskell Spec.hs

some ordinary spec items
  returns the first element of a list []
some legacy HUnit tests
  test_read_is_inverse_to_show []
  test_23_is_equal_to_42 []

Failures:

  Spec.hs:29:6:
  1) some legacy HUnit tests test_23_is_equal_to_42
       expected: 42
        but got: 23

  To rerun use: --match "/some legacy HUnit tests/test_23_is_equal_to_42/"

Randomized with seed 921447365

Finished in 0.0005 seconds
3 examples, 1 failure