Posts tagged ‘Agile’

Following on from my previous post I thought it only fair to dive down into the code that was shown in that article and give a bit more of an explanation on what is going on.

First of all, some of you may have looked at the sample code and asked “What is the ContextSpecification class that the ShoppingCartContext is derived from?” – fair question and one that deserves to be explained.

Allow me to digress momentarily in order to try and set the context (for you seasoned BDD’rs – pun intended!). I was first introduced to BDD (indirectly) at a session on coding Katas at TechEd 2010 in New Orleans and BDD was not exactly why I had attended the session. The Behavior Driven aspect of the interactive presentation was very brief and at the time I was left with the desire to know more, so before the End of TechEd party I spent time scouring numerous technical and not so technical sites – looking for further details. What I found was far more than I had bargained for; it wasn’t that the tests were written in a natural language sort of way, it was the idea that the code was being driven via tests that were in turn driven by use cases – OMG!!!! You mean that the requirements analyst directly affects the way the tests are written? I had already bought in to the TDD mindset and to me it had made perfect sense, but this was far beyond what I had bargained for. So in true engineering fashion – I tried it out myself and low and behold it worked (albeit in a very sanitized and benign sort of way). Before we go any further, I would highly recommend that you read Dan North’s Introduction to BDD (http://behaviour-driven.org/Introduction); there you will see that many of us may be fortunate to get to step 4 of the steps to enlightenment. In my case I was there and thanks to the intro to BDD I would get to 6 and hopefully on to step 7.

So there I am trying to implement my first set of BDD tests (before code implementation) and I hit my first stumbling block. The Context Specification Framework I had been introduced to at TechEd, Machine.Specification by Aaron Jensen (http://github.com/machine/machine.specifications), had wonderful plugin capabilities for ReSharper but nothing that I could use inside of MSTest; yes I know, “big deal”, “so what”, blah, blah… Well as much as I love ReSharper, I still prefer to run MSTest as it is what is run in my build environments. Therefore anything that I have difficulty running with MSTest will be an even bigger hassle on my build machines. So off I went again, looking for more jewels in the proverbial rain-forest of information and lo-and-behold I came across Eric Lee’s implementation of a base class that uses MSpec (http://blogs.msdn.com/b/elee/archive/2009/01/20/bdd-with-mstest.aspx) called ContextSpecification. It is a superb abstract class that allows me to easily write my BDD style test classes and thereby drive my code implementation.

Now then, we have the MSpec assembly reference and now an abstract class (ContextSpecification) to derive from and as I am a big fan of RhinoMocks (for generating mocks or stubs), let’s throw that into the mix. With this base we are ready to go do some BDD.

As I have stated before, the Requirements are what drive our tests in BDD; more specifically the creation of Use Cases will drive the tests. So going back to the example in my previous post, we will start with the following requirement:

    A customer can add items to their shopping cart.

Strictly speaking, in SCRUM terms, this should be written as follows:

    AS A Customer

    I WANT to be able to add items to a shopping cart

    SO THAT I can keep a collection of items that I want to buy.

From this user story we can expand the Use Cases (I also consider them as Conditions of Acceptance for the User Story) to give me detail to the high level statement:

Scenario 1: Adding items to an empty shopping cart

  • GIVEN that the shopping cart is empty
  • WHEN the customer adds 1 item
  • THEN the shopping cart should contain 1 item

Scenario 2: Adding items to a full shopping cart

  • GIVEN that the shopping cart contains 2 items
  • WHEN the customer adds 1 item
  • THEN the shopping cart should contain the 2 existing items and the 1 new item.

I have purposefully capitalized the GIVEN, WHEN and THEN, simply to draw parallels with the AS A <role> I WANT <functionality> SO THAT <benefit> of SCRUM and hopefully highlight the fact that patterns can be drawn from both and thereby help us to create consistent ways in which to write both User Stories and Use Cases.

Now that we have our Use Cases we can start to create our tests. Taking the first scenario we will need to setup a Shopping cart context; which is where we bring in the ContextSpecification abstract class (remember, we don’t have any implementation code yet):

namespace Bdd.Shopping
{
    public class ShoppingCartContext : ContextSpecification
    {
        /// <summary>
        /// The "Given some initial context" method
        /// </summary>
        protected override void Context()
        {
            // setup your class under test
        }
    }

    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class UnitTest1 : ShoppingCartContext
    {
        /// <summary>
        /// The "When an event occurs" method
        /// </summary>
        protected override void BecauseOf()
        {
            //
            // TODO: Add behavior setup (Action) here
            //
        }

        /// <summary>
        /// The "then ensure some outcome" method.
        /// </summary>
        [TestMethod]
        public void TestMethod1()
        {
            //
            // TODO: Add test logic here
            //
        }
    }
}

Remember that the use case was written as follows:

  • GIVEN that the shopping cart is empty
  • WHEN the customer adds 1 item
  • THEN the shopping cart should contain 1 item

The “GIVEN” aspect of the use case is the Context() method of our base class – where we initialize our member variables.

The “WHEN” of the use case will be the TestClass – this will be the container for the THEN aspect.

The “THEN” will be the TestMethod and perform the appropriate assert(s).

Putting all of this together we arrive at the following:

namespace Bdd.Shopping
{
    public class ShoppingCartContext : ContextSpecification
    {
        protected ShoppingCart _cart;
    }

    /// <summary>
    /// Test Class for "WHEN the customer adds 1 item THEN the shopping cart should contain 1 item"
    /// use case.
    /// </summary>
    [TestClass]
    public class when_1_item_is_added_to_an_empty_shopping_cart : ShoppingCartContext
    {
        /// <summary>
        /// The "Given some initial context" method
        /// </summary>
        protected override void Context()
        {
            _cart = new ShoppingCart();
        }

        /// <summary>
        /// The "When an event occurs" method
        /// </summary>
        protected override void BecauseOf()
        {
            ShoppingItem item = new ShoppingItem();
            _cart.Add(item);
        }

        /// <summary>
        /// The "then ensure some outcome" method.
        /// </summary>
        [TestMethod]
        public void then_the_shopping_cart_should_contain_1_item()
        {
            Assert.AreEqual(1, _cart.Items.Count);
        }
    }
}

The class name of the TestClass and the method name of the TestMethod help us associate the test with the first use case; “WHEN the customer adds 1 item THEN the shopping cart should contain 1 item”.

In true TDD fashion we have only implemented enough to compile (i.e. absolute minimum of implementation classes) – so this test will fail:

BDD  - Fail First

The next step, of course is to put in the functionality to get the test to pass (TDD mantra – Red, Green, Refactor, Repeat until all test are done). In the case of the implementation classes, we will go from this:

    public class ShoppingCart
    {
        internal void Add(ShoppingItem item)
        {
            throw new NotImplementedException();
        }

        public List<ShoppingItem> Items { get; set; }
    }

    public class ShoppingItem
    {
        public ShoppingItem() {}
    }

To this:

    public class ShoppingCart
    {
        public ShoppingCart()
        {
            Items = new List<ShoppingItem>();
        }

        internal void Add(ShoppingItem item)
        {
            Items.Add(item);
        }

        public List<ShoppingItem> Items { get; set; }
    }

    public class ShoppingItem
    {
        public ShoppingItem() {}
    }

This will give us green in our first test:

BDD  - Then Pass

Now we move on to the next use case:

  • GIVEN that the shopping cart contains 2 items
  • WHEN the customer adds 1 item
  • THEN the shopping cart should contain the 2 existing items and the 1 new item.

Here we see that the Use Case is more specific in that it is requiring us to check that the latest item has been added – we will need to add an identifier to the item be able to check against it in our assertion. This will mean that we will need to run our first test again as we will be changing the implementation classes.

First we write the new Test class and associated Test method and do the minimum implementation to get it to compile.

New Test class and Test method:

    [TestClass]
    public class when_1_item_is_added_to_a_cart_containing_2_items : ShoppingCartContext
    {
        private const string NewItemTitle = "Test Driven Development By Kent Beck";

        /// <summary>
        /// The "Given some initial context" method
        /// </summary>
        protected override void Context()
        {
            _cart = new ShoppingCart();
            ShoppingItem item = new ShoppingItem("Behavior Driven Development By Dan North");
            _cart.Add(item);
            item = new ShoppingItem("Agile Software Development with Scrum By Ken Schwaber and Mike Beedle");
            _cart.Add(item);
        }

        /// <summary>
        /// The "When an event occurs" method
        /// </summary>
        protected override void BecauseOf()
        {
            ShoppingItem item = new ShoppingItem(NewItemTitle);
            _cart.Add(item);
        }

        /// <summary>
        /// The "then ensure some outcome" method.
        /// </summary>
        [TestMethod]
        public void then_the_shopping_cart_should_contain_the_2_existing_items_and_the_1_new_item()
        {
            Assert.AreEqual(3, _cart.Items.Count);
            Assert.AreEqual(NewItemTitle, _cart.Items[2].Title);
        }
    }

Minimum implementation classes:

    public class ShoppingCart
    {
        public ShoppingCart()
        {
            Items = new List<ShoppingItem>();
        }

        internal void Add(ShoppingItem item)
        {
            Items.Add(item);
        }

        public List<ShoppingItem> Items { get; set; }
    }

    public class ShoppingItem
    {
        public ShoppingItem(string title) {}

        public string Title { get; set; }
    }

When we run the test, the first one will still pass, but seeing as we have done the minimum to be able to compile the second test will fail:

BDD  - Then Fail Again

So therefore the next stage is to make the red go green and “back fill” the correct functionality – to update the implementation class as follows:

    public class ShoppingItem
    {
        public ShoppingItem(string title)
        {
            Title = title;
        }

        public string Title { get; set; }
    }

Now when we run the tests all should be green:

BDD  - Then Pass Again

As we continue we are always aligning our code with the use cases and therefore ensuring that we are adding the business value as intended. With the TDD aspect we are also ensuring that any changes we do to the implementation can be done so with the peace of mind that as long as all of the tests past before we go on to the next use case, we will be building robust code.

As I have said in this blog post and the previous one, BDD is a natural evolution of TDD in as much that it adds the linkage from the tests to the requirements. At a personal level it is also a natural progression in my continuous evolution as a software professional and it helps to consolidate my understanding of the requirements more than any type of review ever could.

Make no mistake, BDD and (especially) TDD are a definite shift in mindset mostly in the idea that the test is written first and you only write enough of the implementation to be able to get the test to pass. This puts the onus on the test being right in the first instance and places more significance on the testing aspect of software development.

  • Share/Bookmark

Although many people may have commented so. I have been drawn in and fired up by Behavior Driven Development (BDD) and through various discussions I have found a great number of non-believers and nay sayers who, strangely enough, don’t truly “get” Agile development either. Strange that, isn’t it? The brick wall I sometimes encounter when trying to get the idea of SCRUM across to certain people is that it is “academic and won’t really work for us”, “we can use facets of it, but the thing as a whole just doesn’t fit”. And in a similar way the same arguments came up when I mention BDD.

So let’s refresh our knowledge on BDD before we go any further. Behavior Driven Development was the brain child of Dan North and he has an excellent article about its evolution on his blog (http://blog.dannorth.net/introducing-bdd/). BDD brings together the Requirements Analyst with the Testers and Developers to start breaking down the stories into use cases (may be known as Conditions of Acceptance in a User Story). So what’s new you may ask? Well, those Use Cases, written in natural language become the definitions of the Test Cases and Unit Tests that will drive the code.

What? Test before Code? Unheard of! Charlatan!

Oh please! Really? Yes folks, BDD is sometimes seen as an extension of TDD (Test Driven Development). TDD pushes the testing to the fore and is used to drive the implementation, so rather than waiting until the code is written to create the unit tests, we now create the unit test and write the code to make the test pass. In my mind I see BDD as TDD on steroids! So how does it work?

Imagine the following (benign and fictitious) requirement:

  • A customer can add items to their shopping cart.

This could be expanded into the following use cases (or conditions of acceptance):

Scenario 1: Adding items to an empty shopping cart

  • Given that the shopping cart is empty
  • When the customer adds 1 item
  • Then the shopping cart should contain 1 item

Scenario 2: Adding items to a full shopping cart

  • Given that the shopping cart contains 2 items
  • When the customer adds 2 items
  • Then the shopping cart should contain 4 items

From this we can derive our test cases and the definition of our Unit Tests. Consider the following code:

namespace ShoppingCartExample
{
    public class ShoppingCartContext : ContextSpecification
    {
        protected ShoppingCart _cart;
    }

    [TestClass]
    public class when_1_item_is_added_to_an_empty_shopping_cart : ShoppingCartContext
    {
        ///

        /// The "Given some initial context" method
        /// 

        protected override void Context()
        {
            _cart = new ShoppingCart();

        }

        ///

        /// The "When an event occurs" method
        /// 

        protected override void BecauseOf()
        {
            ShoppingItem item = new ShoppingItem("Behavior Driven Development By Dan North");
            _cart.Add(item);

        }

        ///

        /// The "then ensure some outcome" method.
        /// 

        [TestMethod]
        public void the_shopping_cart_should_contain_1_item()
        {
            Assert.AreEqual(1, _cart.Items.Count);
        }
    }

    [TestClass]
    public class when_2_items_are_added_to_a_shopping_cart_containing_two_items : ShoppingCartContext
    {
        ///

        /// The "Given some initial context" method
        /// 

        protected override void Context()
        {
            _cart = new ShoppingCart();
            ShoppingItem item = new ShoppingItem("Behavior Driven Development By Dan North");
            _cart.Add(item);
            item = new ShoppingItem("Agile Software Development with Scrum By Ken Schwaber and Mike Beedle");
            _cart.Add(item);
        }

        ///

        /// The "When an event occurs" method
        /// 

        protected override void BecauseOf()
        {
            ShoppingItem item = new ShoppingItem("Test Driven Development By Kent Beck");
            _cart.Add(item);
            item = new ShoppingItem("The Art of Unit Testing By Roy Osherove");
            _cart.Add(item);
        }

        ///

        /// The "then ensure some outcome" method.
        /// 

        [TestMethod]
        public void the_shopping_cart_should_contain_4_item()
        {
            Assert.AreEqual(4, _cart.Items.Count);
        }
    }
}

I will go in to more detail about the code in a later blog article. For now we will concentrate on the naming of the classes and Test Methods.

Once we have implemented the code that the tests call, we will see the following results:

BDD Unit Test Results

You can now see how the unit test classes relate to the context of the use case (“Given that the shopping cart is empty” with “When the customer adds 1 item“) and the test methods relate to the result criteria (“Then the shopping cart should contain 1 item“).

The beauty of BDD is that it slams the team into instant interaction; there are no ceremonies, burndowns or roles to allow us to ease into the Agile environment; this is an “in your face”, “get on with it” approach and is an Agile technique that can easily be used within the SCRUM framework. This is also the “ugly” part of BDD, individuals may not be comfortable working in this way and this leads to a bigger question of a right fit for those individuals. The benefits of working introducing BDD to your team are obvious:

  • The clarity of requirements are brought to the fore faster than in any other circumstance – if you can’t write the test, then something is wrong with the requirements and the team will spot that as soon as they sit down to work with the requirements analyst.
  • Unit Tests are written from the beginning and make sense to everyone, even the non-technical members of the group can see how well the design is going, just by looking at the unit tests being run (or not).
  • The design is driven from the requirements – as it should be; why would you write code for anything else? Therefore we see a facet of lean.

The adoption of BDD is by no means easy and it can, as stated before, lead to exposing some deficiencies in the team or environment. This in itself may be a good incentive to adopt; hyper-productive teams are driven to succeed by the very nature of their ease in adopting agile techniques and BDD lends itself to those types of individuals.

  • Share/Bookmark

People often wonder where I get the time and energy to work the way that I do; the truth is it that it is all down to the passion I have for my work as a software engineer and the type of work that I am involved in. I am also very passionate about pushing the boundaries and I find it very difficult to accept that something can’t or won’t be done on the basis of “But, we’ve always done it that way” – it doesn’t necessarily mean that it is the right way, nor does it mean that it is appropriate for today’s world. It might have kept companies ahead of the game 10 or 15 years ago, but the world has moved on since then and now we have to be faster, more efficient, better. For me Agile Software Development lends itself to this change and is all about change.

Becoming Agile... in an imperfect world - Manning Publications

Becoming Agile... in an imperfect world - Manning Publications - Greg Smith and Ahmed Sidky

I will be honest and say that this is the first “work related” book that actually captured my attention to the point that I would sit and read whilst my loved ones were enjoying their sweet slumber (and obviously blog about it).

This book is highly informative; being neither condescending, nor pushy and over-bearing on the way that agile adoption should be approached. Without intending to be a partisan; I would even go as far as saying that it is more than recommended reading, it should be required reading for anyone thinking of migrating to agile; recent adoptees of agile or anyone in between.

From the first chapters that guide us through the principles (I loved the annotated 12 principles of the Manifesto for Agile Software Development – section 1.1.2) and the descriptive text on the “paradigm shift from a plan-driven mentality”; to the readiness assessments and the importance of obtaining executive support; through to the population of the product backlog and on to the first iterations of an example company adopting Agility in their software development process.

There is no substitute for actually reading the book, which is a must; however various chapters and sections drew my attention more than others.

Section 1.1.2 – The agile principles:

Although the manifesto has been analyzed and described on various blogs and books; the descriptive text for each principle was really handy when evangelizing on agile and is a good primer for anyone new to the subject (and possibly even for those of us who have been practicing agile).

Section 1.2 – A paradigm shift from a plan-driven mentality:

This is a must read for those of us who have come from years of waterfall and attempts at changes to “traditional” methodologies or processes. The section highlights the change in mentality that is needed to move from more traditional ways of software development to a leaner, more agile way.

Section 2.4 – What does it look like when a team “becomes agile”:

With comparative plan related diagrams of how the change is made from waterfall to agile and the breakdown of how that transition was made; is comforting for those that have made the change as well as those that are thinking about/planning the change.

Section 3.2 – The different flavors of agile:

This section has a really good breakdown of strengths and weaknesses of the two foremost agile methods; Scrum and XP.

Section 3.3 – Create your own flavor to become agile within your constraints:

When I first started in agile there seemed to be a common mantra that permeated throughout the meetings and blogs that effectively stated if you weren’t doing it exactly by the book, you weren’t being agile. It is completely preposterous.
How can the same agile development methods used by a web advertising company be cookie-cut for a software company writing client server applications in a strong regulatory environment? The answer is – it can’t. There will need to be some adaptation. After all isn’t that one of the principle concepts of agile; what is the point of having Sprint Retrospectives to adjust and tweak a process in a constant attempt to improve? This section is a must read for those that are constantly being belittled or set-upon by “those in the know”.

Chapter 4 – The fitness test: all about readiness assessments:

Although I have not had the opportunity of actually performing this exercise; having read through the chapter it is very informative and goes in to great detail on how a company can be measured for it’s fitness to adopt agile development.

Section 6.3.1 – Tough questions:

I liked this section because of the example of typical questions asked by the team that will be adopting agile development and the possible answers to give about the migration process.

Section 7.1.1 – Attributes of a good coach:

This section contains a very good breakdown of the attributes that should be sought when selecting an agile coach. The following sections go into further detail about training and coaching; as well as details on the interaction with managers and stakeholders.

Section 7.3 – Creating a team with an agile mindset:

This section explains what ingredients are needed to create a sound agile team; from “Culture and roles” through to “Characteristics that influence individual performance”.

Chapter 8 – Injecting agility into your current process:

Just the title alone gives the idea of the maturity of mind that the authors have when confronting a company wanting to adopt agile development methods. From documenting the existing process (not everyone has it written in stone and perhaps not all aspects of the company are actually doing what it says in the process hand-book); to deciding what to keep and what to change.

Chapters 9, 10 and 11

Discuss the selection of a pilot project and the team that will be on the pilot project. This is very informative for those companies that have made up their mind to move to agile and are looking around for the best project to guinea pig.

Section 12.3 – Feature cards compared to…:

As a Scrum practitioner it was interesting to read the comparisons between feature cards, user stories, use cases and functional specifications.

Section 12.5 – Hard-copy vs. electronic cards:

I found this section particularly useful as it highlighted the benefits of both, using SharePoint as an example of the electronic format. Although the idea is to keep it as simple as possible I am an advocate of using technology where possible – more than anything to cut down on the waste generated by so much paper; but also for the fact that you can view the information at any time (this is effective when trying to explain PBI or SBI to persons not located in the same area).

Chapter 13 – Prioritizing the backlog:

This is a subject that I find is the least covered in discussions with peers (both at work and outside) and it is really helpful to see the suggestions posed throughout the chapter. Peppered with examples of a product backlog and how to handle various items; this chapter is a good starting point for broadening the discussion.

Chapter 14 – Estimating at the right level with the right people:

I still remember being asked to estimate for a particular requirement when I still felt that I did not have enough information to do a sound enough job of it. How different it is when you are doing it as a team and everyone can voice their thoughts on the matter. This chapter is particularly useful for those still in “traditional” methods or recent adopters of agile methods. Of particular interest is section 14.1 – Contrasting traditional and agile estimation techniques and section 14.2 – The importance of whole-team estimation; both of which ease the reader into the subject that is quite explanatory with regards to the estimation process in agile.

Section 16.3 – Identifying and estimating tasks:

This section has a nice “call-out” titled “Task assignments aren’t permanent” that describes how the early stages, specialist people will be suited to certain tasks and how with the passage of time and acquired experience in an agile environment team members will become more capable of taking on varied tasks that perhaps were out of their realm in the beginning.

The latter chapters of the book, starting with chapter 20, describe the process of adapting to change and learning as we go. Section 20.1 – Common reasons for adapting (i.e. make those tweaks mentioned earlier); describes common issues that crop up and some ways that teams adapt to the situation described.
Chapter 22 is particularly interesting with a detailed explanation on how to prepare and manage the retrospective.
Chapter 23 is a must read for companies that have successfully started a pilot project and are now looking at how to push across the divide and bring about change at an enterprise level.

As I stated at the beginning of this article, I would seriously make this book required reading for those that are at all interested in adopting agile or have just started – it is clear, concise and has plenty of example scenarios that many individuals and corporations would identify with.

  • Share/Bookmark