I've long been interested in Behavior Driven Design and it's something that is strangely missing from the Haskell community. QuickCheck is an amazing tool that I use whenever I can, but BDD has it's uses too, even in Haskell.
hspec aims to be simple and there's only three functions that most people will need to use;
hspec. Requirements are always about something and
describeis how you say what they are about.
describetakes the name of something and a list of requirements for it. The requirements themselves have a plain english description of desired behavior and some Haskell code that verifies the behavior is implemented correctly. The function
ittakes the english description and the verifying code. So
itare the two functions that package up something's requirements and verifiers into a list of Specs.
specs :: IO [Spec] specs = describe "quantify" [ it "makes single quantities singular" (quantify 1 "thing" == "1 thing"), it "makes larger quantities plural" (quantify 2 "thing" == "2 things"), it "makes zero quantities plural" (quantify 0 "thing" == "0 things"), it "treats negative quantities just like positive quantities" (quantify (-1) "thing" = "-1 thing"), it "handles words that end with an 'x' (eg box -> boxes)" (pending "no need for this yet") ]
hspec aims to be extendable so
itis part of a type class, making it easy to add your own verifiers such as hUnit. The currently supported verifiers are an expression that reduces to a Bool, or you can use "pending", or you can use a QuickCheck property. The last requirement's verifier is "pending", representing the fact that this requirement isn't expected to be implemented yet so it doesn't have verifier code. That's all you need right there. Since the Specs are just a Haskell data structure you can evaluate them yourself to see what is successful and what is failing, no need for a test runner.
hspec aims to be useful and if you'd like an easy to read report then there's two extra functions
pureHspectakes a list of Specs and returns a nicely formatted list of strings documenting each spec and it's status.
hHspectakes a handle and
IO [Specs]and writes to the handle (usually
stdoutbut it could be a file handle)
>> hHspec stdout specs quantify - makes single quantities singular - makes larger quantities plural - makes zero quantities plural x treats negative quantities just like positive quantities - handles words that end with an 'x' (eg box -> boxes) # no need for this yet Finished in 0.00021 seconds 5 examples, 1 failure
We see from the '
-' that most requirements for
quantifyare met, the one with an '
x' is failing, and the one with a '
#' and extra details is pending since there's no need for it yet. We also get a summary of how long it took and how many specs failed.
I've got some more ideas for it but I think it's simple enough, extendable enough, and useful enough to release to the Haskell community now.
hspec can be found on github at https://github.com/trystan/hspec