Diary of a BDD Beginner

DISCLAIMER: As the title indicates, I am a BDD beginner. I think it is useful for me to publish my experiences because other beginners may find some benefit. If you see something I am doing wrong please leave a comment for everyone to learn from.

I came across a requirement today that I thought was particularly suited to a BDD intro. The requirement in my bug tracker looks like this:

When viewing vehicle details (tracking screen)
Display the timespan between the vehicle's last log and the current time.

when the timespan is less more than one hour
format the timespan as hh:mm eg 1:22 ago

when the timespan is less than one hour
format the timespan as mm ago eg 21 minutes ago

when the timespan is less than one minute
format the timespan as less than 1 minute ago

Tweeple will recognise the similarity between these requirements and the way that twitter shows the age of tweets.

The BDD test, using SpecUnit.net, for one of these requirements might look like this:

[Concern("Vehicles"), TestFixture]
public class when_viewing_vehicle_details_with_last_log_more_than_one_hour_ago 
: ContextSpecification
{
    /* Any objects required by the test */          

    protected override void Context()
    {
        // setup and execute         
    }

    [Observation, Test]
    public void should_format_the_timespan_as_hhmm_ago()
    {
        // verify requirement here     
    } 
} 

The name of the class is the context. This is analogous to a use case or a user story. The name of the test method (or BDD observation) is what we are asserting.

In this case the requirements are implemented by a controller action method called VehicleDetail. Here is my complete BDD test:

[Authorize]
public ActionResult VehicleDetail(string vehicleCode)
{
    var status = vehicleService.RetrieveVehicleStatus(vehicleCode);
    if (status == null) return Content("No data.");
    return View("Detail", status);
}

So to complete the test I need to mock the vehicle service:

[Concern("Vehicles"), TestFixture]
public class when_viewing_vehicle_details_with_last_log_more_than_one_hour_ago : ContextSpecification
{
    private VehicleController controller;
    protected AutoMockContainer container = 
    new AutoMockContainer(new MockFactory(MockBehavior.Loose));
    private const string VEHICLE_CODE = "IMAVEHICLE";
    private VehicleStatusDTO status;
    private ViewResult result;
    private DateTime LOG_TIMESTAMP = new DateTime(2009, 2, 10, 10, 30, 0);
    private DateTime CURRENT_TIME;

    protected override void Context()
    {
        CURRENT_TIME = LOG_TIMESTAMP.AddHours(2).AddMinutes(6);
        status  = new VehicleStatusDTO(
        new VehicleStatus(new VehicleBuilder().Build(), 
        new LogBuilder()
            .WithDeviceTimeStamp(LOG_TIMESTAMP).Build(), Driver.DefaultDriver),
            new DeviceBuilder().Build(), CURRENT_TIME);
        container.GetMock<ivehicleservice>()
            .Expect(vs => vs.RetrieveVehicleStatus(VEHICLE_CODE))
            .Returns(status);
        controller = container.Create<vehiclecontroller>();
        result = (ViewResult) controller.VehicleDetail(VEHICLE_CODE);
    }

    [Observation, Test]
    public void should_format_the_timespan_as_hhmm_ago()
    {
        var dto = (VehicleStatusDTO)result.ViewData.Model;
        Assert.AreEqual("2:06 ago", dto.TimeAgo);
    }
}

SpecUnit.Net includes a tool (SpecUnit.Report.exe) that generates a html report of the specifications in an assembly. The final report, for the Vehicles context, looks like this:

Vehicles specifications    6 contexts, 6 specifications

Vehicles, when viewing vehicle details with last log more than one hour ago    1 specification

  • should format the timespan as hhmm ago

Vehicles, when viewing vehicle details with last log more than one and less than two days ago    1 specification

  • should format the timespan as 1 day ago

Vehicles, when viewing vehicle details with last log more than two days ago    1 specification

  • should format the timespan as X days ago

Vehicles, when viewing vehicle details with last log less than one hour ago    1 specification

  • should format the timespan as X minutes ago

Vehicles, when viewing vehicle details with last log between one and two minutes ago    1 specification

  • should format the timespan as 1 minute ago

Vehicles, when viewing vehicle details with last log less than one minute ago    1 specification

  • should format the timespan as X minutes ago

Comments

Comments are closed