Hanalei, Hawaii Tuesday, February 09, 2010

Make BDD Your BFF

symmetry

I just can’t say enough about BDD (Behavio[u]r Driven Design) and how it’s helping me with an application I’m writing (which you’ll know all about soon enough). I’ve stopped myself from soooo many stupid errors it’s unbelievable – and since I’ve been writing so many opinion posts lately, I thought I’d do an end to end BDD post for the masses.

symmetry

I just can’t say enough about BDD (Behavio[u]r Driven Design) and how it’s helping me with an application I’m writing (which you’ll know all about soon enough). I’ve stopped myself from soooo many stupid errors it’s unbelievable – and since I’ve been writing so many opinion posts lately, I thought I’d do an end to end BDD post for the masses.

Step 1: Get the Bits You’ll Need

Download Aaron Jensen’s Machine.Specifications (MSpec) from here (click on Download) and put it on a drive on your machine. If you’re Git-savvy, then just clone the repo (git://github.com/machine/machine.specifications.git). This is (in my opinion) by far the best test-running framework out there.

Step 2: Download and install Test-driven .NET (TD.NET)

You don’t need to do this if you have ReSharper – but if you want to debug the tests (err – specs) that you write, you’ll need a way to invoke it. TD.NET is your best friend – got get it – it’s free for personal use.

Step 3: Make TD.NET and MSpec friends

When you download MSpec, Aaron and friends are good enough to create a BAT file that hooks TD.NET and MSpec up. You only need to run this once and what you’re doing is telling TD.NET “When I tell you to run a test for MSPec – do this”. ‘

If you open up the MSpec download folder there is another folder in there called “Distribution”, in there is one called “Specifications” and you’ll see the .bat file that you can double-click. For some reason I couldn’t get this to work right and TD.NET wouldn’t work with the MSPec stuff. If you’re in this boat with me – then create a .reg file and add this text, then execute it by double-clicking:

Windows Registry Editor Version 5.00 
[HKEY_CURRENT_USER\Software\MutantDesign\TestDriven.NET\TestRunners\MSpec] 
"Application"="" 
"AssemblyPath"="[DOWNLOAD PATH]\\machine.specifications\\Build\\Debug\\Machine.Specifications.TDNetRunner.dll" 
"TargetFrameworkAssemblyName"="Machine.Specifications" 
"TypeName"="Machine.Specifications.TDNetRunner.SpecificationRunner" 
@="5" 

 

Name the file whatever you want with a “.reg” extension – double click and you’re off.

Step 4: Hook MSpec up to Visual Studio

I don’t like running all the tests using TD.NET – it’s too slow. Instead I use the test runner Aaron and team have created as it’s screaming fast. To do this I like to use External Tools (Tools | External Tools) and I add the setting as you see below:

extools 

Note that the command box points to the ConsoleRunner in the Build\Debug folder. If you want an HTML report to be output to your project – you can do it (and I recommend it) by adding this as your arguments:

$(TargetName)$(TargetExt) --html "$(ProjectDir)\Report.html"

This will tell MSpec to output a file called “Report.html” that you can share with others. More on this below…

Step 5: Create a Class Lib Project and Add References

Easy enough – File | New Class Library, then add the following references:

  1. Machine.Specifications
  2. Machine.Specifications.NUnit
  3. nunit.framework

If you don’t have nunit – well go get it!

This might seem like a lot of steps – the truth is most of them are one-time setup steps that will be easier next time.

All set? Let’s write some SPECS!

Writing Specs (Tests) With MSpec

The first thing to remember when using MSpec is that you’re testing the behavior of whatever it is you’re working with – not necessarily the functionality. The goal of writing these weird looking things is to have them readable by your client - “Executable Specifications” if you will.

So, when you sit down to crank these things out, change your mind a bit and realize you are (literally) writing “specs” for others to read – not tests that you want to pass (that’s a developer thing). Unfortunately this means that you’ll also be writing some funky looking code – but it’s all worth it.

Example – Object Overrides

You’re building a blog for your client, and you’ve discussed URLs. They want their posts to be identifiable by a “pretty URL” and it should be based on a title. You think the typical Wordpress URL might work so you propose this:

  1. A post will have a “slug” which will be based on the title, minus any URL-prohibited characters
  2. The post URL will use the slug and the year, month, and day of the post to uniquely identify the post.

You now have some requirements and you can write your Post class. Being a good geek you decide to override the core .NET object methods so you can test your Post a bit easer:

public override bool Equals(object obj) {
    if (obj.GetType() == typeof(Post)) {
        Post compare = (Post)obj;
        return compare.Slug.Equals(this.Slug, StringComparison.InvariantCultureIgnoreCase);
    } else {
        return base.Equals(obj);
    }

}

public override string ToString() {
    return Title;
}

public override int GetHashCode() {
    return ID.GetHashCode();
}

 

All good –this should work nicely – or will it? We should probably have written the specs first (in BDD they’re “specs”, not tests) – but we haven’t even written one yet. Let’s come back to this.

Bending C# To Your BDD Will

C# wasn’t meant for this kind of gymnastics – but it’s what we got. If you ever use RSpec with Ruby you’ll know why this stuff was written this way (Ruby/RSpec are amazingly clean and simple to read) – but for now just know that I have some tricks for you – just hang tight.

The idea is that you want to use a thing called a “Context” which you will test the behavior of. In our case, we want to test our Post – but that Post will have certain settings on it so we know what we’re testing. This is our Context and in MSpec you write the Context as an abstract class which must be inherited:

    public abstract class with_null_post {
        protected static Post post;
        Establish context = () => {
            post = null;
        };

    }

Yes – freaky. Very freaky. But I can explain this…

First – this is a class – an abstract class which means you can’t instantiate it directly. It’s sort of like an Interface, but not.

Second – the name. It’s written that way to help the MSPec reporting bits output something groovy and awesome. It goes against every fiber of most people’s C# super powers – but just stick with it. It’s not such a big deal after a while and there’s also a reason it starts with “with_”. I’ll get to that.

Next – WTF is “= () =>”. I’ll tell you –but I’ll also tell you not to worry about it. It’s an Anonymous Delegate – basically a “method on the fly”. The syntax here is “Set the Establish delegate equal to this code I’m about to write”. Establish is used by MSpec when you run your tests – just accept it, it won’t hurt you.

Finally – we have our Post and it’s static. This is a concession Aaron and team had to make for the final result – and it’s damn worth it, as you’ll see.

In summary form what we have here is something that makes sense when spoken aloud:

“Establish with_null_post as a post=null”

Writing Your First Spec

You can’t write a Spec without a Context – and we have one of them now. At this point you’re saying “Big F***in Deal” and hopefully I’ll convince you that it actually is. When writing specifications they have to be founded on a “context” if you will – and if that doesn’t make sense, consider this statement:

“When a Post is created it should default the publication date to today and the status to draft”.

This is behavior – and it’s something we should spec out, and we can use our null Post to do it since that will be our Context (creating a Post from nothing).

Actually, if you slice and dice that sentence a bit you’ll see we have two bits of behavior – setting the publish date and the status – so we can use MSPec to define this (again, with crunchy syntax):

[Subject("New Post")]
public class when_creating: with_null_post {

    Because of = () => {
        post = new Post();
    };

    It should_default_published_date_to_now;
    It should_default_status_to_draft;
}

 

Yes – whacky syntax again – but I promise you will get used to it. It’s worth it, especially when you see the result…

First is the Subject attribute – this is purely for reporting and you can send in a type or a string – whatever makes your reports more readable.

Second – you’ll notice this is a class that inherits from the Context – this is intended to be readable (as it is here). If it doesn’t make sense – neither does your spec.

Because is another delegate and “of” is just magic – but it’s meant to be readable. What this code is saying is “because of this action on the Context” and in it’s curly bits you need to put the action that will be tested. In this case – it’s creating a new Post.

The following lines are just crazy. Again – they are delegates (“It” is another special test delegate) but they’re formed the way they are to be readable – as you’ll see in a second.

This is a spec – and it’s executable and when I run it using the MSpec runner I setup above, this is what i see:

Specs in MyProject.Specs:

New Post, when creating
¯ should default published date to now (NOT IMPLEMENTED)
¯ should default status to draft (NOT IMPLEMENTED)

And that’s the payoff. What this type of testing allows us to do is to define behaviors for our classes without writing a lick of code – and not worrying about compiler issues. In this case our spec is reporting a very accurate answer – we haven’t done anything yet…

Being good BDD coders we can go nuts with this – setting up specs to code against, and the filling out the tests as we go.

And that, friends, is BDD.

Getting Your First Spec to Pass

This next part is where we actually test. Let’s say you write the code for your post – setting up the default values in the constructor etc. Now you want to test that functionality to make sure your spec is valid:

    [Subject("New Post")]
    public class when_creating : with_null_post {

        Because of = () => {
            post = new Post();
        };
        It should_default_published_date_to_now = () => {
            post.PublishedAt.ShouldBeGreaterThan(DateTime.Now.AddSeconds(-1));
            post.PublishedAt.ShouldBeLessThan(DateTime.Now.AddSeconds(1));

        };
        It should_default_status_to_draft = () => {
            post.Status.ShouldEqual(PostStatus.Draft);
        };
    }

Notice here that we’ve filled out the “It” stuff to include some tests. These “tests” use a set of Extension Methods that come with MSpec to, again, make things more humanly readable. I think my date tests there could use some love, but if you read them I think you get the idea.

Now, when I execute these tests I see a nice result:

Specs in MyProject.Specs:

New Post, when creating
¯ should default published date to now
¯ should default status to draft

Contexts: 1, Specifications: 2

 

I can actually print that out and take it to my client or manager and we can read it together (along with the 50 or so NOT IMPLEMENTED specs) – and we’ll be right on the same page.

What’s that? Don’t like the weird text layout? That’s OK – here’s a snippet of the HTML output that I mentioned above, with all the specs I’ve written for my blog engine I’m making for myself:specs

 

This is being output in my project directory – but I could easily put it in a network share or somewhere else – it reads very well!

Why You Should Care

Remember where we started with all of this with the object overrides? Well I decided to write it first because hey – it’s just object overrides and I’ve written them before and I’ll test them anyway. Let’s consider the specs we’ll write:

[Subject("New Post")]
public class object_overrides : with_null_post {
    protected static Post post2;
    Because of = () => {
        post=new Post();
    };

    It should_have_title_as_main_identifier;
    It should_be_equal_to_other_post_with_same_slug;
    It should_have_same_hash_code_as_ID;
}

As I’ve been mentioning – the main goal of BDD is to get you to think about Behavior of the application, not just functionality. You might think that that’s great for the results – why the hell do I need to see it in my code?

The answer is right in front of you – are these specs correct? Let’s revisit the requirements:

  1. A post will have a “slug” which will be based on the title, minus any URL-prohibited characters
  2. The post URL will use the slug and the year, month, and day of the post to uniquely identify the post.

If I was writing Unit Tests I don’t think I would have ever caught the problem – but maybe that’s just me. Writing “specs” that my client can understand – well that threw the problem right in my face: the equality test was all kinds of wrong (no year, month, day). How do I know? Because it’s the way I wrote it – AFTER I wrote the code. Oops. Had I written the failing specs first, my client could have reviewed the specs and “accepted” them – then I would have been quite sure of what it was I was doing!

Let’s try that again – this time I’ll tweak it so my client knows what’s going on:

[Subject("New Post")]
public class identifiers_and_equality : with_null_post {
    protected static Post post2;
    Because of = () => {
        post=new Post();
    };

    It should_have_title_as_main_identifier;
    It should_be_equal_to_other_post_with_same_slug_year_month_day;
    It should_use_id_as_system_identifier;
}

 

Here’s what’s changed:

  1. I renamed the Concern to make a bit more sense to the client (“identifiers and equality”).
  2. I changed the second spec to include year, month, and day in the equality test
  3. I changed the last spec to get rid of “hash code” and used something my client could understand

The Payoff

This is the goal of BDD – to get you to think a bit more like your client, and to write tests that fit a bit more into what they see. This will help you to design and build your application in a much more client-specific way and ultimately save you LOADS of time. I can attest to this in all kinds of ways – taking my time and writing specs first is much, much faster.

Tips and Tricks

By far the biggest hurdle to BDD is the syntax. It took me a while to get it and rather than type all that unfamiliar syntax out, I decided to create some code snippets instead. You can download them here. To use them, download to your hard drive somewhere and open up your Code Snippets Manager (VS 2008 – Tools | Code Snippets Manager) and click the “Add” button. Select the snippets folder and then click OK.

To use them, type “context” and TAB – TAB and you’ll have your context. “spec” will create a spec template, and “spec0” will create one that’s not implemented.

If you want to see a screencast on BDD and MSpec, you can watch this one here that I did a few months back.


DarkDeny - September 21, 2009 - Hello Rob.

Thanks for this great post. I have one question - why did you use NUnit, but not xUnit, which as you answered to my question ealier is much faster?
Mike - September 22, 2009 - Yeah, I'd like to know if this is usable with xUnit. I should Google that... brb
Mike - September 22, 2009 - Yeah it is. It apparently has adapters for different unit test frameworks. So my question then is: do you still write unit tests too? Or does BDD imply writing all tests as specs?

Thanks
DarkDeny - September 22, 2009 - AFAIR, there are samples packed with xUnit to write Specifications test. That's why I am asking why Rob is advertising MSpecs for this =)
Cohen - September 22, 2009 - Great post, did you also look at nbehave?
When I compared both (2 years ago I have to add) nbehave had some advantages IMHO:
- you can keep true to the c# coding guidelines since te text comes from attributes and strings...
- you can create parameterized specs (it's a FIT meets nunit kinda like thing, but on a small scale)

Wouldn't it actually be great if your client could create executable specs/reqs so you could use them for BDD and perhaps even user acceptance testing?

Did you also look at storyteller?
Eyston - September 22, 2009 - Because he likes MSpec?
Eyston - September 22, 2009 - Hey Rob,

If you ever write web acceptance tests take a look at cucumber. I'm testing an asp.net as if it were a black box (due to many reasons...) and I decided it was a good excuse to try out cucumber and other ruby tools. It's been helpful in understand how to apply BDD at different levels of testing.

For the web side you then have webrat with mechanize, celerity, and then selenium/watir. Webrat with mechanize is rather cool. Webrat has a simple API that is easy to use but also encourages writing more human meaningful tests (testing what the user sees). Mechanize acts like a real browser and lets you do assertions on the html output without having to drive a real browser -- its all headless and fast. But it doesn't do Javascript. Celerity (which I haven't used yet) does everything mechanize does but uses some java utils to actually run the javascript. So in theory you could do all of your web testing headless. Finally selenium/watir are the normal methods of driving a browser, but the syntax in Ruby is preferable to me.

I'm still toying with this stuff seeing what is useful, but it is a good excuse to learn Ruby at work.
Eyston - September 22, 2009 - Also... there are two railscasts on cucumber by Ryan Bates. I don't remember which one has it, but you can see him start at a Cucumber scenario with the Given, When, Then syntax and drive down to the RSpec level specification type tests. I found it rather cool. Maybe IronRuby is to the point this stuff can be done in .NET? That would be stellar.
junior programmer - September 22, 2009 - i was trying developwithpassion.bdd hosted on github but i haven't gotten my head around bdd just yet. it will take time. rob what were the reasons you chose mspec? there seems to be a few options (around 4 or 5) available for .net platform. now i need to read/try more about bdd to really shift my thinking from tdd.
Estuardo - September 22, 2009 - Excellent post... I like so much your blog and now I'm follower from you in twitter. Can you put your blog address in you Bio of twitter? Because is more easy find.

Thank you
Nick Berardi - September 22, 2009 - Wow thanks for the quick intro. I have had BDD on my list of things to look over, and now that I have looked through your post, this is definitely something I want to pay more attention to. Mostly because it has classes called "Because" and "It" :)
AlSki - September 22, 2009 - While this is great and good, I really have to agree with Cohen. I see the benefit of BDD coming from the specs being written in text and parsed against the code, NOT the code generating the specs.

There are some great efforts on BDD at the moment, and while the Java/Ruby tooling is well ahead of C#, the driving factor seems to be that Specs should be user generated.
Eyston - September 22, 2009 - Thats one cool thing about Cucumber. You have the features file which is purely text and then the step definitions that translate them to code. At first I thought this was going to be terrible because you'd have to duplicate every feature as a step definition, but in practice you just learn to write smart step definitions and features just require a few minor tweaks to fit.

I don't know if IronRuby is a pain in the ass to get working with this stuff, but I can see great value in having Ruby be a first class CLR citizen.
Aaron Jensen - September 22, 2009 - There should actually be little to no performance difference between the NUnit/XUnit in MSpec. The frameworks are *only* used for their assertion libraries, not the actual runner. This is something I intend to do away with eventually as it serves no purpose whatsoever in my opinion. You only need one assertion library. For now I assume people make the decision to use one or the other based on the output of the assertions when they fail, not sure. I can't even remember what the reason was that the XUnit wrapper was written, heh :)
Aaron Jensen - September 22, 2009 - Great post Rob. I really appreciate it when people go out of their way to document the things I really should have at some point :) Thank you.

There's one thing in here that I've sort of changed my position on--the whole with_xxx base class idea. I'm not really a fan of this any more for a few reasons. For one, I (purposely) don't include the base class in the report. I prefer to describe the entire context in the actual context class. In your particular example your "with_null_post", that's not really the context. The context is a description of important elements leading up to the observations. Setting an instance variable to null temporarily is not an important element.

Forcing you to describe your context in a single class name forces you to be and think more concisely and only put the important elements in.

Also, the "composition" of base classes is complicated from a naming perspective. If you have a with_situation_a and with_situation_b, you can't have a when_doing_this and use those two base classes. It doesn't work unless you namespace things and that's just silly. A better alternative is when_doing_this_in_situation_a and when_doing_this_in_situation_b.

My current modus operandi is to have a base class named for the subject (NewPostSpecs) and have that method contain non-important setup and well named utility methods so that the actual context (method/implementation/code) can read better, be more concise and intention revealing.

Hopefully this makes sense, I'm happy to expand further if need be. Thanks again Rob.
Rob Conery - September 22, 2009 - You're welcome! And yes, it certainly does. I struggled for a bit to come up with a reasonable "demo" that would fit here and it comes a bit short I spose. If you had the time and would care to update the examples above - I'd be happy to update/edit. As you know - I haven't been doing this stuff for long and am doing my best to "do it right" - any pointers you have would be lovely.
bonder - September 22, 2009 - Hey Rob, great post as always. I think you had problems with the BAT file because on Vista or Windows 7 you need to run it as an Administrator. Worked for me when I did that. Cheers!
Cohen - September 22, 2009 - for the .net space you have watin.

I know that the developer of watin is using it together with nbehave to execute acceptance tests.
I very much like the syntax for testing pages in his 2.0 version.
Chris Kolenko - September 22, 2009 - I remember watching your first BDD vid and i gave it a shoot. I basically gave up after 2 mins. Mainly because of the learning curve and the fact i was trying to introduce it into a 1/2 built application.

So why should i use this foreign looking syntax?

Is this just for the end client to see it working? because the people i do work for don't really care how the code works, they just want a product that works 100% and is done tomorrow basically.

Rob, when you first started writing these tests what made you think.. damn i should have been using this all along?

After reading your blog over the past year normally i get a light bulb popping into mind. This one is going to take a bit more convincing.
Argyle - September 22, 2009 - I wonder what Ayende will have to offer regarding this subject in his upcoming book Building DSL's With Boo. In the free unedited first chapter, he makes reference to RSpec, and it sounds like the book would be related to BDD. He says he likes Boo because it is CLI compliant, statically typed, and runs on the CLR (I guess that means no waiting for C# dynamic and DLR? I may wrong).

At my company we have non-technical account managers writing specs that I typically tear apart at both the technical and "what does the client really intend" levels (in a professional manner, of course ;)). If I ever get the opportunity to run my own show, BDD tools would be great asset.

Good post!
Rob Conery - September 22, 2009 - You can still use it with an application that's 1/2 built - it's really nothing more than formalizing specifications for *what the app should do*.

I like BDD because it focuses on the value you're building, not necessarily the mechanics. So when you're gearing up to write a test - you could start by saying "how should [thingX] behave when I use the parameterless constructor?" and lay it out.

Of course that's simplistic - but when you get into stuff like "What should happen to the Order when the PayPal payment is received" - well let's see...

Order - when paypal PDT comes in:
- should change the order status
- should add a transaction record to the order
- should email the user saying thank you
- should email the site owner saying that have $$
- should log the entire PDT value in the DB

Those are specs you can write without code - and I'm sure you'd have about 10 more. What about when the payment fails? What's the behavior then?

If you take the above and sit with a manager or client - it will grease the conversation very, very quickly.

Finally - the people you work for don't care how the code works - they want the product to work (as you say). Write specs for the Product then - not the code (change your thinking) - this is the point of BDD.

As for wanting it tomorrow - buy them a Time Machine :)
Jake Scott - September 22, 2009 - Hi Rob, thanks for the awesome post. I think that their will be alot of people waiting to look at the blog engine you are building to get a feel for how to write a suite of specs for an entire application. I guess that the more feedback you get from the likes of Aaron and team the better. It will be really useful for the rest of us who are sitting back and learning from your experiences. Excited about Hana :)
Liam McLennan - September 22, 2009 - I prefer spec unit (http://code.google.com/p/specunit-net/), mostly because the syntax is simpler.

Lots of people suggested cucumber and similar tools but I think they solve a different problem. Those tools only seem to work against systems that can maintain their state and are therefore more suited to functional testing. MSpec and the like leave state management to the developer making them better for fine grained BDD tests.
Chris Kolenko - September 22, 2009 - Thanks Rob, I used some company time to follow up on this blog entry. Did some reading about mspec looked at a few BDD examples with out the fancy syntax.

I agree with you 100%

What I tend to do is have a comment at the top of my class listing what i need to test.. ie.. Add product to PO will increase the total price etc etc.
And i base my unit tests around them (I may have picked that up from you when you blogged about xunit)

ok Rob.. you had me at hello.. i'll give it a shoot with this big project i'm working on in my own time. :D

now i need to find that time machine and i'll be sweet
Craig Stuntz - September 23, 2009 - I'm not sure C# "isn't meant for [writing BDD]." But I'm pretty sure C# is a poor tool for writing Ruby code.
Chris Kolenko - September 23, 2009 - Ok I tried it out last night.. i can see why it's your BFF now..

I recommend everyone should give it ago see what they think..
FutureTurnip - September 23, 2009 - Another great framework is FluentSpec (http://fluentspec.codeplex.com/)
Oz - September 24, 2009 - Thanks for another awesome post! I was completely oblivious to BDD. I "got it" after reading the post and watching the Kona video twice. I'm very impressed with the simplicity yet tremendous value it delivers across the development process. It would also chop off hours of rummaging through stacks of documentation if business and systems analyst were able to produce a specs list like this for every use-case too! Anyway, thanks again Rob!!!
Tim Hardy - September 24, 2009 - I'm heavily researching BDD and am having trouble figuring out where spec writing ends and unit testing begins. If anyone has any practical experience around this, I'd love to hear your thoughts. It seems to me that customer-focused specs will stop short of the unit tests required to fully cover a complex system. I'd like to know how the two meet and how this impacts the TDD "flow".

I'm basically asking Mike's question from above, "So my question then is: do you still write unit tests too? Or does BDD imply writing all tests as specs?"
Lance - September 25, 2009 - So when does it fail? I did a quick spike. Love how it reads and outputs but mine didn't fail when it should have. What gives

[Subject("Spike")]
public class when_does_it_fail
{
static bool _spike;

Establish context = () => { _spike = false; };

It should_still_be_false = () => _spike.Equals(true);
}

output
Spike, when does it fail
¯ should still be false
Daniel Watson - September 25, 2009 - It's just how you are making the assertion change equals to ShouldBeFalse()

[Subject("Spike")]
public class when_does_it_fail
{
static bool _spike;

Establish context = () => { _spike = false; };

It should_still_be_false = () => _spike.ShouldBeFalse();
}
Apostolis Bekiaris - September 26, 2009 - Thnks for the blog Rob. Anyone not convince yet read this blog with more resources on BDD http://apobekiaris.blogspot.com/2009/09/bdd-in-few-hours.html. Also users with x64 machines should change the reg path to HKEY_CURRENT_USER\Software\Wow6432Node\MutantDesign\TestDriven.NET\TestRunners\MSpec
Chris Kolenko - September 26, 2009 - Hey Lance,

Your test is very basic. Where is the because?

In a standard Arrange Act Assert your test would look like this

// Arrange
bool spike = false;

// Act

// Assert
Assert.IsFalse(spike);

:S
Dave Mac - September 27, 2009 - Found this comment really interesting.

Is the report generated by the mspec runner based on the 'when_doing_this_in_situation_a' idea?

The reports do not seem to include the context (base class name) as part of the description so, using Rob's example (temporarly ignoring Aarons comments about the context name:

[Subject("New Post")]
public class when_creating : with_null_post {...

Generates a report that reads:

New Post, when creating
¯ should default published date to now
¯ should default status to draft

To me the first line should onclude the context and read:

New Post, when creating with null post

Or have I missed something!?
Nick Swarr - September 27, 2009 - Just to give MSpec another bump, I really appreciate that it removes a lot of the traditional unit testing noise. I like not having to mark up the fixtures with test attributes (barring the class-level attributes that help in reporting). I enjoy no longer specifying access modifiers like marking class-level members as private simply because it's just less text cluttering the fixture. It creates very clean, concise, modifiable, and understandable tests.

As far as the base class, I saw a couple of posts on the web using the "with_blah" nomenclature. That never quite felt right for me. I share the same sentiment as Aaron but I ended up appending the word "scenario" to them instead. So, using the above examples, I'd have called it new_post_scenario. I don't think it offers any more clarity than what Aaron suggests but it helps me think about the domain a little more organically. I want to think less about pounding out specs and more about modeling behaviors. On that note, perhaps I should be calling the base class new_post_behaviors...

Anyways, excellent write up and I thank you for getting the word out! I enjoy writing my applications using BDD, Context/Specification and MSpec. It's a winning combination.
phenryll - September 27, 2009 - Thanks for the article and your 40-minute video.
You are writing your personal blog, aren't you?
I would love to read the code you have been writing with BDD, a real world project with BDD. It sounds like a book for professional developers :pp
Andrew Walker - September 29, 2009 - Great Video - I really appreciate it and as you said - it is a bit of an "A-ha" moment (Take on me... take me on..) I've been trying to get into the swing of TDD for a few months be hit mental blocks all the time!

One thing - I've been trying since last night to download MSpec - and each time - the download just dies! Tried FF & Chrome! Anyone got another link for it?
Andrew Walker - September 29, 2009 - Of course all I needed to do was post about trouble and the download finally worked all the way through! Got it now - cant wait to get rockin!
Eric Duncan - September 29, 2009 - @Dave Mac:

Yes, I believe that is exactly what Aaron was mentioning. To elaborate more, Rob's context should be:

when_creating_an_empty_post

So, more indepth reports would read like this, from Rob's more complex example of saving author title body above:

when_saving_a_new_post
- should_have_author_set_to_users_display_name
- should_have_seo_friendly_url_or_slug
- should_have_content_in_the_body
- should_have_no_comments

I have been tinkering with this concept for a few months myself, and feel writing the specs in just plain ol' my-cfo-should-know-what-this-means syntax goes a long way.
Eric Duncan - September 29, 2009 - One tweak to Rob's post, and one enhancement:

1) To get InstallTDNetRunner*.bat working, the batch files have to be copied to your Machine.Specifications bin location. If you downloaded the entire source, you will need to build the project first. The Build is located in \Build\Release from the mspec root directory.

Just copy those batch files into the \Build\Release\ directory and double-click to run it.

2) I am going to try MSpec in my next enterprise client, starting Monday! :) I've been tinkering with BDD for a bit now and feel ready to commit it on this next new, very large, project (I myself was introduced to BDD from Rob's initial video post, and tried for a while to 'get it').

In doing this, I am going to present the REPORTS html to my project and account managers. Rob's "Just post this on my door, and everyone knows where I am at" comment in the video a while back. ;)

I have a suggestion for all that want those automated REPORTS html files generated, without having to click an "MSpec" button or setup an external tool for it. You can create a POST BUILD event that generates the reports for you on every build of the TEST project(s). Yep, this runs all tests within the project. Right-click on your Project in the solution explorer, click Properties, and select Build Events tab. In the "Post-build event command line", enter this:

[YOUR-FULLPATH-TO-YOUR-MSPEC-DIR]\Machine.Specifications.ConsoleRunner.exe $(TargetPath) --html $(SolutionDir)$(TargetName).html

Now, just build your TEST project and you will have a new .html in your solutions root. I actually prefer to use a local "\lib\" directory in teh root of my solution. So, the path to my consolerunner is as follows:

$(SolutionDir)lib\mspec-github20090804\Machine.Specifications.ConsoleRunner.exe $(TargetPath) --html $(SolutionDir)$(TargetName).html

Note: I organize my \lib\ by projects and versions, hence the odd name of github's date of pull.

TIP: Seperate your Integration Tests into a seperate IntegrationTests project, so you can quickly run these automated reports from your main specs.
Eric Duncan - September 29, 2009 - Well, in that last comment, there should be "two" dashs before the HTML argument. The comment posting here filtered out the two dashs "-" and "-"html like Rob posted.

- - html
Mike Williams - October 3, 2009 - Great article! I am having a problem though and was wondering if someone could help me. I installed TD.NET (the RTM version), downloaded mspec from GitHub and rebuilt the solution in Visual Studio and installed the latest nunit.

I'm getting the following error when running mspec in my test project:

System.IO.FileLoadException: Could not load file or assembly 'nunit.framework, Version=2.4.6.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'nunit.framework, Version=2.4.6.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77'
at Machine.Specifications.NUnitShouldExtensionMethods.ShouldBeFalse(Boolean condition)
at TestLibrary.Class1.when_does_it_fail.b__1() in C:\Users\Mike\Documents\Visual Studio 2008\Projects\TestLibrary\TestLibrary\Class1.cs:line 18
at Machine.Specifications.Model.Specification.InvokeSpecificationField() in C:\mspec\Source\Machine.Specifications\Model\Specification.cs:line 75
at Machine.Specifications.Model.Specification.Verify() in C:\mspec\Source\Machine.Specifications\Model\Specification.cs:line 53

Any ideas?
Rob Conery - October 3, 2009 - Well yah - you need to reference NUnit!
Asif Raza Ashraf - October 5, 2009 - This is great. Thanks Rob.
Kyle Finley - October 13, 2009 - Rob & others,

I created a macro you might find handy. Build Solution + Run MSpec using the MSpec test runner.

http://kylefinley.net/archive/2009/10/05/1337.aspx

It's simple but helpful.
Gecko