tags:

views:

244

answers:

3

I am just getting into the concept of BDD and have listened to Scott Bellware's talk with the Herding Code guys. I have been playing around with SpecFlow some and like it pretty well.

I understand the distinction between ATDD and TDD as described in the blog post Classifying BDD Tools (Unit-Test-Driven vs. Acceptance Test Driven) and a bit of BDD history, but that leads me to a question.

As described, isn't using a BDD tool (such as MSpec) just another unit testing framework? It seems to me that it is.

Furthermore, this seems to suggest that using SpecFlow to spec out the lower level components (such as your repositories and services) would be wrong. If I can use the same tool for both ATDD and TDD of lower level components, why shouldn't I? There seems to still be some blurry lines here that I feel like I'm not quite understanding.

+5  A: 

A true behavior driven tool would be something like Cucumber. We use it at my job against .NET code. This allows us to write features that define behavior of the system as a whole and we can then execute the features and verify that the system does what we expect. The whole process works very well for us.

http://cukes.info/

There is a .net implementation called NStep that connects to cucumber via the wire protocol, it allows you to write step definitions in C# using lambdas...its pretty awesome.

Step definitions look like this:

When("^I go to the \"([^\"]*)\" (?:[Ss]creen|[Pp]age)$", (string pageName) =>
{
    var screen = ParseScreen(pageName);
    GoToScreen(screen);
    World.Browser.Wait(1000);
});

http://github.com/clearwavebuild/nStep

Climber104
SpecFlow is a .NET implementation of Cucumber.
Brian McCord
Except it is a clone, with its own parser and it compiles the steps into unit tests. No matter how good, a clone will never be as good as the original. Cucumber is constantly adding features that makes the BDD approach a great way to write software. You should check out actual cucumber...it's pretty powerful.
Climber104
BDD tools are really designed to test behavior. So it should encompass the system as a whole. For the underlying core business processes like repositories I would use NUnit and use SpecFlow or Cucumber for Behavior Testing.
Climber104
This is why I love SO, learn something new every day. SpecFlow and cucumber look pretty cool.
Nathan W
+1 for nstep and not reinventing the wheel. NStep implements the cucumber wire protocol so that you can implement steps in .NET while using the ruby cucumber runner.SpecFlow is fine and dandy, but you miss out on all of the tooling out there for cucumber. You also lack the ability to mix simple and dynamic ruby code (great for working with APIs like Selenium) and .NET code (great for working with databases and service facades).
Joseph Daigle
A: 

I think your understanding is in line with mine. BDD is more suited for integration testing and generally tests your system as the end user, eg:

Given I am an authorised user
When I go to the front page
Then there should be a link to my profile with my username as the link text.

There is no reason to not to unit test your repositories at a more granular level. I think both are useful and appropriate.

Igor Zevaka
I still test my repositories, services, etc. (with NUnit currently), but what I'm really wondering is if it is considered "wrong" to use SpecFlow for this purpose also.
Brian McCord
I would think so, SpecFlow is more suited to testing large chunks of code as is, with no mocking or isolating.
Igor Zevaka
+1  A: 

Can't I just use normal unit testing tools? BDD is a process and mentality and so, yes, you can do it with any tools (or not, you can write your own without a tool if you want). However, the TDD tools had certain assumptions which cause some friction when trying to do things in a BDD way. For instance, TDD assumes you are testing an architectural unit of the software; class, module, service. Whereas BDD assumes you are specifying some functional portion of the system.

Should I use SpecFlow/Cucumber to describe lower-level components? First of all, I think the question is a bit misguided. You wouldn't tend to describe components unless those components directly represent behavior. I'll still answer what I believe the spirit of the question is.

Story oriented tools like Cucumber are great for talking about behavior from a customer/user perspective. It can allow you to make specifications that are easily approachable by laymen. However, it can be tedious to describe large amounts or complex state with those tools.

Unit testing, or more code oriented specification tools like rSpec and Machine.Specification, can be a lot more convenient when dealing with complex or large state setups. You can use the various tools available to the languages to manage the state. Things like inheritance and fakes/mocks. Machine.Specification has some good approaches to this for the .NET minded.

So, should you use Cucumber to specify lower-level behavior? I'd say only if its important to have high levels of visibility for that particular behavior. On my current project, we've developed an architectural component to represent certain business-rule intensive portions of the system. Those components are specified with Cucumber, but the majority of system is covered with NUnit.


Btw, SpecFlow is really nice and approachable for .NET folks just getting into BDD, but eventually you'll want to graduate to full-blown Cucumber+nStep. The Cucumber ecosystem is HUGE and helpful. SpecFlow's is much smaller.

Also, the lambda syntax offered by nStep is quite a bit nicer than having to decorate methods a la SpecFlow or Cuke4Nuke.

Disclaimer/Background: I did some of the original development on nStep but I'm using SpecFlow on my current project. I'm working to introduce BDD here and needed something simple and approachable.

brendanjerwin