← ClaudeAtlas

haskell-testinglisted

Set up and write Haskell tests with `hspec`, `QuickCheck`, and `hspec-discover`. Covers the test-suite cabal stanza, auto-discovery, per-module spec layout, property tests, `Arbitrary` instance placement, in-memory effect interpreters, and colored/specdoc output (locally and in CI). Use when adding tests, configuring the test runner, deciding between unit and property tests, or making test output more readable.
ivelten/claude-haskell-skills · ★ 0 · Testing & QA · score 60
Install: claude install-skill ivelten/claude-haskell-skills
# Haskell Testing Default test stack: `hspec` for structure + `QuickCheck` for property tests, with `hspec-discover` for auto-discovery. For doctest setup (executable examples in Haddock comments), see `haskell-documentation`. ## Test-suite cabal stanza ```cabal test-suite myapp-test import: shared type: exitcode-stdio-1.0 hs-source-dirs: test main-is: Spec.hs build-depends: , base , myapp , hspec ^>=2.11 , QuickCheck ^>=2.14 build-tool-depends: hspec-discover:hspec-discover ``` The `test/Spec.hs` file is a one-liner that turns on hspec-discover: ```haskell {-# OPTIONS_GHC -F -pgmF hspec-discover #-} ``` That's it — hspec-discover walks `test/` looking for `*Spec.hs` modules whose path mirrors the source module structure, and assembles them into one test executable. ## Test file conventions Tests are auto-discovered when they match `<Module>Spec.hs` and export `spec :: Spec`: ```haskell module User.RegistrationSpec (spec) where import Test.Hspec import Test.QuickCheck import User.Registration spec :: Spec spec = describe "registerUser" $ do it "rejects empty emails" $ parseEmail "" `shouldBe` Left EmptyEmail prop "round-trips through encode/decode" $ \(email :: Email) -> parseEmail (renderEmail email) === Right email ``` Conventions: - **One spec module per source module**, mirroring the directory structure. `src/User/Registration.hs` ↔ `test/User/RegistrationSpec.hs`. - **Property