hedgehog
Release with confidence.
http://github.com/hedgehogqa/haskell-hedgehog
| LTS Haskell 24.16: | 1.5@rev:2 |
| Stackage Nightly 2025-10-24: | 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 anya -> 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 forPropertyT(#267, @geigerzaehler)MonadResourceinstance forPropertyT(#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 todefaultMainas 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 likeReaderTandStateTon 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 innerExceptT(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)
checkSequentialandcheckParallelnow 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 aShowinstance (@jacobstanley)- Removed uses of
Typeableto allow for generating types which cannot implement it (@jacobstanley)