Being given so much unwanted opportunity of looking at bad, hurriedly written code recently, I can’t stop evangelising about unit tests. But don’t worry, today I’m going to write about something you problably haven’t seen yet. Behavior Driven Development.
So, what’s wrong with TDD? Why do we bring another approach (assuming it’s not complementary - this is partially true). The problem with TDD (and writing unit tests in general) is that:
- to maintain them properly they need to be perfectly clear about what they do -> each test should represent a functional scenario case and all tested scenario cases together should cover full functional domain
- the more detailed they get (and more complex actual functionality is) the less readable they become
- even if you have 100% unit test code coverage, your code should be accepted tested at the end (by your client’s people) - to sleep in a calm way you should be convinced that your unit tests cover business scenarios (as those are tested by end-users)
What do I usually do to achieve that? It’s quite simple, but it requires a bit of self-discipline. I split every test into "Assign", "Act", "Assert" parts and I start writing test logic in comments. So, initially my test case consists only of comments and what I do next is to fill the gaps between comments with the actual code. If you check such a test later, you’d see that those comments usually start with "When…", "If…", "Given…", "Then…" - that’s because what I do (on a conceptual level) is truly preparing a workflow / scenario of what’s going to be tested. I map my “natural language” conditions into code. Doesn’t it look like translating an acceptance test into unit test? That’s basically what Behavioral Driven Development is about - you specify what the code has to do (_almost_ in business requirements way) and then you can make code do it :)
More basic information about BDD can be found here: http://en.wikipedia.org/wiki/Behavior_Driven_Development
BDD is not only about conceptual approach - there are actual tools that can help you with that. Imagine executing BDD tests and reading the outputs using the “natural language-style” descriptions. You’d be able to know (without digging into code) what business functionality is working and what’s not! Do those tools really work? Personally I haven’t given them a go yet and I’ve seen just one try of someone else (they failed, but for some other reasons, not related to BDD), but I’m quite encouraged to try it out.
Just to make things a little bit more complex - BDD tools come in 2 flavors - "xBehave" and "xSpec". The best description of differences between those can be found here: http://stackoverflow.com/questions/307895/what-is-the-most-mature-bdd-framework-for-net
Personally, I find “xSpec” approach totally not convincing, but on the other hand - “xBehave” is very tempting: it aids you with correct structuring of your tests and making them absolutely readable. It also promotes reusing of spec steps (atomic steps in your unit tests) which helps a lot if you need to test plenty of variations of one scenario. To see how it really works, you should watch this video (it’s half an hour, but truly worth of your time): http://www.youtube.com/watch?v=SVwBz-ZTliw&feature=related
Just to conclude - I’ve decided to try SpecFlow (http://specflow.org) and you can expect some brief review in forthcoming weeks.