Dataworks Blog

    RAPID RUNDOWN: HOW WE APPROACH BEHAVIOUR DRIVEN DEVELOPMENT

  •  

    In a previous blog post we outlined how we arrived at Behaviour Driven Development (BDD). This post is a short outline of what BDD means and some tooling for developers using Visual Studio as their IDE.

    In Test Driven Development the developer starts by writing tests. With BDD the developer instead starts by writing a feature. A feature is similar to a user story in general agile approaches. Each feature is broken down into a set of distinct scenarios. These scenarios are captured in a domain specific language called Cucumber and take the form of Given, When, Then.

    These features provide functional documentation for the application in one place. Where it starts to get interesting is that with specific tooling these scenarios can be tied directly to unit tests implemented in your test framework of choice e.g. MSTest, NUnit, XUnit etc.

    Unit tests are written for each scenario in a TDD based approach

    ·         Write the test for a scenario

    ·         See that it fails

    ·         Implement enough of the feature for the test to pass

    ·         Refactor

    ·         Move to the next scenario

    This leads to a single point of documentation for each feature with the various scenarios related to that feature tied directly to unit tests which in turn exercise the implementation of that feature within the application.

    To achieve this in Visual Studio we need specific tools to support writing features in Cucumber and tying these tests to our unit tests. Our choice for this has been the SpecFlow extension for Visual Studio. SpecFlow supports BDD in Visual Studio from 2010 up.

    To use SpecFlow, first install the Visual Studio extension. We then add a separate class library project to our solution for our BDD tests. We use Nuget to add SpecFlow and SpecFlow.Assist.Dynamic to this project. The default test runner is NUnit but you can set your preferred test runner in the app.config e.g.

    <unitTestProvider name="MSTest" /></specFlow>

    For more on SpecFlow visit the website at http://www.specflow.org/

    For ASP MVC applications we take the approach of testing from the “controller” to the database. We want to exercise database functionality as part of the tests especially in cases where stored procedures are used as part of the data access layer. If we mock out all of that then we may miss bugs in the database layer.  In some cases there may be databases outside of our application, in those cases we would most likely implement an API to access this data, in such cases we mock out the API.

    So for example a SpecFlow feature file might contain some Cucumber as follows:

    Feature: AddOrangesToPile
    	As a person who likes to collect oranges
    	I would like to be able to add oranges to a pile of oranges
    
    		
    @AddAOrange
    Scenario: Add one orange when I previously had none
     Given that no oranges exist
     When I add 1 orange
     Then I now have 1 orange in my pile of oranges
    

    Right clicking allows us to generate a step definition skeleton which maps unit tests to our Cucumber scenarios, I’ve added some comments to show how the tests might be implemented e.g.

            [Given(@"that no oranges exist")]
            public void GivenThatNoOrangesExist()
            {
                ScenarioContext.Current.Pending();
         // here we’d call through our controller to check how many oranges are 
         // currently in the database for our application 
         // and add assertions to check that there are none
            }
    
            [When(@"I add (.*) orange")]
            public void WhenIAddOrange(int p0)
            {
                ScenarioContext.Current.Pending();
         // here we’d make a call to our Orange Controllers add method
            }
    
            [Then(@"I now have (.*) orange in my pile of oranges")]
            public void ThenINowHaveOrangeInMyPileOfOranges(int p0)
            {
                ScenarioContext.Current.Pending();
    	     // here we’d read back the current count of oranges in our database
    	     // and assert that its 1
            }
    

    The unit tests stubs can then be filled out, initially to fail. Then the implementation can be added to make the tests pass.

     

    At Dataworks we enable the perfect hybrid of configurable off the shelf toolsets and custom software development to deliver innovative solutions to match your specific business process requirements. This ensures we are the best at what we do.

    If you would like to discuss how we can use our experience and expertise to deliver real benefits to your business please contact us today on 051 878555 or email info@dataworks.ie

     

    Image courtesy of Stuart Miles at FreeDigitalPhotos.net

  • Back to Blogs