Scrum Gathering London 2011 – day 3

The third day of the London Scrum Gathering (day 1, day 2) was reserved for an Open Space session led by Rachel Davies and a closing keynote by James Grenning.

We started with the Open Space. I’d done Open Spaces before, but this one was definitely on a much larger scale than what I’d seen before. After the introduction, everyone that had a subject for a session wrote their subject down, and got in line to announce the session (and have it scheduled). With so many attendents, you can imagine that there would be many sessions. Indeed, there were so many sessions that extra spaces had to be added to handle all of them. The subject for the Open Space was to be the Scum Alliance tag-line: “Changing the world of work”.

I initially intended to go the a session about Agile and Embedded, as the organiser mentioned that if there wouldn’t be enough people to talk about the embedded angle, he was OK with widening the subject to ‘difficult technical circumstances’. I haven’t done much real embedded work, but was interested in the broader subject. It turned out, though, that there were plenty of interested parties into the real deal, so the talk quickly started drifting to FPGAs and other esoterica and I used the law of two feet to find a different talk.

My second choice for that first period was a session about getting involvement of higher management. This session, proposed by Joe Justice and Peter Stevens (people with overlapping subjects were merging their sessions), turned out to be  very interesting and useful. The group shared experiences of both successfully (and less successfully) engaging higher management (CxOs, VPs, etc.) into an Agile Change process. Peter has since posted a nice summary of this session on his blog.

My own session was about applying Agile and Lean-Startup ideas to the context of setting up a consultancy and/or training business. If we’re really talking about ‘transforming the world of work’, then we should start with our own work. My intention was to discuss how things like transparency, early feedback, working iteratively and incrementally could be applied for an Agile Coach’s work. My colleague and I have been working to try and approach our work in this fashion, and are starting to get the hang of this whole ‘fail early’ thing. We’ve also been changing our approach based on feedback of customers, and more importantly, not-customers. During the session we talked a little about this, but we also quickly branched off into some related subjects. Some explanation of Lean-Startup ideas was needed, as not everyone had heard of that. We didn’t get far on any discussion on using some of the customer/product development ideas from that side of things, though.

Some discussion on contracts, and how those can fit with an agile approach. Most coaches are working on a time-and-material basis, it seems. We have a ‘Money for nothing and your changes for free’ type contract (see http://jeffsutherland.com/Agile2008MoneyforNothing.pdf, sheets 29-38) going for consultancy at the moment, but it’s less of a fit than with a software development project. Time and material is safest for the coach, of course, but also doen’t reward them for doing their work better than the competition. How should we do this? Jeff’s ‘money back guarantee’ if you don’t double your velocity is a nice marketing gimmick, but a big risk for us lesser gods: Is velocity a good measure for productivity and results? How do we measure it? How do we determine whether advice was followed?

Using freebies or discounts to customers to test new training material on was more generally in use. This has really helped us quickly improve our workshop materials, not to mention hone the training skills…

One later session was Nigel Baker’s. He did a session on the second day called ‘Scrumbrella’, on how to scale Scrum, and was doing a second one of those this third afternoon. I hadn’t made it to the earlier one, but had heard enthusiastic stories about it, so I decided to go and see what that was about. Nigel didn’t disappoint, and had a dynamic and entertaining story to tell. He made the talk come alive by the way he drew the organisational structures on sheets of paper, and moved those around on the floor during his talk, often getting the audience to provide new drawings.

There is no way I can do Nigel’s presentation style justice here. There were a number of people filming him in action on their cellphones, but I haven’t seen any of those movies surface yet. For now, you’ll have to make do with his blog-post on the subject, and some slides (which he obviously didn’t use during this session). I can, however, show you what the final umbrella looked like:

All my other pictures, including some more from the ScrumBrella session, and from the Open Space closing, can be found on flickr.

Closing Keynote by James Grenning on ‘Changing the world of work through Technical Excellence’

(slides are here)

The final event of the conference was the closing keynote by James Grenning. His talk dealt with ‘Technical Excellence’, and as such was very near my heart.

He started off with a little story, for which the slides are unfortunately not in the slide deck linked above, about how people sometimes come up to him in a bar (a conference bar, I assume, or pick-up lines have really changed in the past few years) and tell him: “Yeah, that agile thing, we tried that, it didn’t work”.

He would then ask them some innocent questions (paraphrased, I don’t have those slides, not a perfect memory):

So you were doing TDD?

No.

Ah, but you were doing ATDD?

No.

But surely you were doing unit testing?

Not really.

Pair programming?

No.

Continuous Integration?

Sometimes.

Refactoring?

No!

At least deliver working software at the end of the sprint?

No…

If you don’t look around and realise that to do Agile, you’ll actually have to improve your quality, you’re going to fail. And if you insist on ignoring the experience of so many experienced people, then maybe you deserve to fail.

After this great intro, we were treated to a backstage account of the way the Agile Manifesto meeting at Snowbird went. And then about what subjects came up after this year’s reunion meeting. James showed the top two things coming out of the reunion meeting:

We believe the agile community must:

  1. Demand Technical Excellence
  2. Promote individual [change] and lead organizational change

The rest of his talk was a lesson in doing those things. He first went into more detail on Test Driven Development, and how it’s the basis for improving quality.
To do this, he first explains why Debug-Later-Programming (DLP) in practice will always be slower than Test-First/TDD.

The Physics of Debug-Later-Programming

DLP vs TDD

Mr. Grenning went on to describe the difference between System Level Tests and Unit Tests, saying that the System Level Tests suffer from having to test the combinatorial total of all contained elements, while Unit Tests can be tailored by the programmer to directedly test the use of the code as it is intended, and only that use. This means that, even though System Level Tests can be useful, they can never be sufficient.
Of course, the chances are small that you’ll write sufficient and complete Unit Tests if you don’t do Test Driven Development, as Test-After always becomes Release First. Depending on Manual Testing for testing is a recipe for unmaintainability.

The Untested Code Gap

The keynote went on to talk about individual and organisational change, and what Developers, Scrum Masters and Managers can do to improve things. Developers should learn, and create tested and maintainable code. Scrum Masters should encourage people to be Problem Solvers, not Dogma Followers. He illustrated this with the example of Planning Poker. As he invented Planning Poker, him saying that you shouldn’t always use it is a strong message. For instance, if you want to estimate a large number of stories, other systems can work much better. Managers got the advice to Grow Great Teams, Avoid De-Motivators, and Stop Motivating Your Team!

DeMotivators

It was very nice to be here for this talk, validating my own stance on Technical Excellence, and teaching me new ways of talking to people in order to help them see the advantages of improving their technical practices. Oh, and some support for my own discipline in strictly sticking to TDD…

Article on Oracle and Agile posted (Dutch)

My article on using Agile on projects using Oracle technology was published in this months Optimize magazine, and the full text (in Dutch!) is now available on the Qualogy website.

The article is mainly meant as an introduction to agile principles and practices for Oracle developers that are new to them. It focused on explaining short feedback loops, and the importance of technical practices such as Continuous Integration and (Unit) testing for success with iterative and incremental development.

Scrum Gathering London 2011 – day 2

First day report here.

Steve Denning on Radical Management
(slides are here)

The second day of the London Scrum Gathering started with a Keynote by Steve Denning. Where yesterday’s workshop had been about his storytelling work, today he was full-on about Radical Management. He quickly sketched the main points of his book (which everyone got given in their goody bag, so I have two now…), and it’s relation and implications for all the Agile aficionados in the audience.

The message was not all that positive, in a way. Steve described how many companies were, mostly slowly, but often surely, managing themselves to death. For an audience full of Scrum Coaches, the way in which this is happening did not really come as a big surprise: distance between the people doing the work, and the customer, hierarchical and divisive management, and simply not enough focus on Steve’s golden rule: delight your customer!

One of the main implications of this keynote was a worrying one: Steve told some stories (of course:-) on companies that had tried to change, but couldn’t. Some individual Ford manufacturing plants, for instance, tried to work in different ways, got splendid results, but were ordered to stop being silly, and conform to the ‘Ford Way’ of doing things. He stated that for those companies, the only solution was to wait for a generation of managers to leave the company, or for the company to be left behind, to die by natural (market) selection. The Borders ways, so to speak, though Steve was pitting Wal-mart as the walking dead against Amazon’s vibrant business future.

So what happens when you tell a big audience of change agents that in many cases change will not succeed? You get a nice set of questions after your talk, for a start. One of the questions (the one asked by me:-) was: “taking the difficulty of changing existing managers as a given, what can be done to avoid new generations of managers to adopt the same thinking that the current generation has? Can we work with education institutions to try and change the ways new batches of MBAs think?” The answer was that he is indeed working on that, both with the Harvard Business Review, as directly with some education institutes. A glimmer of hope, to end the keynote with.

Tobias Mayer on Dogma Free Scrum
(slides are here)

Next stop was a talk by Tobias Mayer. Tobias has caused some controversy in the last year by denouncing his Scrum Alliance certifications (insert link!). Because of that, I was a little surprised, but certainly happy, to see that he would be talking at this Gathering. The subject was ‘Dogma Free Scrum’. Tobias started by showing some pictures from different sources describing Scrum. This was to illustrate that even with something small and fairly well defined, people will have very different interpretations of what this thing is. He then talked about his own ideas of what Scrum means. His model is certainly simple, and based on the PDCA loop:

But this is so generic as a picture, and so doesn’t really describe what he thinks Scrum is. To complete that, he uses the following list of five principles:

Having given us his view, Tobias then asked us to split up into groups and draw our own picture of Scrum on an A1 (flip-over) paper, keeping those principles in mind. Once we’d done that, we passed our pictures over to the next group, where we continued working on our neighbours’ pictures. This gave a nice insight in how we all see the same subject differently, and communicate it differently.

The next part of this talk took the idea of communication and interpretation further, talking about creating a Collaboration Space. The idea is that many, if not most, issues in a company can be traced to not making clear enough requests. This can be alleviated by focusing on making a Collaboration Space, in which the person making the request can collaborate with the people to whom the request is made, so that common understanding can be reached. The Requester focuses on making the ‘Why’ of the request as clear as possible, while the Responder focuses on the ‘How’. Together they determine the ‘What’.

Joseph Pelrine on Cynefin – Making Sense of Agile

Joseph Pelrine started out his presentation characterising the experience of listening to a talk by Dave Snowden, the originator of Cynefin, as getting hosed by the full blast of a fireman’s spout. He promised us that his talk was intended to bring that down to a more familiar British level of water pressure.

Having just heard Snowden talk at the Lean and Kanban Benelux conference in Antwerp, I can certainly attest that some further explanation is very useful… Joseph elaborated on the nature of complexity, and talked about how these concepts are usually only understood at a very shallow level within the Agile community. (actually quoting a tweet of mine to prove the point:-) He explained that the different areas in the Cynefin model should be handled differently.

He also mentioned that finding out what style to use is not as simple as saying: “Oh, software development is a complex system, so we have to handle anything within software development as complex.” Though the whole of software development is complex, there are plenty of things within the software development process that are not, and are within the complicated or simple areas. He had some figures on how different activities are distributed between the different areas.

The slides for this talk haven’t appeared on-line yet, but he does have an excellent paper on this subject out: On Understanding Software Agility – A Social Complexity Point Of View

If you are interested in this subject, make sure to also read Snowden’s HBR article “A Leader’s Framework for Decision Making”, and browse around on Cognitive Edge’s website for more background.

Mike Bassett (and Roman Pichler) on Lessons Learned from becoming Agile at Electronic Arts

The last talk of the day was an experience report from Electronic Arts. Mike Bassett described how they adopted agile for the development of a physics engine used in many EA games. The talk was mostly done my Mike, with Roman offering intermittend comments along the way.

Mike started with an overview of what they were building (the Physics Engine), and how this fit within the EA company. They had been a separate company, taken over by EA. Most EA games had been using other Physics Engines, and they’d been incrementally improving their product so that it would become attractive to be used in various games. Before their agile adoption, they’d been driven by many different clients at the same time, and had many problems delivering to all of those on time, and with quality. He also described that concomitant to the nature of the work, their people were highly intelligent, independent, and not naturally inclined to spend much time on social niceties.

Then he described how they changed things around to regular releases in close communication with one customer, one game, where other customers/games could use the finished product as well, and take advantage of the new features developed for this priming game. So for instance the new FIFA 2011 soccer game would have specific requests for functionality, and would be the ones providing feedback to the Physics Engine team. But the Ice Hockey game also in development would use the same version as the Soccer game, and get profit from that new functionality.

Mike also presented some metrics. Unfortunately, I haven’t found his slides anywhere on-line yet, so I can’t give a good overview of those metrics. As I recall, many of the expected improvements were there, but there were also a number of surprise outliers. Hopefully, the slides will be released soon so we can look at those numbers in more detail.

There’s one more post coming up about #sglon, talking about the third and final day. That day was an all day Open Space event, and a fantastic closing keynote by James Grenning.

Scrum Gathering London 2011 – day 1

I’ve been having an interesting couple of weeks. Last week I attended the Lean and Kanban Benelux conference in Antwerp, and then had a wonderful three days with Ron Jeffries and Chet Hendrickson when they came over at Qualogy to teach me and my collaeques in the ways of Agile development skills.

This week, I’m in London for the Scrum Gathering conference, meeting with lots of people I’ve so far only encountered over the twitter et al.

Since I’m still here in London, I’m going to write about this out-of-order, since the London experience is still fresh and ongoing. I’ll definitely also write about last week, though!

I arrived here on Monday evening, having taken the train from Haarlem, via Rotterdam and Brussels, to London’s St. Pancras station.
I spent most of the train ride working on a TDD exercise I’ve come up with, in which I try to test-drive to an algorithm to solve a little puzzle game my kids have. I’ve never been very good algorithmically (or any-rythmicly, really), so if I manage to create a working program that actually solves the puzzle that’s a very strong argument for TDD:-) My first try ended in a mess, so I took Ron and Chet their advice, and threw that away to start over. It’s looking better now, but I’ll post more about this if/when I end up with a working solution (or simply give up completely).

Joe Justice and WikiSpeed
After checking into the Hotel, and getting some sleep, the next day started quite spectacularly with a keynote by Joe Justice from wikispeed who gave a talk on how he and his team used Agile methods to guide the work on creating a super fuel efficent car with a team of volunteers from all over the world.

Joe’s talk touched on classical auto development methods, and how much time they take. He then pits that against the performance of his team, which created the first version of their car in only three months time! The car had a fuel consumption of less than 100mpg, while up to that point it wasn’t even certain that that would be possible.
He talked about the way the team uses familiar concepts from Scrum/Agile to create a close knit team and get things done quickly, improving all the while. They use concepts such as working test-driven, pairing, and whole-team work to keep the project running at high speed even though it is based on very-part-time volunteers, distributed over the whole world.

What was even more impressive to me was the use of OO like ideas in taking the modularity and decoupling of the car’s components to extremes. Unfortunately, the talks here are not being taped, but you can see Joe talking about this in this five minute video from youtube:

The keynote ended with a driven call to action for people to start projects such as the WikiSpeed car in other areas that can make the world a better place. True to character, this was accompanied by the offer to help out in setting up such efforts under the WikiSpeed name.

How To Change The World – Jurgen Appelo

Next was Jurgen Appelo, author of the book Management 3.0. His book deal with applying knowledge and concepts from complexity theory to managing software teams. It’s both interesting and entertaining, so I highly recommend it for anyone working in a management role in software development.
This talk referenced some of the ideas and models from the book, but applies them to the area of change management. Jurgen freely admits not originating these ideas, but he does combine them in a nicely integrated meta-model. Also, he annotates that meta model with a series of questions that guide in applying the model, which was the part I though most useful in this talk. His slide-set and a separate document listing those questions can be found on his website. I think most people involved in efforts to change their organisation will be helped by reading those questions, or at very least humbled by all the things that they didn’t do to effect that change… (I was)

Jamie Dobson on The Rise of Corruption on Software Projects

Jamie‘s talk suffered from a bit of confusion, as time and place had change a couple of time. I’ve been to his talks before, and he can usually trigger some nice discussion, framing software development issues in interesting history lessons. For instance, did you know that in early contact with Tahiti, the sailors traded a nail against sexual favours of the native women? All part of an interesting lesson in economics!

Because of the confusion, not many people turned up for the talk, but in the end there were five of us, including Jamie. We still managed to get a nice discussion going, and I must admit that it was a nice bonus to be talking with James Grenning there. As it was mostly discussion, it’s hard to give a good overview of this talk. Jamie’s posted his preparatory notes on his website, but the gist of his point was (in my interpretation) that different incentives will always mean that there’s a measure of corruption. The discussion was on whether that was something we can see in the Agile community (yes, CSM training was mentioned), and whether there are ways to avoid that (IMO: not really, and mostly the good outweighs the bad). Plenty to talk about, very enjoyable, but hard to reflect here. You should have been there:-)

Steve Denning on Mastering the Basics of Leadership Storytelling

Next for me was this workshop by Steve Denning. I read his book on Radical Management last year, and was looking forward to hearing him talk on that. But that’s day 2, where he gave a keynote on that subject.
This was about his other book, on Leadership Storytelling


In this workshop, Steve told us how he came to appreciate the power of storytelling to get a point (or an organisational change) across, and what the best way to craft a story is. He also gave us a number of exercises to practice, for instance one where you describe the reasons someone opposed to a change has in different forms: He…, I…, You… A very powerful exercise, because to do that, you have to actually take the other’s point of view. I happened to be in the same group as Joe Justice, who I talked about above.

Boat ride

After the sessions, we gathered to take a ride on the Dixie Queen on the Thames, on which we also had food, drinks, and a lot of talk. All in all a great day. I’ll talk about the second day of the conference later!

A Cucumber Experiment

Having used the GildedRose recently as the subject of a coding dojo, I thought it would also make an interesting subject for some experimentation with Cucumber. Cucumber is a tool that allows you to use natural language to specify executable Acceptance Tests. The GildedRose exercise, originally created by Bobby Johnson, can be found on github, in both C# (the original), and Java (my copy). This code kata is a refactoring assignment, where the requirements are given together with a piece of existing code and the programmer is expected to add some functionality. If you take one look at that existing code, though, you’ll see that you really need to clean it up before adding that extra feature:

    public static void updateQuality()
    {
        for (int i = 0; i < items.size(); i++)
        {
            if ((!"Aged Brie".equals(items.get(i).getName())) && !"Backstage passes to a TAFKAL80ETC concert".equals(items.get(i).getName()))
            {
                if (items.get(i).getQuality() > 0)
                {
                    if (!"Sulfuras, Hand of Ragnaros".equals(items.get(i).getName()))
                    {
                        items.get(i).setQuality(items.get(i).getQuality() - 1);
                    }
                }
            }
            else
            {
                if (items.get(i).getQuality() < 50)
                {
                    items.get(i).setQuality(items.get(i).getQuality() + 1);

                    if ("Backstage passes to a TAFKAL80ETC concert".equals(items.get(i).getName()))
                    {
                        if (items.get(i).getSellIn() < 11)
                        {
                            if (items.get(i).getQuality() < 50)
                            {
                                items.get(i).setQuality(items.get(i).getQuality() + 1);
                            }
                        }

                        if (items.get(i).getSellIn() < 6)
                        {
                            if (items.get(i).getQuality() < 50)
                            {
                                items.get(i).setQuality(items.get(i).getQuality() + 1);
                            }
                        }
                    }
                }
            }

            if (!"Sulfuras, Hand of Ragnaros".equals(items.get(i).getName()))
            {
                items.get(i).setSellIn(items.get(i).getSellIn() - 1);
            }

            if (items.get(i).getSellIn() < 0)
            {
                if (!"Aged Brie".equals(items.get(i).getName()))
                {
                    if (!"Backstage passes to a TAFKAL80ETC concert".equals(items.get(i).getName()))
                    {
                        if (items.get(i).getQuality() > 0)
                        {
                            if (!"Sulfuras, Hand of Ragnaros".equals(items.get(i).getName()))
                            {
                                items.get(i).setQuality(items.get(i).getQuality() - 1);
                            }
                        }
                    }
                    else
                    {
                        items.get(i).setQuality(items.get(i).getQuality() - items.get(i).getQuality());
                    }
                }
                else
                {
                    if (items.get(i).getQuality() < 50)
                    {
                        items.get(i).setQuality(items.get(i).getQuality() + 1);
                    }
                }
            }
        }
    }

Having gone through the exercise a few times, I already had a version lying around that had the requirements implemented as a bunch of junit regression tests, and some real unit tests for my implementation, of course. A good starting point to get going with Cuke, though in many real-life situations I’ve found that those regression tests are not available…

Adding Cucumber to the maven build

To prepare for the use of Cucumber, I first had to set it up so that I had all the dependencies for cucumber, and have it run in the maven integration-test phase. The complete Maven pom.xml is also on GitHub.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>GildedRoseJava</groupId>
    <artifactId>GildedRoseJava</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.2</version>
            <type>jar</type>
            <scope>test</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.picocontainer</groupId>
            <artifactId>picocontainer</artifactId>
            <version>2.10.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>cuke4duke</groupId>
            <artifactId>cuke4duke</artifactId>
            <version>0.4.4</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <repositories>
        <repository>
            <id>codehaus</id>
            <url>http://repository.codehaus.org</url>
        </repository>
        <repository>
            <id>cukes</id>
            <url>http://cukes.info/maven</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>cukes</id>
            <url>http://cukes.info/maven</url>
        </pluginRepository>
    </pluginRepositories>
    <build>
        <plugins>
            <plugin>
                <groupId>cuke4duke</groupId>
                <artifactId>cuke4duke-maven-plugin</artifactId>
                <configuration>
                    <jvmArgs>
                        <jvmArg>
                            -Dcuke4duke.objectFactory=cuke4duke.internal.jvmclass.PicoFactory
                        </jvmArg>
                        <jvmArg>-Dfile.encoding=UTF-8</jvmArg>
                    </jvmArgs>
                    <!-- You may not need all of these arguments in your
          own project. We have a lot here for testing purposes... -->
                    <cucumberArgs>
                        <cucumberArg>--backtrace</cucumberArg>
                        <cucumberArg>--color</cucumberArg>
                        <cucumberArg>--verbose</cucumberArg>
                        <cucumberArg>--format</cucumberArg>
                        <cucumberArg>pretty</cucumberArg>
                        <cucumberArg>--format</cucumberArg>
                        <cucumberArg>junit</cucumberArg>
                        <cucumberArg>--out</cucumberArg>
                        <cucumberArg>${project.build.directory}/cucumber-reports</cucumberArg>
                        <cucumberArg>--require</cucumberArg>
                        <cucumberArg>${basedir}/target/test-classes</cucumberArg>
                    </cucumberArgs>
                    <gems>
                        <gem>install cuke4duke --version 0.3.2</gem>
                    </gems>
                </configuration>
                <executions>
                    <execution>
                        <id>run-features</id>
                        <phase>integration-test</phase>
                        <goals>
                            <goal>cucumber</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Adding a Feature

To start with cucumber, you create a feature file that contains a Feature, which is expected to be in the User Story schema, and contains all the Acceptance Tests for that story in the Gherkin format.

The feature file is placed in the {$project.root}/features directory. The Story looks as follows:

Feature: Quality changes with sell-in date Feature
         In order to keep track of quality of items in stock
         As a ShopKeeper
         I want quality to change as the sell-in date decreases

A Scenario

This doesn’t do anything, until you start adding some scenarios, which can be seen as the acceptance criteria for the story/feature. For now, if you do

mvn integration-test

you’ll get confirmation that Cucumber has found your feature, and that there were no test scenarios to run:

[INFO] Code:
[INFO]
[INFO] Features:
[INFO]   * features/quality_decrease.feature
[INFO] Parsing feature files took 0m0.111s
[INFO]
[INFO] Code:
[INFO]   * /home/wouter/data/eclipse/kata/GildedRoseGitHub/target/test-classes/org/geenz/gildedrose/BackstagePassStoreKeepingItemTest.class
[INFO]   * /home/wouter/data/eclipse/kata/GildedRoseGitHub/target/test-classes/org/geenz/gildedrose/GildedRoseRegressionTest.class
[INFO]   * /home/wouter/data/eclipse/kata/GildedRoseGitHub/target/test-classes/org/geenz/gildedrose/GildedRoseTest.class
[INFO]   * /home/wouter/data/eclipse/kata/GildedRoseGitHub/target/test-classes/org/geenz/gildedrose/ImmutableItemTest.class
[INFO]   * /home/wouter/data/eclipse/kata/GildedRoseGitHub/target/test-classes/org/geenz/gildedrose/ItemFactoryTest.class
[INFO]   * /home/wouter/data/eclipse/kata/GildedRoseGitHub/target/test-classes/org/geenz/gildedrose/StoreKeepingItemTest.class
[INFO]   * /home/wouter/data/eclipse/kata/GildedRoseGitHub/target/test-classes/org/geenz/gildedrose/cucumber/BasicFeature.class
[INFO]
[INFO] Feature: Quality changes with sell-in date Feature
[INFO]   In order to keep track of quality of items in stock
[INFO]   As a ShopKeeper
[INFO]   I want quality to change as the sell-in date decreases
[INFO]
[INFO] 0 scenarios
[INFO] 0 steps
[INFO] 0m0.062s

Now, let’s add a scenario, let’s say a scenario for the basic situation of quality decreasing by one if the sell-in date decreases by one:

Feature: Quality changes with sell-in date Feature
        In order to keep track of quality of items in stock
        As a ShopKeeper
        I want quality to change as the sell-in date decreases

        Scenario: Decreasing Quality of a Basic Item
                Given a Store Keeping Item with name "+5 Dexterity Vest"
                And a sellIn date of 5
                And a quality of 7
                When the Item is updated
                Then the sellIn is 4
                And the quality is 6

There’s a few things to notice here. First of all, this is readable. This scenario can be read by people that have no programming experience, and understood well if they have some knowledge of the domain of the application. That means that scenarios like this one can be used to talk about the requirements/expected behaviour of the application. Second is that this is a Real Life example of the workings of the application. Making it a specific example, instead of a generic rule, makes the scenario easier to understand, and thus more useful as a communication device.

Glue

So what happens when we try to run the integration-test phase again? Will we magically see this scenario work? Well, no, there’s still some glue to provide, but we do get some help with that:

[INFO] Code:
[INFO]
[INFO] Features:
[INFO]   * features/quality_decrease.feature
[INFO] Parsing feature files took 0m0.077s
[INFO]
[INFO] Code:
[INFO]   * /home/wouter/data/eclipse/kata/GildedRoseGitHub/target/test-classes/org/geenz/gildedrose/BackstagePassStoreKeepingItemTest.class
[INFO]   * /home/wouter/data/eclipse/kata/GildedRoseGitHub/target/test-classes/org/geenz/gildedrose/GildedRoseRegressionTest.class
[INFO]   * /home/wouter/data/eclipse/kata/GildedRoseGitHub/target/test-classes/org/geenz/gildedrose/GildedRoseTest.class
[INFO]   * /home/wouter/data/eclipse/kata/GildedRoseGitHub/target/test-classes/org/geenz/gildedrose/ImmutableItemTest.class
[INFO]   * /home/wouter/data/eclipse/kata/GildedRoseGitHub/target/test-classes/org/geenz/gildedrose/ItemFactoryTest.class
[INFO]   * /home/wouter/data/eclipse/kata/GildedRoseGitHub/target/test-classes/org/geenz/gildedrose/StoreKeepingItemTest.class
[INFO]   * /home/wouter/data/eclipse/kata/GildedRoseGitHub/target/test-classes/org/geenz/gildedrose/cucumber/BasicFeature.class
[INFO]
[INFO] Feature: Quality changes with sell-in date Feature
[INFO]   In order to keep track of quality of items in stock
[INFO]   As a ShopKeeper
[INFO]   I want quality to change as the sell-in date decreases
[INFO]
[INFO]   Scenario: Decreasing Quality of a Basic Item               # features/quality_decrease.feature:6
[INFO]     Given a Store Keeping Item with name "+5 Dexterity Vest" # features/quality_decrease.feature:7
[INFO]     And a sellIn date of 5                                   # features/quality_decrease.feature:8
[INFO]     And a quality of 7                                       # features/quality_decrease.feature:9
[INFO]     When the Item is updated                                 # features/quality_decrease.feature:10
[INFO]     Then the sellIn is 4                                     # features/quality_decrease.feature:11
[INFO]     And the quality is 6                                     # features/quality_decrease.feature:12
[INFO]
[INFO] 1 scenario (1 undefined)
[INFO] 6 steps (6 undefined)
[INFO] 0m0.221s
[INFO]
[INFO] You can implement step definitions for undefined steps with these snippets:
[INFO]
[INFO] @Given ("^a Store Keeping Item with name \"([^\"]*)\"$")
[INFO] @Pending
[INFO] public void aStoreKeepingItemWithName+5DexterityVest_(String arg1) {
[INFO] }
[INFO]
[INFO] @Given ("^a sellIn date of 5$")
[INFO] @Pending
[INFO] public void aSellInDateOf5() {
[INFO] }
[INFO]
[INFO] @Given ("^a quality of 7$")
[INFO] @Pending
[INFO] public void aQualityOf7() {
[INFO] }
[INFO]
[INFO] @When ("^the Item is updated$")
[INFO] @Pending
[INFO] public void theItemIsUpdated() {
[INFO] }
[INFO]
[INFO] @Then ("^the sellIn is 4$")
[INFO] @Pending
[INFO] public void theSellInIs4() {
[INFO] }
[INFO]
[INFO] @Then ("^the quality is 6$")
[INFO] @Pending
[INFO] public void theQualityIs6() {
[INFO] }
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9.500s
[INFO] Finished at: Fri Sep 16 14:27:29 CEST 2011
[INFO] Final Memory: 5M/106M
[INFO] ------------------------------------------------------------------------

Ok! The build is successful, the new scenario is found, but apparently ‘undefined’, and there’s a load of javacode dumped! Things are moving along…

We copy-past-clean-up the java code into a test class, such as this:

package org.geenz.gildedrose.cucumber;

import cuke4duke.annotation.I18n.EN.Given;
import cuke4duke.annotation.I18n.EN.Then;
import cuke4duke.annotation.I18n.EN.When;
import cuke4duke.annotation.Pending;
import org.geenz.gildedrose.ItemFactory;
import org.geenz.gildedrose.StoreKeepingItem;

import static org.junit.Assert.*;

public class BasicFeature {

	 @Given ("^a Store Keeping Item with name \"([^\"]*)\"$")
	 @Pending
	 public void aStoreKeepingItemWithName+5DexterityVest_(String arg1) {
	 }

	 @Given ("^a sellIn date of 5$")
	 @Pending
	 public void aSellInDateOf5() {
	 }

	 @Given ("^a quality of 7$")
	 @Pending
	 public void aQualityOf7() {
	 }

	 @When ("^the Item is updated$")
	 @Pending
	 public void theItemIsUpdated() {
	 }

	 @Then ("^the sellIn is 4$")
	 @Pending
	 public void theSellInIs4() {
	 }

	 @Then ("^the quality is 6$")
	 @Pending
	 public void theQualityIs6() {
	 }
}

Pending

And, after noticing and correcting that a ‘+’ sign can’t be part of a Java method name, we run it again, Sam.

Oh dear:

[INFO] Feature: Quality changes with sell-in date Feature
[INFO] In order to keep track of quality of items in stock
[INFO] As a ShopKeeper
[INFO] I want quality to change as the sell-in date decreases
[INFO]
[INFO] Scenario: Decreasing Quality of a Basic Item # features/quality_decrease.feature:6
[INFO] Given a Store Keeping Item with name "+5 Dexterity Vest" # BasicFeature.aStoreKeepingItemWithNamePlus5DexterityVest_(String)
[INFO] TODO (Cucumber::Pending)
[INFO] /home/wouter/.m2/repository/.jruby/gems/cucumber-0.8.7/lib/cucumber/step_match.rb:26:in `invoke'
[INFO] /home/wouter/.m2/repository/.jruby/gems/cucumber-0.8.7/lib/cucumber/ast/step_invocation.rb:62:in `invoke'
[INFO] /home/wouter/.m2/repository/.jruby/gems/cucumber-0.8.7/lib/cucumber/ast/step_invocation.rb:41:in `accept'
[INFO] /home/wouter/.m2/repository/.jruby/gems/cucumber-0.8.7/lib/cucumber/ast/tree_walker.rb:99:in `visit_step'
[INFO] /home/wouter/.m2/repository/.jruby/gems/cucumber-0.8.7/lib/cucumber/ast/tree_walker.rb:164:in `broadcast'
[INFO] /home/wouter/.m2/repository/.jruby/gems/cucumber-0.8.7/lib/cucumber/ast/tree_walker.rb:98:in `visit_step'
[INFO] /home/wouter/.m2/repository/.jruby/gems/cucumber-0.8.7/lib/cucumber/ast/step_collection.rb:15:in `accept'
[IN
.....

Just what a Java developer likes: Ruby stackstraces! Luckily, the first entry is fairly clear: TODO (Cucumber::Pending).
And indeed, now that we take another look at it, the methods we just created all have a @Pending annotation. If we remove that, the scenario ‘runs’ successfully:

[INFO] Feature: Quality changes with sell-in date Feature
[INFO]   In order to keep track of quality of items in stock
[INFO]   As a ShopKeeper
[INFO]   I want quality to change as the sell-in date decreases
[INFO]
[INFO]   Scenario: Decreasing Quality of a Basic Item               # features/quality_decrease.feature:6
[INFO]     Given a Store Keeping Item with name "+5 Dexterity Vest" # BasicFeature.aStoreKeepingItemWithNamePlus5DexterityVest_(String)
[INFO]     And a sellIn date of 5                                   # BasicFeature.aSellInDateOf5()
[INFO]     And a quality of 7                                       # BasicFeature.aQualityOf7()
[INFO]     When the Item is updated                                 # BasicFeature.theItemIsUpdated()
[INFO]     Then the sellIn is 4                                     # BasicFeature.theSellInIs4()
[INFO]     And the quality is 6                                     # BasicFeature.theQualityIs6()
[INFO]
[INFO] 1 scenario (1 passed)
[INFO] 6 steps (6 passed)
[INFO] 0m0.269s

Adding code

Of course, it doesn’t actually test anything yet! But we can take a look at the way the text of the scenario is translated into executable code. For instance:

	 @Given ("^a sellIn date of 5$")
	 public void aSellInDateOf5() {
	 }

This looks straightforward. The @Given annotation gets a regular expression passed to it, which matches a particular condition. If the method actually set a sell-in value on some object, this would be a perfectly valid step in performing some test.

So let’s see where we can create such a sellable item. This other method looks promising:

	 @Given ("^a Store Keeping Item with name \"([^\"]*)\"$")
	 public void aStoreKeepingItemWithNamePlus5DexterityVest_(String arg1) {
	 }

For the non-initiated into the esoteric realm of regular expressions, the regexp here looks a little more scary. It really isn’t all that bad, though. The backslashes (\) are there to escape out the quotes (“). The brackets (()) are there to capture a specific region to be passed into the method: anything within those brackets is passed in as the first parameter of the method (out arg1 String parameter). And to specify what we want to capture, the [^\”]* simply means any character that is not a quote. So this captures everything within the quotes in our scenario, which happens to be the name of the item.

So let’s change that into:

    private StoreKeepingItem item = null;

    @Given ("^a Store Keeping Item with name \"([^\"]*)\"$")
    public void aStoreKeepingItemWithName(String name) {
        item = ItemFactory.create(name, 0, 0);
    }

Now our first line will create a new Item, with the correct name! That was easy!
Now we can fix the earlier method:

	 @Given ("^a sellIn date of 5$")
	 public void aSellInDateOf5() {
             item.setSellIn(5);
	 }

But, since I now already know how to parameterise these annotations, let’s doe that immediately:

    @Given("^a sellIn date of ([0-9]*)$")
    public void aSellInDateOf(int sellIn) {
        item.setSellIn(sellIn);
    }

Much better. Now let’s imagine we’ve done this for the rest as well (click to see):

package org.geenz.gildedrose.cucumber;

import cuke4duke.annotation.I18n.EN.Given;
import cuke4duke.annotation.I18n.EN.Then;
import cuke4duke.annotation.I18n.EN.When;
import cuke4duke.annotation.Pending;
import org.geenz.gildedrose.ItemFactory;
import org.geenz.gildedrose.StoreKeepingItem;

import static org.junit.Assert.*;

public class BasicFeature {

    private StoreKeepingItem item = null;

    @Given ("^a Store Keeping Item with name \"([^\"]*)\"$")
    public void aStoreKeepingItemWithName(String name) {
        item = ItemFactory.create(name, 0, 0);
    }

    @Given("^a sellIn date of ([0-9]*)$")
    public void aSellInDateOf(int sellIn) {
        item.setSellIn(sellIn);
    }

    @Given("^a quality of ([0-9]*)$")
    public void aQualityOf(int quality) {
        item.setQuality(quality);
    }

    @When("^the Item is updated$")
    public void theItemIsUpdated() {
        item.doDailyInventoryUpdate();
    }

    @Then("^the sellIn is (.*)$")
    public void theSellInIs(int expectedSellIn) {
        assertEquals(expectedSellIn, item.getSellIn());
    }

    @Then("^the quality is ([0-9]*)$")
    public void theQualityIs(int expectedQuality) {
        assertEquals(expectedQuality, item.getQuality());
    }
}

The test still passes, so this seems to work! For the rest of the scenarios, see the checked-in feature file on GitHub. Take a look at that file, and compare it to the README. Which one is clearer to you? Do they both contain all the information you need?

The odd one out

Note that there is one scenario there that is not covered by the methods that we have, so once you try to run this particular scenario, things fall apart:

        Scenario: Quality and SellIn of a Sulfuras item does not change
                Given a Store Keeping Item with name "Sulfuras, Hand of Ragnaros" with a sellIn date of 5, a quality of 7
                When the Item is updated
                Then the sellIn is 5
                And the quality is 7

Since this item is supposed to be immutable, I can’t really go and set the sellIn or quality after it’s been created. So I made a separate method to pass-in the sell-in and quality at initialisation time:

    /**
     * Separate when clause to indicate initial state, since some items can't be changed after initial creation.
     */
    @Given ("^a Store Keeping Item with name \"([^\"]*)\" with a sellIn date of ([0-9]*), a quality of ([0-9]*)$")
    public void aStoreKeepingItemWithNameAndSellInDateAndQualityOf(String name, int sellIn, int quality) {
        item = ItemFactory.create(name, sellIn, quality);

There could be a nicer way to do this, either by creating all items in this way, or by changing the way the immutable items work, but this was easy enough to do that I didn’t look any further.

So when we run all the scenarios, we get:

[INFO] Feature: Quality changes with sell-in date Feature
[INFO]   In order to keep track of quality of items in stock
[INFO]   As a ShopKeeper
[INFO]   I want quality to change as the sell-in date decreases
[INFO]
[INFO]   Scenario: Decreasing Quality of a Basic Item               # features/basic.feature:6
[INFO]     Given a Store Keeping Item with name "+5 Dexterity Vest" # BasicFeature.aStoreKeepingItemWithName(String)
[INFO]     And a sellIn date of 5                                   # BasicFeature.aSellInDateOf(int)
[INFO]     And a quality of 7                                       # BasicFeature.aQualityOf(int)
[INFO]     When the Item is updated                                 # BasicFeature.theItemIsUpdated()
[INFO]     Then the sellIn is 4                                     # BasicFeature.theSellInIs(int)
[INFO]     And the quality is 6                                     # BasicFeature.theQualityIs(int)
[INFO]
[INFO]   Scenario: Quality decrease doubles after sell-in has passed # features/basic.feature:14
[INFO]     Given a Store Keeping Item with name "+5 Dexterity Vest"  # BasicFeature.aStoreKeepingItemWithName(String)
[INFO]     And a sellIn date of 0                                    # BasicFeature.aSellInDateOf(int)
[INFO]     And a quality of 10                                       # BasicFeature.aQualityOf(int)
[INFO]     When the Item is updated                                  # BasicFeature.theItemIsUpdated()
[INFO]     Then the sellIn is -1                                     # BasicFeature.theSellInIs(int)
[INFO]     And the quality is 8                                      # BasicFeature.theQualityIs(int)
[INFO]
[INFO]   Scenario: Quality never becomes negative                   # features/basic.feature:22
[INFO]     Given a Store Keeping Item with name "+5 Dexterity Vest" # BasicFeature.aStoreKeepingItemWithName(String)
[INFO]     And a sellIn date of 0                                   # BasicFeature.aSellInDateOf(int)
[INFO]     And a quality of 0                                       # BasicFeature.aQualityOf(int)
[INFO]     When the Item is updated                                 # BasicFeature.theItemIsUpdated()
[INFO]     Then the sellIn is -1                                    # BasicFeature.theSellInIs(int)
[INFO]     And the quality is 0                                     # BasicFeature.theQualityIs(int)
[INFO]
[INFO]   Scenario: Quality of Aged Brie increases with age  # features/basic.feature:30
[INFO]     Given a Store Keeping Item with name "Aged Brie" # BasicFeature.aStoreKeepingItemWithName(String)
[INFO]     And a sellIn date of 5                           # BasicFeature.aSellInDateOf(int)
[INFO]     And a quality of 1                               # BasicFeature.aQualityOf(int)
[INFO]     When the Item is updated                         # BasicFeature.theItemIsUpdated()
[INFO]     Then the sellIn is 4                             # BasicFeature.theSellInIs(int)
[INFO]     And the quality is 2                             # BasicFeature.theQualityIs(int)
[INFO]
[INFO]   Scenario: Quality of Aged Brie never increases past 50 # features/basic.feature:38
[INFO]     Given a Store Keeping Item with name "Aged Brie"     # BasicFeature.aStoreKeepingItemWithName(String)
[INFO]     And a sellIn date of 5                               # BasicFeature.aSellInDateOf(int)
[INFO]     And a quality of 50                                  # BasicFeature.aQualityOf(int)
[INFO]     When the Item is updated                             # BasicFeature.theItemIsUpdated()
[INFO]     Then the sellIn is 4                                 # BasicFeature.theSellInIs(int)
[INFO]     And the quality is 50                                # BasicFeature.theQualityIs(int)
[INFO]
[INFO]   Scenario: Quality of Backstage Passes increases by 1 if sell-in is greater than 10 # features/basic.feature:46
[INFO]     Given a Store Keeping Item with name "Backstage passes to a TAFKAL80ETC concert" # BasicFeature.aStoreKeepingItemWithName(String)
[INFO]     And a sellIn date of 11                                                          # BasicFeature.aSellInDateOf(int)
[INFO]     And a quality of 20                                                              # BasicFeature.aQualityOf(int)
[INFO]     When the Item is updated                                                         # BasicFeature.theItemIsUpdated()
[INFO]     Then the quality is 21                                                           # BasicFeature.theQualityIs(int)
[INFO]
[INFO]   Scenario: Quality of Backstage Passes increases by 2 if sell-in is less than 10 but more than 5 # features/basic.feature:53
[INFO]     Given a Store Keeping Item with name "Backstage passes to a TAFKAL80ETC concert"              # BasicFeature.aStoreKeepingItemWithName(String)
[INFO]     And a sellIn date of 6                                                                        # BasicFeature.aSellInDateOf(int)
[INFO]     And a quality of 20                                                                           # BasicFeature.aQualityOf(int)
[INFO]     When the Item is updated                                                                      # BasicFeature.theItemIsUpdated()
[INFO]     Then the quality is 22                                                                        # BasicFeature.theQualityIs(int)
[INFO]
[INFO]   Scenario: Quality of Backstage Passes increases by 3 if sell-in is 5 or less but more than 0 # features/basic.feature:60
[INFO]     Given a Store Keeping Item with name "Backstage passes to a TAFKAL80ETC concert"           # BasicFeature.aStoreKeepingItemWithName(String)
[INFO]     And a sellIn date of 5                                                                     # BasicFeature.aSellInDateOf(int)
[INFO]     And a quality of 20                                                                        # BasicFeature.aQualityOf(int)
[INFO]     When the Item is updated                                                                   # BasicFeature.theItemIsUpdated()
[INFO]     Then the quality is 23                                                                     # BasicFeature.theQualityIs(int)
[INFO]
[INFO]   Scenario: Quality of Backstage Passes is 0 after the concert (sell-in) passes      # features/basic.feature:67
[INFO]     Given a Store Keeping Item with name "Backstage passes to a TAFKAL80ETC concert" # BasicFeature.aStoreKeepingItemWithName(String)
[INFO]     And a sellIn date of 0                                                           # BasicFeature.aSellInDateOf(int)
[INFO]     And a quality of 20                                                              # BasicFeature.aQualityOf(int)
[INFO]     When the Item is updated                                                         # BasicFeature.theItemIsUpdated()
[INFO]     Then the quality is 0                                                            # BasicFeature.theQualityIs(int)
[INFO]
[INFO]   Scenario: Quality and SellIn of a Sulfuras item does not change                                             # features/basic.feature:74
[INFO]     Given a Store Keeping Item with name "Sulfuras, Hand of Ragnaros" with a sellIn date of 5, a quality of 7 # BasicFeature.aStoreKeepingItemWithNameAndSellInDateAndQualityOf(String,int,int)
[INFO]     When the Item is updated                                                                                  # BasicFeature.theItemIsUpdated()
[INFO]     Then the sellIn is 5                                                                                      # BasicFeature.theSellInIs(int)
[INFO]     And the quality is 7                                                                                      # BasicFeature.theQualityIs(int)
[INFO]
[INFO]   Scenario: Quality of Conjured items goes down twice as fast as a normal item before sell-in # features/basic.feature:80
[INFO]     Given a Store Keeping Item with name "Conjured Mana Cake"                                 # BasicFeature.aStoreKeepingItemWithName(String)
[INFO]     And a sellIn date of 5                                                                    # BasicFeature.aSellInDateOf(int)
[INFO]     And a quality of 20                                                                       # BasicFeature.aQualityOf(int)
[INFO]     When the Item is updated                                                                  # BasicFeature.theItemIsUpdated()
[INFO]     Then the quality is 18                                                                    # BasicFeature.theQualityIs(int)
[INFO]
[INFO]   Scenario: Quality of Conjured items goes down twice as fast as a normal item after sell-in # features/basic.feature:87
[INFO]     Given a Store Keeping Item with name "Conjured Mana Cake"                                # BasicFeature.aStoreKeepingItemWithName(String)
[INFO]     And a sellIn date of 0                                                                   # BasicFeature.aSellInDateOf(int)
[INFO]     And a quality of 20                                                                      # BasicFeature.aQualityOf(int)
[INFO]     When the Item is updated                                                                 # BasicFeature.theItemIsUpdated()
[INFO]     Then the quality is 16                                                                   # BasicFeature.theQualityIs(int)
[INFO]
[INFO] 12 scenarios (12 passed)
[INFO] 64 steps (64 passed)
[INFO] 0m1.617s
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10.861s
[INFO] Finished at: Fri Sep 16 15:57:23 CEST 2011
[INFO] Final Memory: 5M/106M
[INFO] ------------------------------------------------------------------------

So now we have a full set of acceptance tests, covering the whole of the requirements, and with only very limited amount of code needed. Of course, the small amount of code needed is for a large part because I already refactored the original to something more managable. I would be a nice next experiment to start with these scenarios, and grow the code from there. If you do this, let me know, and send a pull request!

Parameterization

For some type of tests, it makes sense to have a scenario where you put in different types of data, and expect different results. By separating the scenario from the input and output data, you can make thes kind of tests much more readable. In the case of our example, you can find the same tests in the parameterised.feature file, but it’s small enough to simply include here:

Feature: Quality changes with sell-in date Feature
        In order to keep track of quality of items in stock
        As a ShopKeeper
        I want quality to change as the sell-in date decreases

        Scenario Outline: Changing Quality of an Item
                Given a Store Keeping Item with name "<item name>"
                And a sellIn date of <sell in>
                And a quality of <quality>
                When the Item is updated
                Then the sellIn is <expected sell in>
                And the quality is <expected quality>

		Examples:
		| item name			| sell in	| quality	| expected sell in	| expected quality	|
		| +5 Dexterity Vest	| 5			| 7			| 4					| 6					|
		| +5 Dexterity Vest	| 0			| 10		| -1				| 8					|
		| +5 Dexterity Vest	| 0			| 0			| -1				| 0					|
		| Aged Brie			| 5			| 1			| 4					| 2					|
		| Aged Brie			| 5			| 50		| 4					| 50				|
		| Backstage passes to a TAFKAL80ETC concert	| 11 | 20 | 10		| 21				|
		| Backstage passes to a TAFKAL80ETC concert	| 6  | 20 | 5		| 22				|
		| Backstage passes to a TAFKAL80ETC concert	| 5  | 20 | 4		| 23				|
		| Backstage passes to a TAFKAL80ETC concert	| 0  | 20 | -1		| 0					|
		| Conjured Mana Cake| 5			| 20		| 4					| 18				|
		| Conjured Mana Cake| 0			| 20		| -1				| 16				|

As you can see, this is much shorter. It does skip on the detailed text for each scenario, though, which I thought to be somewhat of a loss in this particular case. For tests with larger sets of data, this is probably a great feature, though. For this example I though the feature was clearer with the more verbose scenarios.

If you want to know more, a great resource is the cuke4ninja free on-line book. The Cucumber wiki, and additional tutorials list are also great sources of knowledge.

Adventures in Rework

I came across this post by Martin Fowler, on the Strangler Application pattern, and its accompanying paper. This brought back memories of some of my own adventures in rework, some fond, others not so much. In all cases, though, I think they were very valuable lessons on what to do and not to do when reworking existing systems. No reason not to share those lessons, especially as some of them were rather painful and expensive to learn. The paper linked above is a success story, mine are more the kind you tell your children about to keep them away from dysfunctional projects. This is not because these projects were done by horrible or incompetent people, or completely ineffective organisations. They weren’t. But sometimes a few bad decisions can stack up, and result into the kind of war stories developers share after a few beers.

I’ll wait here until you’re back from the fridge.

When talking about rework, note that I’m not calling them ‘legacy systems’, as you’ll see that in a few of these cases the ‘legacy’ system wasn’t even finished yet before the rework began.

‘Rework’ is simply a name for rebuilding existing functionality. It is distinct from Refactoring in that it is usually not changing existing code, but replacing it. Another distinction is one of scope. Refactoring is characterised by small steps of improvement, while Rework is about replacing a large part of (or an entire) system. Or in simpler terms:

Rework = bad, Refactoring = good

One problem is that very often people talk about refactoring when they mean rework, giving the good practice of refactoring a bad name. When a developer or architect says ‘We need to do some refactoring on the system, we think it will take 4 weeks of work for the team’, what they are talking about is rework. Not surprisingly, many managers now treat refactoring as a dirty word…

When do you do rework?

Rework is not always bad. There can be good reasons to invest in re-implementation. Usually, maintainability and extensibility are part of those reasons, at least on the technical side. This is the type of rework that is similar to refactoring, in that there is no functional change. This means that this is work that does not give any direct business value. From the point of view of the customer, or the company, this means that these kind of changes are ‘cost’ only.

Rework can also be triggered by changes in requirements. These might be functional requirements, where new functionality can’t easily be fitted in the current system. Usually, though, these are non-functionals. Such as: we need better scalability, but the platform we’re using doesn’t support that. Or: We need to provide the same functionality, but now as a desktop application instead of a web-application (or vice versa).

Rework is also sometimes triggered by policy, such as “we’re moving all our development over to…”. And then Java, Scala, Ruby, ‘The Cloud’, or whatever you’re feeling enthusiastic about at the moment. This is not a tremendously good reason, but can be a valid one if you see it in the context of, for example: “We’re moving all our development over to Java, since the current COBOL systems are getting to be difficult to maintain, simply because we’re running out of COBOL programmers.’

Adventure number one

This was not the first piece of rework I was involved with, but a good example of the importance of always continuing to deliver value, and keeping up trust between different parties in an organisation. No names, to protect the innocent. And even though I certainly have opinions on which choices were good and which were not, this is not about assigning blame. The whole thing is, as always, the result of the complete system in which it happens. The only way to avoid them is complete transparency, and the trust hopefully resulting of that.

A project I worked on was an authorisation service for digital content distribution. It could register access rights based on single-sale or subscription periods. This service in the end was completely reworked twice, with another go in the planning. Let’s see what happened, and what we can learn from that.

The service had originally been written in PHP, but was re-created from scratch in Java. I don’t know all the specifics on why this was done, but it involved at least the component of expected better performance, and there was also a company-wide goal of moving to Java for all server-side work. The non-functional requirements and policy from above.

This project was a completely redone system. Everything, including database structures, was created new from scratch. There was a big data-migration, and extensive testing to ensure that the customers wouldn’t suddenly find themselves with missing contents, or subscriptions cut short by years, months or minutes.

Don’t try to change everything at once

A change like that is very difficult to pull off. It’s even more difficult if the original system has a large amount of very specific business-logic in code to handle a myriad of special cases. Moreover, since the reasons for doing rework were completely internally directed, the business side of the company didn’t have much reason to be involved in the project, or understanding of the level of resources that were being expended in it. It did turn out, though, that many of the specific cases were unknown to the business. Quickly growing companies, and all that…

[sidebar: The Business]
I use the term ‘The Business’ in this post regularly. This is intentional. There is a valid argument, made often in the Agile community, that talking about ‘the business’ is an anti-pattern indicating overly separated responsibilities indicative of silo thinking. And I think that in a lot of cases this is true, though sometimes you just need a word…
In this case, there actually was a separation. There were some silos. And the use of the word is accurate.
And I couldn’t think of another term.
[/sidebar]

Anyway, the project was late. Very late. It was already about 9 months late when I first got involved with it. At that point, it was technically a sound system, and was being extensively tested. Too extensively, in a way. You see, the way the original system had so many special cases hard-coded was in direct conflict with the requirement for the new system to be consistent and data-driven. There was no way to make the new implementation data-driven and still get 100% the same results as the old one.

Now, this should not be a problem, as long as the business-impact is clear, and the business side of the organisation is closely enough involved to early-on make clear decisions on what are acceptable deviations from the old system and what are not. A large part of the delays were simply due to that discussion not taking place until very late in the process.

As with all software development, rework needs the customer closely involved

In the end, we did stop trying to work to 100% compliance, and got to sensible agreements about edge-cases. Most of these cases were simply that a certain subset of customers would have a subscription end a few days or weeks later, with negligible business impact. They still caused big delays in the project delivery!

What problems to fix is a business decision

Unfortunately, though the system went live eventually, this was with a year’s delay. It was also too late. On the sales and marketing side, a need had grown to not only register subscriptions for a certain time-period, but also to be able to bill them periodically (monthly payments, for instance). Because the old one hadn’t been able to do this, neither could the new one. And because the new system had been designed to work very similar to the old one, this was not an very straightforward functionality to add.

If you take a long time to make a copy of an existing system, by the time you’re done they’ll want a completely different system

Of course, it was also not a completely impossible thing to add, but we estimated at the time that it would take about three months of work. And that would be *after* the first release of the system, which hadn’t taken place yet. That would bring us to somewhere around October of that year, while the business realities dictated that having this type of new product would have the most impact if released to the public early September.

So what happens to the trust between the development team and the customer by a late release of something that doesn’t give any new functionality to the customer? And if the customer, after not getting any new functionality for a full year, then has a need and hears that he’ll have to wait another 6 months before he can get it? He tells the development team: “You know what? I’ll get someone else to do it!”

Frustrate your customer to your peril!

So the marketing department gets involved in development project management. And they put out a tender to get some offers from different parties. And they pick the cheapest option. And it’s going to be implemented by an external party. With added outsourcing to India! Such a complex project set-up that it *must* work. Meanwhile, the internal development organisation is still trying to complete the original project, and is keeping off getting involved into this follow-up thing.

Falling out within the organisation means falling over of the organisation

Now this new team is working on this new service which is going to be about authorisation and subscriptions. They talk to the business, and start designing a system based on that (this was an old-school waterfall project). Their requirement focus a lot on billing, of course, since that is the major new functionality relative to the existing situation. But they also need to have something to bill, and that means that the system also supports subscriptions without a hard end-date, which are renewed with every new payment. The existing system doesn’t support that, which is a large part of that three months estimation we were talking about.

Now a discussion starts. Some are inclined to add this functionality to the old system, and make the new project about billing and payment tracking. But that would mean waiting for changes in the existing system. So others are pushing to make the new system track the subscription periods. But then we’d have two separate systems, and we’d need to check in both to see if someone is allowed access to a specific product. Worse, since you’d have to be able to switch from pre-paid (existing) to scheduled payments, there would be logic overlapping those two.

Architecture is not politics. Quick! Someone tell Conway!

All valid discussions on the architecture of this change. Somehow, there was an intermediate stage where both existing and new system would keep track of everything, and all data would magically be kept in sync between those two systems, even though they had wildly different domain models about subscriptions. That would have made maintenance… difficult. So the decision was to move everything into the new system, and have the old system only there as a stable interface toward the outside world (ie. a façade talking to the new system through web-services, instead of to its own database).

So here’s a nice example of where *technically* there isn’t much need for rework. There are changes needed, but those are fairly easy to incorporate into an existing architecture. We’re in a hurry, but the company won’t fall over if we are late (even if we do have to delay introducing new payment methods and product types). But the eroded trust levels within the company made the preference to start from scratch, instead of continuing from a working state.

Trust is everything

Now for the observant among you: Yes, some discussion was had about how we had just proven that such a rework project was very complex, and last time took a lot of time to get right. But the estimates of the the external party indicated that the project was feasible. One of the reasons they thought this was that they’d talked mostly to the sales side of the organisation. This is fine, but since they didn’t talk much to the development side, they really had no way of knowing about the existing product base, and its complications and special cases. Rework *should* be easier, but only if you are in a position to learn from the initial work!

If you do rework, try to do it with the involvement of the people who did the original work

It won´t come as a big surprise that this project did not deliver by early September as was originally intended. In fact, it hadn´t delivered by September of the following year. In that time the original external party had been extended and/or replaced (I never quite got that clear) by a whole boatload of other outsourcing companies and consultants. The cost of the project skyrocketed. Data migration was, of course, again very painful (but this time the edge-case decisions were made much earlier!)

A whole new section of problems came from from a poorly understood domain, and no access during development to all of the (internal) clients that were using the service in different ways. This meant that when integration testing started, a number of very low-level decisions on the domain of the new application had to be reconsidered. Some of those were changed, others resulted in work-arounds in all the different clients, since the issues were making a late project later.

Testing should be the *first* thing you start working on in any rework project. Or any project at all.

Meanwhile, my team was still working on the existing (now happily released) system, both maintenance, new features, and the new version that ran against the new system´s web-services. And they were getting worried. Because they could see an army of consultants packing-up and leaving them with the job of keeping the new system running. And when it became clear that the intention was to do a big-bang release, without any way to do a roll-back, we did intervene. One of the developers created a solution to pass all incoming requests to both the old and the new systems, and do extensive logging on the results, including some automated comparisons. Very neat, as it allowed us to keep both systems in sync for a period of time, and see if we ran into any problems.

Always make a roll-back as painless as possible

This made it possible to have the new system in shadow-mode for a while, fix any remaining issues (which meant doing the data-migration another couple of times), and then do the switch painlessly by changing a config setting.

Make roll-back unnecessary by using shadow-running and roll-forward

So in the end we had a successful release. In fact, this whole project was considered by the company to be a great success. In the sense of any landing you can walk away from, this is of course true. For me, it was a valuable lesson, teaching among other things:

  • Haste makes waste (also known as limit WIP)
  • Don´t expect an external supplier to understand your domain, if you don´t really understand it yourself
  • Testing is the difference between a successful project and a failed one
  • When replacing existing code, test against live data
  • Trust is everything

I hope this description was somewhat useful, or at least entertaining in a schadenfreude kind-of way, for someone. It is always preferably to learn from someone else’s mistakes, if you can… I do have other stories of rework, which I´ll make a point of sharing in the future, if anyone is interested.

Reading up: 5 Books To Read If You Want To Really Understand Agile

Last year, I posted an overview of some books every programmer should read. Those still stand, and I find more and more examples where I would like to re-iterate the advice to read those books.

This post is about other books, though. Books related to Agile and Lean principles and practices. There are many books on those subjects, and quite a number of those have become standard-works. I think you’d be hard-pressed to find an Agilist that has not read Agile Estimation and Planning, User Stories Applied, Agile Project Management with Scrum, etc. If you’re lucky, they’ll even know Agile Software Development, Principles, Patterns and Practices.

So those are on all the lists anyway, and thus not very interesting for me to write about. So I’ll do it a little differently. This is a list of a few books that, at different moments, have really helped me take my understanding of Agile to new levels.

Let’s start with the basics. I spent a little time on an XP team at the start of my career, but I didn’t really appreciate the significance of that at the time. After all, I didn’t really have anything to compare it to! So it took me a while to get back on that track. Time mostly spent wondering why there was so little testing going on in the teams I found myself on, and trying to fix that. At one point, though, the company I was working in was changing over to using Scrum, and I was first in line to go get trained, and get going with it.

Scrum and XP From The Trenches

Scrum and XP From The Trenches

Scrum and XP from the Trenches – Henrik Kniberg

Before the training, I was of course reading up on the material, finding a lot of familiar concepts, and being very happy with what I was finding. The most useful text I encountered was Henrik Kniberg‘s ‘Scrum and XP from the Trenches‘. Useful, because it is short, free (to download, though you can buy a hard copy, nowadays), incredibly practical and emphasizes the combination of Scrum and XP. I’m very much convinced that that combination is crucial to get to any kind of success with Scrum.

So if you’re new to Scrum (or even if you’re not, but somehow missed this book), go through this book to get a quick but very thourough overview of what to do. And what not. I wouldn’t do everything exactly as Henrik describes in the book, but then, neither does he, anymore! Scrum is about learning, and adapting, so it would be surprising (and worrying!) if the people who work with it don’t learn how to do it better as time goes by.

Scaling Lean & Agile development – Craig Larman and Bas Vodde

Fast-forwarding some time, and skipping a number of books, we come to a time where we were discussing the options of organising the development efforts around a large-ish project, that would occupy about half of our approx. 120 persons large department. Coincidentally (or perhaps not) I and another Scrum Master had both been reading the sample chapter on Feature Teams from Larman and Vodde‘s book ‘Scaling Lean & Agile Development‘. The subject matter of that chapter fit perfectly with our new plans, and we did (eventually…) end-up with a feature team set-up as described in the book. The clear way in which everything was explained, and the immediate practical value of the advice (Try… / Avoid…) made this immediately valuable (so go download and read that sample chapter, already!)

Scaling Lean and Agile Development - Book cover

Scaling Lean and Agile Development - Book cover

Of course, finding something good like that meant buying the book as well. One of the rare non-fiction books that I couldn’t put down, so I read it in one weekend. For me, even though I bought it for use in an Agile environment, this book was an eye-opening introduction to the concepts of Lean and of Systems Thinking. The book starts of with a 5 chapter section on ‘Thinking Tools’, including Systems Thinking, Lean Thinking and Queueing Theory. These concepts are explained very clearly, and if they’re new for you, this will make quite a lot of the issues you see around you at work and in organisations click into place. The ‘Organizational Tools’ section then goes into more practical detail on how to arrange your organisation (Teams, Feature Teams) and your work (Requirements Areas) in such a way that you can do Large-Scale Scrum.

The authors’ idea of large-scale is 100-500 persons working on a single product. This is larger than the situations I’ve worked with (which was roughly 60 persons max., as I said above), but not only does the advice (and thinking tools!) in this book work just as well for just two scrum teams, it will also certainly help your work with single teams, or with multiple teams in an organisation where each team works on a different product.

A companion book has been released (Practices for Scaling Lean & Agile Development) which, though less horizon-expanding for me, gives more concrete practical advice based on the idea in the first book.

Leading Lean Software Development – Mary and Tom Poppendieck

Now, as you can imagine, my appetite was whet on the subject of Lean. Now Lean is a subject that came out of studying the ways of working at Toyota, which in turn was inspired by the work of W. Edward Deming. So if you’re looking, there’s a lot to read on this subject. The people who’ve done most in bringing the concepts of Lean out of the production context of Toyota (and the general management context of Deming) are Mary and Tom Poppendieck. They’ve written three books dealing with Lean in software development, but the first one that I read was the last one released: ‘Leading Lean Software Development

Leading Lean Software Development - Book Cover

Leading Lean Software Development - Book Cover

This book deals with the different aspects of managing software development, and is valid whether you want to call your way of working Lean or Agile. All the advice in here is great, but the way in which is given is even better! The whole book is set-up in such a way that each subject discussed is from the point of view of the roles that are impacted by the new way of working.

This means that the chapters on Reliable Delivery are framed from the point of view of a Project Manager, with both examples and language that fits for that role. The chapters focused on Technical Excellence take into account the views and experiences found in Software Developers and Architects, breaking down the ways working all the way back to Edsger Dijkstra, and then building it up again explaining how modern ways of working such as TDD are the closest we’ve yet come to some of the ideas of early computer science.

Because of that focus on explaining things from different points of view, the message of the book is much stronger than it would otherwise be. Also, this gives you the necessary tools to discuss the sometimes radically different views with people in various roles. Useful is you are going to be in a coaching role, as I was just switching to at the time I read this.

Next to Reliable Delivery  (planning and flow) and Technical Excellence (how to build things) ,the book also has chapters covering Systems Thinking (seeing, and optimising)  the whole, Relentless Improvement, Great People (finding, growing and keeping them) and Aligned Leaders (for a common goal, and in moving to lean/agile).

Like the Larman and Vodde book, for me each chapter was instant recognition of the problems described, and gave continuous affirmment of a way of working that I find instinctively correct.

Kanban – David J. Anderson

Kanban is an Agile system for managing work in the same way Scrum is. Kanban is more directly related to Lean than is the case for Scrum, and is considered to be the Lean software development method. In the context of these books, Kanban is a concrete implementation of the ideas of Lean encountered in the Larman/Vodde and Poppendieck books. That is also how the book reads: very concrete, with step-by-step guides to implementation of Kanban. It also gives plenty of background on why the recommended works, of course, but this is secondary to the practical side. The author, David J. Anderson, is the inventor of the Kanban Method, and this is the book that defines it.

Kanban - Book Cover

Kanban - Book Cover

Since this article’s title mentions Agile, it may be surprising that so much of the material in this list is about Lean ideas. I’ve written before on this blog that I thing the similarities between Agile and Lean are much more important than the differences. Quite a few of the ideas are the same. Certainly some of the tools are the same (for instance, a Scrum board is nothing more than a simple kanban board). Reading how those tools are used in other contexts, and why they work, can only improve your skills in using them in any context. Also, it’s important to avoid becoming a one-trick-pony. There are many situations where (ie.) a Kanban system will be much more appropriate than using Scrum would be. One example is the simple Kanban I helped set-up for our recruitment team.

Back to the book. As I said, this book stays very close to the day-to-day reality of improving software development processes. The subtitle is ‘Successful Evolutionary Change for Your Technology Business’, and the book describes why you should use the Kanban approach to guide a change process. The approach is much more incremental than a Scrum implementation usually is, which in some situations can mean the difference between failure and success. Of course, the book also goes into a lot of details on the mechanics of the parts of Kanban, how to use them in various situations, etc.  Not surprising for the book that defines the process, by its inventor.

Management 3.0 – Jurgen Appelo

Management 3.0 - Book Cover

Management 3.0 - Book Cover

This particular book I didn’t want to like (probably because of the title), but a friend ‘lent’ me a pdf copy, and after reading the first few chapters I had to cave in and order the book.

I haven’t actually finished it yet (this was last week), but am very much enjoying what I’ve read so far. The contents as well as a nicely irreverent style of humour make this a great read.

The reason the contents is so good, is that this book approaches management from the point of view of complex systems theory. Complex Adaptive Systems are mentioned often enough as a contributor to the way Scrum is set-up, but very rarely does anyone go into much detail on the how and why of that. Even rarer is this books look at how those concepts can and should be used for management. Not Project Management per se (the Poppendieck book above does a nice job of that as well), but also people management and teams.

If you’d like a quick introduction on why complex systems theory is useful for management of work, take a quick look at this video by Dave Snowden on how to organise a children’s party:

 

 

 

 

http://www.youtube.com/watch?v=Miwb92eZaJg&rel=0

Snowden, and his company Cognitive-Edge are doing interesting work in this area, and I look forward to hearing him speak at the Lean and Kanban conference in Antwerp in October.

The book uses the grounding in complexity to discuss all the subjects that a manager should take care of (but often doesn’t, or not very effectively). Subjects covered include How To Energise People, The Basics of Self-Organisation, How To Empower Teams, How To Develop Competence and How To Grow Structure. And quite a few more, but I haven’t completely read it yet. What I have read is both directly applicable, but more importantly has given me new tools to think about my work.

That’s it for this post. It can be hard with so many great books out there to pick just a few that you should read. I’ve picked a few that gave me new thinking tools over the past five years, and presented them in the chronological order in which I read them. What books should really be in this list according to you? Or do you think other books cover these kind of subjects in an even better way? Let me know!

Performance Reviews

One of the things that makes my commute to work enjoyable (next to the BBC Friday night comedy hour) is the LeanBlog podcast. In it Mark Graban talks to different people about Lean. The people he talks to have varying backgrounds, and the general quality of the podcast is very high.

One of the podcasts I listened to a while back was with Samuel Culbert, who was talking about performance reviews. I was reminded of that episode tonight while talking with some ex-colleagues about the way performance reviews were done in our old company. We weren’t very enthousiastic.

Now you might think that that is not too strange. People are very rarely enthusiastic about their performance reviews. The way most appraisal systems are set-up is that only a small percentage of people if allowed to receive a very high score. The idea is that there are a very few high-performers that should get an extra pay raise or bonus (or both), but that their occurrence should be very rare. The result is that for most people, performance review meetings contain lots of unpleasant surprises.

Why? Well, one reason is that managers are only allowed a quotum of high performers. This certainly was the case in the company I was talking about with my ex-colleagues, and going against that got me into some trouble at the time. So the team that worked fantastically together, and managed to bring a very difficult project to a successful conclusion against the odds saving the company millions. That team only gets one person to have the highest level pay-raise. The others, who worked just as hard, and were just as indispensable for the results, get a disappointment. Not that they don’t get a raise, but for those people the manager needs to emphasis the things that they did wrong. To be able to defend them not getting the top score, despite their success.

Lucky for the manager/team-lead there is always something wrong to be found! Lucky for the company, they hire completely random, so their bell-curve of performance always works out… Actually, Culbert mentions that these distributions usually mean that about 70% of the people should be marked as average. That is going to be difficult, isn’t it?

But the appraisal is necessary, right? To ensure people stay motivated. To ensure they’re focused on improving. To set explicit targets, both for their work (because you can’t expect them to understand what’s important for their day-to-day work), and for their personal development (because… sorry can’t seem to think of a reason).

Mr. Culbert makes some good points in the podcast, calling performance reviews “corporate theatre,” as well as a “sham,” a “facade,” “immoral” and “intimidating”. Unsurprisingly, since he’s written a book called “Get rid of the performance review“.

His latest book is apparently called “Beyond Bullshit“, which sounds like another one I should pick-up.

My own views on this practice is aligned with Culberts: at best, a performance review doesn’t add any value; mostly, it is harmful for people and company.

If the feedback you as a manager give during a review is in any way new to the person you’re reviewing, then you’ve failed as a manager to do your job (which should have been helping that person to do their work as best as possible, not collecting information on how they do that work for later use). If not, why have the meeting.

If the review is about verifying whether targets have been met, or to set new targets, you really should read Dan Pink’s Drive about all the ways the use of targets is hurting motivation, and thus performance, of your people.

Agile is Rock ‘n’ Roll

[EDIT: Thanks to Hubert Iwaniuk, there’s now a playlist to accompany your reading of this post!]

[EDIT: There’s now also an XP version of this: XP Is Classic Rock]

I’ve had a number of occasions where people, usually working in a very strict, waterfall, environment, have voiced the opinion that ‘all that agile stuff’ is just an excuse to go ‘back to’ cowboy programming and rock ‘n’ roll development.

My normal response to this is something along the lines of ‘Au contraire! Working agile means you need to be more disciplined, not less!’ Which is true, of course, but not always quite in the same sense that they’re talking about.

Recently, though, it has occurred to me that in some ways, Agile really is Rock ‘n’ Roll! Let’s take a look at some examples:

Estimation and Planning

To quote the well respected experts on backlog prioritisation and de-scoping, Jagger and Richards: “You can’t always get what you want, but if you try, sometimes, you get what you need.”

And indeed this is the basis of Agile (release) planning: We take into account what the customer wants at the start of the project (and place that on our backlog), but make it clear that we do not know for sure yet what will be delivered eventually. We do go back to the customer frequently to determine if he’s happy with what he has so far, and whether he actually needs anything more (or something different). This gets the customer what he needs, or as much of it as possible within the time frame.

Team work

Whether you’re more partial to the original Beatles version, or the Aerosmith cover, the message to ‘Come Together’ is fairly core to our agile values. And from the rest of the lyrics it seems fairly possible that they are talking about old-style hackers and agile coaches:-)

Time Boxing

One tool we’ve certainly embraced in the Agile community is time boxing. And this really goes back to one of the originals of Rock ‘n’ Roll: Rock Around The Clock. As the song says: “We’ll have some fun when the clock strikes one”, and keep going, having a good time and “When it’s eight, nine, ten, eleven too, I’ll be goin’ strong and so will you.”. But we are strict in an almost Cinderella like fashion, and “When the clock strikes twelve, we’ll cool off then”, before we start another time-box.

Ch… Ch… Changes

I still don’t know what I was waiting for
And my time was running wild
A million dead-end streets
Every time I thought I’d got it made
It seemed the taste was not so sweet

If there was ever a song that was completely and obviously inspired by the need for Agile development, this is it. Mr. Bowie is even considerate enough to include the importance of testing: “how the others must see the faker, I’m much too fast to take that test”.

As you can see in the quoted lyrics above, we’re dealing with a man tired of waiting long periods of time for something which isn’t quite what he expected. Again, and again, this happens. A sad story, but all too familiar.

Transparency

We have to remember that the reasons for choosing an Agile way of working is not always one of love at first sight. The choice is often the last one after many disappointing previous liaisons. As Freddie Mercury sings in the last of our Agile Playlist, “I want to break free from your lies, you’re so self-satisfied I don’t need you”, right before he breaks the chains of his waterfall process.

But this same song also contains a warning: even if we deliver all we promise with new ways of working, the temptation to go back to the familiar ways of earlier days remains. And people still may ‘walk out the door’, because they ‘have to be sure’. Unfortunate, but unavoidable.

Take me to the other side

Not all songs are about happy things, though. It would of course be possible to note that Waterfall has some very nice tunes of its own. People would note the micro-management displayed in Every Breath You Take, and Walk This Way. They’ll point to the wishful planning complained about in Won’t Get Fooled Again. And Billy Joel’s Allentown, though written for a different industry, also deserves mention in this list. They might even mention Stairway to Heaven, which symbolically represents the Waterfall process’ stairway like structure, and lyrically describes the results (“When she gets there she knows, if the stores are all closed with a word she can get what she came for”, and “There’s a feeling I get when I look to the west, And my spirit is crying for leaving.”)

Are we sure heaven's this way?

Are we sure heaven’s this way?

For those people, it might be good to remember that there must be 50 ways to leave your waterfall project.

The problem is all inside your head
She said to me
The answer is easy if you
Take it logically
I'd like to help you in your struggle
To be free
There must be fifty ways
To leave your waterfall project

She said it's really not my habit
To intrude
Furthermore, I hope my meaning
Won't be lost or misconstrued
But I'll repeat myself
At the risk of being crude
There must be fifty ways
To leave your waterfall project
Fifty ways to leave your waterfall project

[CHORUS:]
You just interact, Jack
don't make a new plan, Stan
Continuously deploy, Roy
And you test regularly
Create a little trust, Gus
You do need to discuss, much!
Work transparently, Lee
And get yourself free

5 ways to make sure your sprint velocity is a useless number

Velocity always seemed a nice and straightforward concept to me. You measure how much you get done in a certain period of time, and use that to project how much you’ll probably get done in the same amount of time in the future. Simple to measure, enables empirical planning, simple to use in projections and planning. Measuring influences the work, though.

The concept of velocity is almost always used, even within companies that are still new to an Agile way of working. But simple though it seems, there are many ways velocity can lose its usefulness. I happen to think velocity is one of the better metrics, but if you’re not measuring it correctly, or misinterpreting the resulting numbers, it can become a hurdle to good planning.

Let’s have a look at some of the ways velocity doesn’t work, and how to avoid them.

Not a Number

First of all, velocity is not just a number. It’s always a range, or an average with error margins. Why is this important? Because if you do your planning based on a single number, without taking into account the normal variation in productivity that is always there, you can be sure your planning is not giving you a realistic idea of what will be done when.

In other words: realise that your planning is an estimation of when you think a certain set of work can be done. An estimation should always include uncertainty. That uncertainty is, at least partially, made explicit by taking the variance of your velocity into account.

Velocity charted with a confidence level around it

Velocity charted with a confidence level around it

The simplest way to get pessimistic and optimistic values for velocity is to simply take the average of the three lowest and the three highest of the last ten sprints. Another way is to use a mathematical confidence level calculation. I don’t actually think there’s much difference between the two. Charting velocity in this way can get you graphs such as the one shown above.

Then, of course, you have to actually use this in your release planning.

Release forecast using variation in velocity

Release forecast using variation in velocity

Not an average

I know I just talked about it not being an average, but this is different. Another way in which the averaging of points finished in a sprint can cause problems, is if it doesn’t actually mean ‘points finished in a sprint’. Quite often, I’ve met teams that have a lot of trouble finishing stories within their sprints. The causes of that can be many, with stories simply being too large on top. Sometimes these teams have correctly realised that if they’ve only finished part of a story, they don’t get partial ‘credit’ for this in the Sprint’s velocity. But then they do take credit of the full number of story-points for the entire story in the subsequent sprint, once they’ve actually finished the story.

Average?

Average?

So here we can see what happens then. The average is around 20. So should this team plan 20 story-point worth of work into their next sprint? Probably not a good idea, right? If the variation in velocity is very high, there is usually a problem.

What one could do in this instance is re-estimate any unfinished stories so that only the work actually done in the later sprint for those stories is calculated for those sprints. Yes, you’ll ‘lose’ some points that you estimated are don’t seem to count anywhere as work done. But you’ll immediately get a more realistic figure for your velocity, and an immediate reason to make those stories smaller, as they simply won’t fit in a sprint if the velocity is realistic.

For release planning, you’ll not be depending on a weird fluctuation of velocity any more, but on a more dependable figure with less variation.

Variable Sprint Length

If you change the length of your sprints around, velocity will not be very useful. But, I can hear you say, we can just calculate the expected velocity for a 2 week sprint by taking two-thirds of the velocity of a 3 week sprint! That would be nice, but unfortunately it doesn’t work like that. The regular rhythm of sprints creates certain expectations within the team. The team learns how much it can take in, in such a period. Also, the strict time-box of an agreed sprint length is very useful in bringing existing limitations into view.

Bring problems to the surface

Bring problems to the surface

The famous ‘lowering the waters brings the rocks to the surface‘ picture of lean waste elimination is a useful way to view this.

Estimating In Time

If someone asks me how long I’m going to take to do a particular piece of work, I’ll normally answer saying it will take a certain amount of time. This is quite natural, and answers fairly directly the question posed. When someone asks me when I can have such a particular piece of work ready, again I could answer by giving a specific date and time.

If someone asks me how much work I can do in a work week, though, I might be tempted to answer: “40 hours”. And I would probably be right! And if I would then, at the end of that week, look back, and see how much time did I actually work, it would probably not be too far off those 40 hours. But I wouldn’t learn much from that observation.

By using the concept of ‘Story Points’, an abstract measure for estimation, we can still estimate the effort for a certain piece of work. And if we then give other pieces of work an estimation in Story Points, relative to the story we already estimated, we have created a new measurement system! So for instance if ‘Allowing a user to log-in’ is 3 Story Points, then ‘sending a user a password reminder’ could be 5, if it’s about  (but not quite) twice as big.

Of course, in the end you will want to relate those abstract Story Points back to time, since you will often want to determine when you can release a bit of software. But you don’t estimate that, you measure that: It turns out in on sprint, we can do about 12 Story Points, give or take a few. So if that’s the case, we will be able to release functionality X by at the latest, date Y (see the release planning graph earlier).

Some people do the same type of trick by using ‘ideal days’ to estimate, and determining the ‘focus factor’, or percentage they were actually managing to get done. Mathematically this works OK, but it’s very hard for people to let go of their feeling of ‘when it will be done’, and estimate is ‘real’ ideal days.

Including bug-fix time in your velocity

I’ve noticed that this one can be a bit controversial, but it’s an important factor in the usefulness of  your velocity figure.

As a team, you will encounter work that is not part of creating new functionality from your product owners wishlist. Often, this work presents itself in the form of fixing defects found in your software. Most of the time, those defects exist in the software because in an earlier sprint some new functionality was added.

Now it can be that such a defect is discovered, and needs to be fixed right away, because it truly interferes with a customer’s use of your system. Those types of defect are usually not estimated, but certainly not taken into account when calculating your velocity for a certain sprint.

Other defects are less critical, and will/should be planned (prioritised by your Product Owner) to be taken into a sprint. Those types of defects sometimes are estimated, but still should not be taken into account when calculating your velocity!

Why not? Well, if you see the goal of your team as delivering new software for the Product Owner, then a defect is simply a way in which some work delivered was not completely done. Usually not done in the form of not sufficiently tested. Fixing such a defect is of course very important. But it is slowing you down from the primary goal of delivering new functionality! But adding the points for fixing the defect to your velocity would make it seem that you are not going any slower (maybe even faster!). So it would give a false impression of the speed in which you’re getting the work the Product Owner wants, done, and might skew release planning because of that.

Also, it would means that your improvements in quality, which you’ve been working so hard on, will not be visible in your velocity. Now, is that right?