Friday, February 11, 2011

Announcing hspec

Announcing hspec - BDD for Haskell

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

 - 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

No comments:

Post a Comment