03 January 2010

BDD podcast for ANUGCast

I was recently interviewed for ANUGCast by Søren Skovsbøll about Behavior-Driven Development. If you want to listen to it you can find it here.

Labels: ,


23 October 2009

Use AutoHotKey to enable easy BDD naming style

When writing BDD specifications I prefer to use StoryQ. But on smaller projects I often revert to using more traditional TDD with a dash of BDD naming style:

8 public class MessageBusTests

9 {

10 public void Should_send_message_when_event_occur()

11 {

12 // SUT code

13 }

14 }


But typing the underscores soon become tiresome so I use AutoHotKey and a script by JP Boodhoo to auto-insert an underscore every time I hit space.

If you would like to try this out, do the following:
  1. Install AutoHotKey
  2. Copy the file "BDD naming mode.ahk" to your start menu folder along with the two icon files from the zip file.
  3. Double click the .ahk file to enable the script or restart your computer.
Now you can turn on/off the BDD naming style using Ctrl+Shift+U. The BDD icon in your tray should change to indicate activation.

Download BDD naming mode script and icons: AutoHotKeyBDDNamingMode.zip

Labels: ,


19 October 2009

When your tests rot

The last 15 months I have worked as project manager, system architect and competency trainer at Transsoft A/S.

When I was hired, my task was to implement transparent project management, which would allow the board to know what development was doing and how the project was progressing. I also had to implement practices, which would empower the team to deliver software of a verifiable quality level.

ERP software is supposed to last many years, often 10-15 years. This means, that it must be built to be maintainable, and it must have a very extensible and flexible application architecture, which allow for easy implementation of customer specific busines rules and views.

In order to deliver a system with the kind of progress transparency and quality of architecture demanded by the board, I had the following agenda:

Concretely:
All these elements are needed in some form or shape, to deliver the kind of software we write. But the test-suite, that is the result of test-first development, is to me, the most important element, to ensure a steady progress and a certain level of quality to the code. A Lot of Good Things emerge when you do Test-Driven Development/BDD that I will not reiterate here,

The last few months I have spent a lot of my time developing a course department in Transsoft. This has had the consequence, that I haven't had the same focus on our practices and quality of the code, that I had before. My lack of focus on our practices have resulted in a rotting test-suite.

After a major refactoring (that I gave the greenlights on), our tests were not kept in synch, and we could no longer rely on them. This has reduced the confidence of the team, as we can no longer run all our tests and know, that adding a new feature or removing a bug, has not changed the expected behavior of the system. In addition, the test-suite is now technical debt and does the exact opposite of its intention - it reduces confidence instead of reinforcing it.

We have changed our sprint plan to give the developers time to refactor the tests to get in synch with the codebase. We also did a brush up on our DONE DONE DONE definition as well on why we use the practices we do. But this work takes time, velocity is reduced and refactoring 500+ tests is a pain.

So my advice to any team practicing TDD or unit-testing is to NEVER, EVER ALLOW YOUR TESTS TO ROT!

Labels: , , ,


07 October 2009

Slides from BDD presentation

Update: I have zipped the slides for download as the original link was broken!

I recently did a presentation on Behavior-Driven Development using User Stories, Acceptance Criteria and a tool called StoryQ at Frontdata in Viby for Århus .NET User Group.

Thanks for the participation from the engaging audience, it was great!

You can download the slides here: anug.BDD.presentation.zip

Labels: , ,


02 September 2009

BDD presentation in Århus .NET User Group

On Wednesday 30th of september I'm doing a presentation on Behavior-Driven Development for Århus .NET User Group. I introduced TDD to the team I work with at Transsoft in august 2008. After 7-8 months we transitioned fully to BDD - a choice both I and the developers are very happy about.

I've had a number of people mailing me questions about BDD and how we practice it. In the presentation I'll show exactly how we do it and explain why it works for us.

If your team thinks about moving to BDD (or TDD) it is possible to hire me for a day or two of education. Send me a mail at: mbo at transsoft dot dk if you are interested. Or take a look at the courses we offer at Transsoft: http://www.transsoft.dk/kursus-afdeling-kalender.aspx (in danish)

Labels: ,


29 June 2009

BDD with StoryQ

Behavior-Driven Development means building software with an intentional focus on the context of the requested behavior as expressed by the customer.

We use stories to capture the essence of a conversation with the customer. It includes the role of the person who need a specific feature as well as the motivation for it.

Story: Some descriptive story title
As a [ROLE]
I want [FEATURE]
So that [MOTIVATION]

While the story captures the essence of what is needed, we use acceptance scenarios to tell us how the feature is supposed to work as well as when the story is actually finished.

Scenario: Some descriptive scenario title
Given [SOME CONTEXT]
When [SOME EVENT OCCURS]
Then [ENSURE SOME DESIRED OUTCOME]

Most stories require several acceptance scenarios to fully flesh out the required behavior, covering both success- and failure scenarios.

Working in this way has some serious benefits. You are always developing exactly what the customer requested, not what you think she needs. The coherency and elegance of your interfaces has a good chance to increase as your mind is guided by a real world work flow perspective as expressed by the customer in the acceptance scenarios.

In traditional TDD the focus is on the single class and it's collaboration with other classes while BDD focus on a sequence of actions that, as a whole, has business value, makes sense for, and can be expressed by, the customer herself.

Doing BDD is about reducing the loss of semantics in the process of capturing the requirements to the actual 'translation' into working software. If we can help the customer to express the whats (stories) and the hows and whens (scenarios) in the format presented above, we are very close to executable requirements that can be put directly into our code.

Enter StoryQ.

StoryQ is a framework for Behavior-Driven Development. There exist other such frameworks for .NET such as NBehave and to a lesser extend MSpec. StoryQ allows us to take the stories and scenarios - as written by the customer - and put them directly into our code .

StoryQ uses a fluent interface API which conforms very naturally to the format of both stories and scenarios.

First the story and scenario as written by the customer:
Story: Create a booking
-------------------------
As a booking clerc
I want to create new bookings
So that the cargo of our customer can be handled efficiently

Scenario: Create a new booking
-------------------------------------------------------------
Given a view to create a new booking
When I enter customer data
and enter cargo pickup address
and enter cargo delivery address
and enter payment address
and enter billing info
and enter cargolines
and save the booking
Then I want the booking to be saved
and available on the list of unplanned bookings
We can now take this text and put it into a specification file where we can run it (NUnit).

[TestFixture]
public partial class Resources_Spec
{
    [Test]
    public void Create_A_Booking()
    {
        var story = new Story("Create a booking");
 
        story.AsA("booking clerc")
            .IWant("to create new bookings")
            .SoThat("the cargo of our customer can be handled efficiently")
 
            .WithScenario("Create a new booking")
            .Given("a view to create a new booking")
            .When("I enter customer data")
                .And("enter cargo pickup address")
                .And("enter cargo delivery address")
                .And("enter payment address")
                .And("enter payment address")
                .And("enter billing info")
                .And("enter cargolines")
                .And("save the booking")
            .Then("I want the booking to be saved")
                .And("available on the list of unplanned bookings");
 
        story.Assert();
    }
}

The output of running this specification is this (I use ReSharper to run my specs):




As you can see, the format of the output is the same as that the customer wrote. It is also plain that all the steps of the specification are pending - no code has been written yet.

It should also be plain that this spec now provides a step-by-step plan for implementing the expressed need of the customer, right there in your code - no excess interpretation - no loss of semantics (provided you have written good stories and scenarios, but that is the subject of another post).

Now you can start making the specification pass.

Take small steps. This part is much like traditional TDD.

Use the specification to drive the design of your interfaces. Implement only just enough to make it pass. Refactor as needed. Repeat.

[TestFixture]
public partial class Resources_Spec
{
    [Test]
    public void Create_A_Booking()
    {
        var story = new Story("Create a booking");
 
        story.AsA("booking clerc")
            .IWant("to create new bookings")
            .SoThat("the cargo of our customer can be handled efficiently")
 
            .WithScenario("Create a new booking")
            .Given(()=>aViewToCreateANewBooking())
            .When("I enter customer data")
                .And("enter cargo pickup address")
                .And("enter cargo delivery address")
                .And("enter payment address")
                .And("enter payment address")
                .And("enter billing info")
                .And("enter cargolines")
                .And("save the booking")
            .Then("I want the booking to be saved")
                .And("available on the list of unplanned bookings");
 
        story.Assert();
    }
 
    IBookingView view;
 
    private void aViewToCreateANewBooking()
    {
        view = new BookingView();
        Assert.That(view, Is.Not.Null);
    }
}
public interface IBookingView
{}
public class BookingView : IBookingView
{}

The ReSharper test runner output now looks like this:



Now you simply continue driving out your interfaces and making the next step of your specification pass until the entire story pass.

If you are coming from TDD this way of working will soon become addictive. BDD is very effective and ensure a better understanding of, and emphasis on, developing software that in behavior and usage do exactly what was intended by the customer.

But do not take my word for it. Go download StoryQ and grap a copy of User Stories Applied by Mike Cohn and start building better software!

Labels: ,


13 March 2009

Transactional testfixture with db rollback

Doing integration testing sometimes require that you hit the database. As we want to run our tests in isolation we go through the following steps for every test run:
  1. deploy db schema (time consumer)
  2. populate tables with required test data
  3. run the test
  4. undeploy the db schema (time consumer)
While this works, it takes more than an hour to run the several hundred integration tests we currently have in our project.

So instead of deploying and undeploying our db schema for every test we run, we're using a transactional testfixture which rolls back every change made to the database in the TearDown() method:

   12     /// To use this class, your NUnit TestFixtures must inherit it 
   13     /// and override the Setup() and Teardown() methods (remember to call base).
   14     /// 
   15     /// Note: TransactionScope requires MSDTC is enabled on the machine running the tests.
   16     /// Note: This article explains how to enable MSDTC on a Windows XP SP2: 
   17     /// http://blogs.msdn.com/florinlazar/archive/2004/06/18/159127.aspx
   18     /// 
   19 
   20     [TestFixture]
   21     public abstract class AbstractTransactionalTestFixture
   22     {
   23         private TransactionScope transactionScope;
   24 
   25         [SetUp]
   26         public virtual void Setup()
   27         {
   28             transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew);
   29         }
   30 
   31         [TearDown]
   32         public virtual void Teardown()
   33         {
   34             transactionScope.Dispose();
   35         }
   36     }

This has succesfully reduced the execution time to a few minutes.

Labels: ,


15 August 2008

BDD and that warm fuzzy feeling inside

Inspired by a Magic the Gathering card quote:
"For the first time [the developer] felt warm and fuzzy inside"
BDD has a distinct and real influence on those who transition to it. We all know the gut-wrenching agony of working on a big-bundle-of-messy-code project, where you anticipate immediate disaster and unemployment every time you change or add a line of code. Likewise, many developers know the uncertainty felt when faced with a complex task they do not know they are able to solve.

Both ailments are cured when practicing BDD. Your specifications give you confidence that if your code change breaks anything, you will know immediately. Driving your design, spec by spec, gives you the confidence to solve even very complex problems.

All in all, BDD lessen your worries and builds confidence. Is is almost a zen-moment when a developer let's himself go and puts his trust in BDD to carry him through. Once that step is taken, there is no going back, because now, every day, you want that warm and fuzzy feeling inside.

Labels:


14 August 2008

Changing your practice: BDD

I have introduced the XP practice of Behavior-Driven Development (BDD) to my colleagues. The art of unit testing was not foreign to them, but driving the design of your interfaces and architecture using BDD was a new concept to them. I'm very pleased that they have caught on to the benefits of BDD so fast and that they appear to enjoy it!

In practice we use BDD in the following context:

A developer selects the story he wants to work on. The story tasks are disclosed using acceptance criteria scenarios. During development further tasks may emerge as we gain more understanding of the system. Story point estimates are updated accordingly.

The developer selects the task he feels is the most appropriate to start with. Experience and reflective thinking will help in selecting the most appropriate entry point of design.

The developer now adds a specification to the test project. We use NUnit and Rhino Mocks.

Now the most simple specification the developer can write is typed. We flesh out the interface, member by member, and implement only enough code to get green lights. Thinking about the big picture is allowed and necessary, but restraint is urged. Just enough architecture is implemented at last responsible moment.

Spec by spec the interface emerges. We know and accept that refactoring will occur in many iterations before the code is done. We don't try to bake the perfect cake in first try. As Uncle Bob puts it: "First make it work - then make it right - then make it fast". This credo may seem simple, and it is, that is it's strength.

Don't overreach yourself, experiment with your own capabilities and develop a BDD style of your own. Reach a point where you can sustain a continous pace. We develop during sprints yes, but the project as a whole is a long journey, set your pace so that you reach the goal-line and don't 'hit the wall' halfway.

We have only just started, but my gut-feeling about the process and the people I work with is good. More on this subject later. I'm off to bed...

Labels: ,


05 July 2008

Example: User Story and Acceptance Criteria Scenario

I promised to make a follow-up post on a real-world example using User Stories and Acceptance Criteria Scenarioes. As I am still new to most of the business concepts at my new job; I will not presume that the example is covering everything it should. It is just provided as an example of how we will be using User Stories and Acceptance Criteria Scenarios.

So here goes:

User Story

Title: Update planned plan with driver info
As an Accountant
I want to update the planned plan with information from the driver(s)
So that the invoice(s) to customers and hauliers are based upon actual and correct information

Acceptance Criteria Scenarios

Scenario 1: Mark an associated plan of a planned plan as carried out
Given a planned plan with 3 associated plans that are not marked as carried out
When one associated plan is marked as carried out
Then ensure that the number of associated plans, that are not marked as carried out, is 2

Scenario 2: Planned plan is marked as carried out
Given a planned plan
When all associated plans are marked as carried out
Then ensure to mark planned plan as carried out

Labels: , ,


27 June 2008

User Stories and Acceptance Criteria Scenarios

In our current project we will be using Scrum for project management and augment the process with practices from XP, such as acceptance testing, continous integration and hopefully behaivour-driven development.

We will be collecting requirements with user stories, small three-sentence stories written by the customer, which tell the things they want the system to do. We will start out with this story format:
Title: One line describing the story
As a <role>
I want <goal>
So that <motivation>
The user story will fill the role it does in a XP project, but we will also be using it to express the story's behaviour or acceptance criteria. The acceptance criteria will have an executable feel about them, which is good, as we will be using them in our BDD specifications.

An acceptance criteria scenario looks like this:
Scenario 1: Title
Given <some initial context>
And <some more context>
When <an event occurs>
Then <ensure some outcome>
And <ensure another outcome>
I'll make a follow-up example of how a user story and acceptance criteria scenario will look like in a realworld case.

Labels: , ,


This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]