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;
describe
, it
, and hspec
. Requirements are always about something and describe
is how you say what they are about. describe
takes 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 it
takes the english description and the verifying code. So describe
and it
are 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
it
is 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
pureHspec
and hHspec
. pureHspec
takes a list of Specs and returns a nicely formatted list of strings documenting each spec and it's status. hHspec
takes a handle and IO [Specs]
and writes to the handle (usually stdout
but 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 quantify
are 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