hedgehog
Release with confidence.
http://github.com/hedgehogqa/haskell-hedgehog
| LTS Haskell 24.17: | 1.5@rev:2 | 
| Stackage Nightly 2025-10-31: | 1.7 | 
| Latest on Hackage: | 1.7 | 
hedgehog-1.7@sha256:ec9120e200e4a35933ffa082e9dd9aabd59c8a630f8f2ead3f655e71f9839c30,4696Module documentation for 1.7
- Hedgehog
- Hedgehog.Gen
- Hedgehog.Internal- Hedgehog.Internal.Barbie
- Hedgehog.Internal.Config
- Hedgehog.Internal.Discovery
- Hedgehog.Internal.Distributive
- Hedgehog.Internal.Exception
- Hedgehog.Internal.Gen
- Hedgehog.Internal.HTraversable
- Hedgehog.Internal.Opaque
- Hedgehog.Internal.Prelude
- Hedgehog.Internal.Property
- Hedgehog.Internal.Queue
- Hedgehog.Internal.Range
- Hedgehog.Internal.Region
- Hedgehog.Internal.Report
- Hedgehog.Internal.Runner
- Hedgehog.Internal.Seed
- Hedgehog.Internal.Show
- Hedgehog.Internal.Shrink
- Hedgehog.Internal.Source
- Hedgehog.Internal.State
- Hedgehog.Internal.TH
- Hedgehog.Internal.Tree
- Hedgehog.Internal.Tripping
 
- Hedgehog.Main
- Hedgehog.Range
 
Release with confidence.
Hedgehog automatically generates a comprehensive array of test cases, exercising your software in ways human testers would never imagine.
Generate hundreds of test cases automatically, exposing even the most insidious of corner cases. Failures are automatically simplified, giving developers coherent, intelligible error messages.
Features
- Integrated shrinking, shrinks obey invariants by construction.
- Abstract state machine testing.
- Generators allow monadic effects.
- Range combinators for full control over the scope of generated numbers and collections.
- Equality and roundtrip assertions show a diff instead of the two inequal values.
- Template Haskell test runner which executes properties concurrently.
Example
The main module, Hedgehog, includes almost everything you need to get started writing property tests with Hedgehog.
It is designed to be used alongside Hedgehog.Gen and Hedgehog.Range which should be imported qualified. You also need to enable Template Haskell so the Hedgehog test runner can find your properties.
{-# LANGUAGE TemplateHaskell #-}
import           Hedgehog
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
Once you have your imports set up, you can write a simple property:
prop_reverse :: Property
prop_reverse =
  property $ do
    xs <- forAll $ Gen.list (Range.linear 0 100) Gen.alpha
    reverse (reverse xs) === xs
And add the Template Haskell splice which will discover your properties:
tests :: IO Bool
tests =
  checkParallel $$(discover)
If you prefer to avoid macros, you can specify the group of properties to run manually instead:
{-# LANGUAGE OverloadedStrings #-}
tests :: IO Bool
tests =
  checkParallel $ Group "Test.Example" [
      ("prop_reverse", prop_reverse)
    ]
You can then load the module in GHCi, and run it:
λ tests
━━━ Test.Example ━━━
  ✓ prop_reverse passed 100 tests.
In Memory of Jacob Stanley
As we come to the end of our guide to haskell-hedgehog, we’d like to take a moment to remember and honor one of its key contributors, our dear friend, author and co-founder, Jacob Stanley.
Jacob’s passion for Haskell and his commitment to creating high-quality, reliable software was truly inspiring. His work has shaped haskell-hedgehog in countless ways, and without him, it wouldn’t be the project it is today.
Jacob passed away unexpectedly on April 9th. His absence is deeply felt, but his impact on this project, and on all of us who had the privilege to work with him, remains. We continue to maintain and develop haskell-hedgehog in his memory and in honor of his dedication to excellence in programming.
As you explore haskell-hedgehog, and possibly contribute to its ongoing development, we invite you to join us in remembering Jacob Stanley — a tremendous developer, collaborator, and friend.
Contributors
Changes
Version 1.7 (2025-09-22)
- Fix eta-reduction issues for GHC 9.0; add CI and cabal support for GHC 9.0.2 (#557, @tomjaguarpaw)
- Allow lifted-async 0.11 (#556, @felixonmars)
- Remove fromJustcall by using a separate existential wrapper (#554, @HuwCampbell)
Version 1.6 (2025-09-08)
- Fix GitHub CI URL ([#545][545], @tmcgilchrist)
- Bump upper bounds for containers and random (#544, @moodmosaic)
- Support GHC 9.12 (#540, @erikd)
- Add callstacks to generators that can error (#538, @ChickenProp)
- Drop support for GHC 8.0.2 (#538, @ChickenProp)
Version 1.5 (2024-07-25)
- Bump containers and filepath dependencies (#533, @erikd)
- Hedgehog.Internal.Report: Add configPrintShrinkPath(#531, @sol)
- Allow GHC 9.10 (#530, @erikd)
- hedgehog-{example,quickcheck,test-laws}: Raise QuickCheck bound (#529, @JackKelly-Bellroy)
- Allow to omit icons at the start of important output lines (#524, @sol)
- Allow to omit source location from report (#523, @sol)
- Fix “insufficient coverage” message (#521, @sol)
- Support empty property names (#520, @sol)
- Allow to disable the recheckAt-message (#519, @sol)
- Remove redundant Showconstraints:evalMaybe,evalMaybeM(#516, @endgame)
- Relax upper bound on ansi-terminal(#515, @moodmosaic)
- Report.hs refactoring (#514, @sol)
- Relax time dependency to < 1.15 (#513, @tomjaguarpaw)
- Bump barbies upper bound (#510, @jchia)
- Support primitive 0.9 (#509, @Vekhir)
- Show less context on failure (#505, @sol)
- Allow GHC 9.8 (#504, @tomjaguarpaw)
- Wrap evalMaybeMandevalEitherMinwithFrozenCallStack(#499, @ocharles)
Version 1.4 (2023-08-07)
- Fix skipping to tests/shrinks when tests have been discarded (#489, @ChickenProp)
Version 1.3 (2023-06-22)
- Better documentation for Var(#491, @endgame)
- Bump upper bounds for ansi-terminal(#486, @mpilgrem)
- Better documentation for Gen.filter[T],Gen.mapMaybe[T],Tree.prune(#485, @ChickenProp)
- Update Github CI actions, exclude Haddocks for old GHCs (#482, @ysangkok)
- Support GHC 9.6 (#481, @ysangkok)
- Bump upper bounds for resourcetandprimitive(#478, @shlevy)
- Export Hedgehog.Internal.Seed.seed(#477, @sol)
- Better documentation for sample(#468, @parsonsmatt)
- Replace exceptions dependency with safe-exceptions (#466, @ocharles)
- Generalise Hedgehog.Gen.element(#411, @ocharles)
Version 1.2 (2022-08-28)
- Allow skipping to a specific test number or shrink result (#454, @ChickenProp)
- Support GHC 9.4 (#461, @ysangkok)
- Allow newer dependencies (#457, @ysangkok)
- Add Gen.subset (#451, @chris-martin)
- Add example for Gen.subsequence (#450, @chris-martin)
- Don’t drop actions depending on shrunk predecessors (#453, @ChickenProp)
Version 1.1.2 (2022-09-02)
Version 1.1.1 (2022-01-29)
- Support using fixed seed via HEDGEHOG_SEED(#446, @simfleischman / @moodmosaic)
- Compatibility with text-2.0 (#443, @sjakobi)
- Better ‘cover’ example code in haddocks (#423, @jhrcek)
Version 1.1 (2022-01-27)
- Replace HTraversable with TraversableB (from barbies) (#412, @ocharles)
- Support GHC 9.2 (#436, @patrickt)
Version 1.0.5 (2021-03-12)
- GHC 9 Support (#392, @utdemir)
- Use binary shrinking for integral (#413, @HuwCampbell)
- Build tree from values instead of wrapping and unwrapping (#414, @HuwCampbell)
- Don’t shrink the action chosen in state machine testing (#415, @HuwCampbell)
- Support shrinking 1-bit numbers for CLaSH (#397, @jonfowler / @jacobstanley)
Version 1.0.4 (2020-12-11)
- Bump ansi-terminal to 0.11 (#394, @mpilgrem)
- Clean up hedgehog.cabal for GHC 8.0+ (#391, @felixonmars)
- Bump random to 1.2 (#396, @felixonmars)
- Improve the distribution of Range.scaleLinear(#405, @jonfowler / @moodmosaic)
- Change Gen.frequencygenerator immediately shrink (#406, @ocharles / @HuwCampbell)
- Add Property.evalMaybe,Property.evalMaybeMandProperty.evalEitherM(#381, @markus1189 / @moodmosaic)
- Bump QuickCheck to 2.14 (#409, @lehins)
- Bump bytestring to 0.11 (#408, @Bodigrim)
- Minor Haddock formatting improvments (#398, @sshine / @moodmosaic)
Version 1.0.3 (2020-06-26)
- Bump cabal-version to 1.10 (#390, @moodmosaic)
- Don’t swallow errors if we can’t find the source file (#387, @HuwCampbell)
- Add Property.evalNF(#384, @dcastro)
- Add Gen.eitherandGen.either_(#382, @dcastro)
- Add filterT,justT, andmapMaybeTtoGenexports (#366, @kquick)
- Bump pretty-show to 1.10 which supports quasi-quotes (#365, @jacobstanley)
- Remove undefinedinGenT’sMonadWriterinstance (#344, @HuwCampbell)
- Make Tree.interleavelogarithmtic rather than linear (#313, @edsko)
Version 1.0.2 (2020-01-10)
- Support GHC 8.10 (#376, @sjakobi)
- Speed up Tree.splits(#349, @treeowl)
- Speed up Gen.shuffle(#348, @treeowl)
- Add docs on the bounds of Size(#346, @chris-martin)
- Fix performance issues with color handling (#345, @stolyaroleh)
- Add mapMaybe,mapMaybeT, inTreeandGen(#339, @treeowl)
- Fix some formatting bugs in Haddock (#332, @sshine)
- Add MonadGeninstances forStateT(#321, #330, @HuwCampbell / @tomjaguarpaw / @symbiont-sam-halliday)
- Add MonadBaseControlinstance forPropertyT(#328, @treeowl)
Version 1.0.1 (2019-09-16)
- Add compatibility with GHC 8.8 (#319, @erikd)
- Include location of failed assertion in report. This enables editors to more easily parse the location of failed test assertions, and provide links/jump functionality (#308, @owickstrom)
- Stop using filter to define unicode (#303, @ajmcmiddlin)
- Export LabelName from main module (#299, @erikd)
Version 1.0 (2019-05-13)
- Add histograms to labels / coverage (#289, @jacobstanley)
- Improved shrinking of lists (#276, @jacobstanley / @edsko)
- Simplify MonadGen, this breaks the use ofStateTon the outside of aGenTfor the time being, it still works fine on the inside though and you can usedistributeTto run it (#276, @jacobstanley)
- Change ApplicativeGenTto use zipping (#272, @jacobstanley / @edsko)
- Rename Tree->TreeT,Node->NodeT(#272, @jacobstanley)
- difffunction which takes any- a -> a -> Boolcomparison function (#196, @chessai / @jacobstanley)
- Labelling of test runs via label,collect(#262, @ruhatch / @jacobstanley)
- Classification of test runs via cover,classify(#253, @felixmulder / @jacobstanley)
- Define proper Applicativeinstances forNodeT,TreeTandGenT(#173@sjakobi)
- MonadFailinstance for- PropertyT(#267, @geigerzaehler)
- MonadResourceinstance for- PropertyT(#268, @geigerzaehler)
- Example for the trippingfunction (#258, @HuwCampbell)
- Improve documentation for state machine testing (#252, @endgame)
- runTestsfunction for running tests from a top level executable, this was later renamed to- defaultMainas is the de facto convention (#168, @erikd)
- Show output variables when parallel state machine testing fails to linearise (#235, @HuwCampbell)
- Note about enumBoundeddanger (#202, @thumphries)
- Expose discoverPrefixto find prefixed properties (#229, @ruhatch)
- Remove use of unixpackage and replace withlookupEnv(#226, @puffnfresh)
Version 0.6.1 (2018-09-22)
- Fix UTF-8 related rendering bugs on Windows (#218, @moodmosaic)
- Verify that our SplitMix/Seed avoids pathological γ-values (#207, @moodmosaic)
- Avoid weak gamma values in Hedgehog.Internal.Seed (#198, @moodmosaic)
Version 0.6 (2018-05-14)
- Pass Dieharder statistical/randomness tests (#185, @moodmosaic)
- Catch readFileexceptions on the repl (#184, @thumphries)
Version 0.5.3 (2018-03-12)
- Add SemigroupandMonoidinstances forGenTthat lift the innerMonoid(#156, @andrewthad)
- Gen.unicodeno longer generates non-characters (#154, @johnchandlerburnham)
- Documentation improvements (#162, @fisx)
- Documentation fixes (#157, @dredozubov)
Version 0.5.2 (2018-02-05)
- Add doc explaining use of withTests 1(#134, @chris-martin)
- Explicitly define Semigroupinstance forSummary(#142, @gwils)
- Depend on semigroups(#140, @LightAndLight)
- Support transformers-0.4(#150, @gwils)
Version 0.5.1 (2017-12-06)
- Only invoke setNumCapabilitieswhen using the-threadedruntime (#130, @ekmett)
- Correct mixGammaoddness check (#124, @markhibberd)
Version 0.5 (2017-07-16)
- Parallel state machine testing, allows detection of commands which are not-atomic (#98, @jacobstanley)
- Easier to use variables for state machine testing (#94, @jacobstanley)
- MonadGenclass allows the use of transformers like- ReaderTand- StateTon the outside of generators (#99, @jacobstanley)
- Better error messages for tests which throw exceptions (#95, @jacobstanley)
- Separated test input generation and assertions in to PropertyTandTestTrespectively, this allowsTestTto have aMonadBaseControlinstance (#96, @jacobstanley)
- This document grew links to the pull requests which introduced various changes (#93, @moodmosaic)
Version 0.4.1 (2017-06-28)
- Fixed runtime type error that could occur when shrinking state machine commands (#91, @jacobstanley)
Version 0.4 (2017-06-28)
- Abstract state machine testing, check out Tim Humphries’ great blog post or the process registry example to see how it works (#89, @jacobstanley)
- liftCatch,- liftCatchIO,- withCatchfunctions for isolating exceptions during tests (#89, @jacobstanley)
Version 0.3 (2017-06-11)
- Exponential range combinators (#43, @chris-martin)
- Roundtrip example, check out the blog post (#85, @thumphries)
- trippingnow displays intermediate value (#85, @jacobstanley)
- distributefunction for pulling a transformer out to the top level (#83, @jacobstanley)
- withExceptTfunction for executing tests with an inner- ExceptT(e.g.- Test (ExceptT x m) a) (#83, @jacobstanley)
Version 0.2.2 (2017-05-16)
- Fixed scope of unicodecharacter generators (#76, @moodmosaic)
- Widen version bounds for some dependencies (#80, @amarpotghan)
- Expose test modules to fix build on nix / hydra (#78, @amarpotghan)
- Fixes for GHC 8.2 RC2 (#77, @erikd)
Version 0.2.1 (2017-05-09)
- Added ascii,latin1,unicodecharacter generators (#73, @jacobstanley)
Version 0.2 (2017-05-06)
- Added a quiet test runner which can be activated by setting HEDGEHOG_VERBOSITY=0(@jacobstanley)
- Concurrent test runner does not display tests until they are executing (@jacobstanley)
- Test runner now outputs a summary of how many successful / failed tests were run (@jacobstanley)
- checkSequentialand- checkParallelnow allow for tests to be run without Template Haskell (@jacobstanley)
- Auto-discovery of properties is now available via discoverinstead of being baked in (@jacobstanley)
- annotateallows source code to be annotated inline with extra information (@jacobstanley)
- forAllWithcan be used to generate values without a- Showinstance (@jacobstanley)
- Removed uses of Typeableto allow for generating types which cannot implement it (@jacobstanley)
