Why write Unit Tests?

Testing is a passion of mine and it’s something I expect to write about a lot more in the future. What I feel is discussed less often though is “Why are we writing tests?”

When many people talk about writing tests they talk about writing Unit Tests, classes and methods broken down into small, isolated areas of code which can be examined with tests to guarantee code quality. Let’s look at an example:

public string ReadText(string filename)
{
  if(File.Exists(filename))
  {
    return File.ReadAllText(filename);
  }
  else
  {
    return null;
  }
}

This code reads the text in a file and returns it, if the file doesn’t exist it returns null.

The thing is, this is trivial code. Writing Unit Tests for something like this is overkill surely? That thirty minutes or so could be invested in the next feature, a bug fix or meeting the tight deadline.

Let’s suppose another developer comes along in a few years time, they see this method and know something their predecessor didn’t. .NET has a FileNotFoundException exception! Deciding to be a conscientious coder they update the method to throw an appropriate exception if the file isn’t found.

public string ReadText(string filename)
{
  if(File.Exists(filename))
  {
    return File.ReadAllText(filename);
  }
  else
  {
    throw new FileNotFoundException(string.Format("The file '{0}' was not found", filename));
  }
}

Unfortunately our conscientious developer missed something. One of the myriad of methods which calls our methods is GetOrCreateFileWithContents

public string GetOrCreateFileWithContents(string filename, string defaultContents)
{
  var currentContents = ReadText(filename);
  if(currentContents == null)
  {
    currentContents = CreateFile(filename, defaultContents);
  }

  return currentContents;
}

Because of our change this method now fails, ReadText throws an exception and the new file is never created in it’s place. This may be an oversimplified example with an overzealous and (dare I say it careless) tidy up but it illustrates the risks we take every day when refactoring and improving code.

This is the true value of Unit Tests, not in finding bugs but in defining the behaviour of the method. If our original developer had invested that extra thirty minutes our Boy Scout would have had some warning when then tried to update the method, they’d have seen that they’d changed the behaviour of the class in an unacceptable way and wouldn’t have made their changes.

The moral of the story? Unit Tests may seem like overkill while you’re writing them. But spare a thought for the poor soul who’s trying to read your methods in a few years time… Leave them a map, a series of executable tests which guarantee that your required behaviour remains unchanged. Your thirty minutes could save them hours, prevent bugs being introduced and help keep your application stable.

SpecFlow what is it and why should I care?

I was introduced to SpecFlow a year or so ago by a friend of mine during a presentation at Agile Yorkshire. He described it as a tool for BDD and I was immediately struck by the revolutionary concept of human readable tests. It’s taken me a little time, some projects and many follow up questions but I feel I’m really beginning to grasp the power of this easy to use tool.

So what is it? SpecFlow is a framework which translates text into a series of steps which are compiled as a test.

This makes more sense with an example. Let’s say I’m the developing the software for a cash machine.


Given I have £150 in the bank
When I withdraw £100
Then I should have £50 remaining in my account

SpecFlow will then generate three steps for you to implement.

[Binding]
public class Bindings
{
  [Given(@"I have £(.*) in the bank")]
  public void GivenIHaveInTheBank(int p0)
  {
    ScenarioContext.Current.Pending();
  }

  [When(@"I withdraw £(.*)")]
  public void WhenIWithdraw(int p0)
  {
    ScenarioContext.Current.Pending();
  }

  [Then(@"I should have £(.*) remaining in my account")]

  public void ThenIShouldHaveRemainingInMyAccount(int p0)
  {
    ScenarioContext.Current.Pending();
  }
}

I’ve filled these in quickly to give you an idea of how the process is intended to work.

[Binding]
public class Bindings
{
  private readonly CashMachine _cashMachine;

  public Bindings(CashMachine cashMachine)
  {
    _cashMachine = cashMachine;
  }

  [Given(@"I have £(.*) in the bank")]
  public void GivenIHaveInTheBank(decimal initialBalance)
  {
    _cashMachine.Balance = initialBalance;
  }

  [When(@"I withdraw £(.*)")]
  public void WhenIWithdraw(decimal withdrawlAmount)
  {

    _cashMachine.Withdraw(withdrawlAmount);

  }

  [Then(@"I should have £(.*) remaining in my account")]
  public void ThenIShouldHaveRemainingInMyAccount(decimal expectedRemainingBalance)
  {
    Assert.AreEqual(expectedRemainingBalance, _cashMachine.Balance);
  }
}

Behind the scenes SpecFlow has built a test using your test framework of choice (MSTest, NUnit, XUnit or a variety of others). These tests can be run within Visual Studio as any other unit test. Here’s my scenario running in Resharper:

 

Resharper Executing Test

 

I think most people would be impressed by this. SpecFlow has converted human readable text and enabled us to write a simple unit test for it. We can easily add a second to make sure that our new state of the art cash machine can also dispense pennies.


Given I have £100.86 in the bank
When I withdraw £1.99
Then I should have £98.87 remaining in my account

We can add additional complexity such as overdrafts


Given I have £100 in the bank
And I have an overdraft of £50
When I withdraw £125
Then I should have £-25 remaining in my account

Or functionality to check that I cannot go overdrawn


Given I have £100 in the bank
And I have an overdraft of £0
When I withdraw £125
Then I should be prevented from withdrawing money
And I should have £100 remaining in my account

I’m sure you can see the value of having simple, understandable definitions of what a particular area of code should do instead of the complicated, developer-only Unit Tests which litter many of today’s solutions. If you wish these executable tests can form the basis of your specs, documentation and even training. Your Product Owner can get involved and validate the tests are correct, if they’re particularly tech-savvy they may even write a few themselves!

What I particularly love about SpecFlow however is the way it empowers today’s QAs. From the moment the first bindings have been created your QA team can be let loose to create new tests, verify edge cases and prove alternate scenarios until they are happy that the feature works as designed. Tests can now be created alongside the features being developed, Acceptance Tests can be created directly from the specification which the QA team can use to validate each feature and scenario as it is being developed. These same tests then form the basis of your regression suite for years to come.

Should any of these tests fail the QA team can provide the developer with not only the human readable replication steps but with with an executable test which can be debugged on the dev’s own PC.

I find this very exciting, we’ve started using SpecFlow for a number of projects and I have every intention of using it for more. If you’re interested in finding out more visit the SpecFlow website or read their Quick Start Guide.

Learning the role of Scrum Master at the deep end

My induction into my informal position of Scrum Master was rather quick, a member of staff was leaving and the team needed someone to help run the meetings. Learning fast and jumping straight in at the deep end is my typical (if not favourite) way of learning so I rolled up my sleeves, read a few books and did my best.

So what have I learned? What dubious advise could I pass onto any developer who finds themself stepping into the same role?

Know your Ceremonies

The Scrum Master’s week is punctuated by meetings such as Daily Standups, Planning Sessions, Sprint Review and Retrospectives. You’ll encounter resistance to these because devs like writing code, they don’t enjoy spending hours each week sat in the meeting room. You’ll need to justify these sessions, if you can’t explain why you want to meet then it’s best not to!

Daily Standup

This is the most common session you’ll be expected to run. It’s also the most famous, many businesses claim to be agile simply because they have a daily standup! Getting it right is key to your team’s success.

First the obvious question, do you actually need to stand up? No! People who have never attended a standup will challenge this methodology, there are advantages for and against standing up for the meeting and you need to understand both sides if you want to discuss the reasons. On the one hand physically standing encourages participants to keep their part short and on topic, I also like to guide speakers around the circle so everyone knows when they will be expected to talk and no one is left stammering. On the other hand standing up can be very difficult for distributed teams, meeting over Skype with headsets reduces lot of background noise but brings with it the inevitable technical problems and opens the unending source of distractions which is a dev’s PC. There’s no right answer, but different teams will prefer one style or another.

Keeping on topic is a huge challenge and one I’m still struggling with. Your standup should consist of three bullet points

  • What did you do yesterday?
  • What are you aiming to do today?
  • Are you blocked in any way and are you on track to burn down?

In my experience there are two main reasons for a scrum wandering off topic, these are Story Telling (going into too much detail about what they did yesterday) and Problem Solving (using everyone’s time to try and become unstuck). Devs love to talk about challenges they overcame and solve other people’s problems. The key is to spot when this occurs and suggest that these conversations can be had later.

The sixteenth minute is an interesting idea, as I mentioned above one of the main reasons for scrums dragging on is people trying to utilise the entire team to solve their impediments. One approach is to formalise an optional follow up chat for the required parties so they can continue to discuss issues without hindering the rest of the team. Keep an eye on how many of these follow up conversations are needed, too many and they rapidly take over the team’s morning.

Sprint Planning

I’ve found the key to Sprint Planning is preparation, this can often be an issue when the meeting is scheduled for first thing on a Monday morning! Before you walk into the planning session you should have:

  • The backlog prioritised
  • Details of the capacity of your team (or team members if you plan individually)
  • Details of how much work has been carried over from the previous sprint

If you don’t have this information to hand you’ll need to acquire it in the meeting, this is all information you should have access to through your planning software. Asking for it in the meeting wastes everyone’s time and leads to boredom and the feeling of wasted time, not how you want to start your sprint!

Armed with this data your planning meeting is simply a matter of dishing out the highest priority tasks to the team members who want to pick them up. Simple!

Sprint Review

The purpose of the Sprint Review is to demonstrate what you’ve built to the stakeholders and other interested parties, this can often be your Product Owner, Support Team or other devs. These people then have the opportunity to provide feedback which can be considered, prioritised and included in the project.

The problem I often find is that there are so many ideas, so many discussion points and so many questions that your one hour slot is barely enough to get through the first demo. So how can we address this?

  • Nominate a single person to make note of the suggestions, by making sure everything is written down no idea is wasted and they can be prioritised and scheduled with your Product Owner
  • Consider recording videos instead of live demos, the live demo is a bane of any presenter. By asking your devs to record videos in advance the demos are foolproof, there are no unexpected technical problems and you know exactly how long each video will last!
  • Save questions and feedback until the end of each presenter. We are geeks, not public speakers, give your developers a chance by letting them get to the end before bombarding them with suggestions on how to improve the task they’ve been slaving over all week!

Sprint Retrospective

A fundamental part of the Agile Manifesto is that teams should look at what went well, what they’re struggling with and adapt their processes to improve. Often this is done in a retrospective meeting.

When I first started doing retrospectives we followed a well known pattern

  • What went well?
  • What didn’t go well?
  • What should we start?
  • What should we stop?

We worked our way around the table and everyone was expected to come up with a suggestion for each list. I found these meetings rather unfulfilling, I often felt they descended into a rant about process, other teams, technology or whatever else was irking the group at the time. While I’ve no doubt that it was good therapy I didn’t feel like the hour achieved much.

Instead I’d suggest planning each meeting with a specific topic

  • How can we ensure that high priority support requests are picked up mid sprint?
  • Should we use Web API or WCF for our new API?
  • How can we get clear acceptance criteria for our upcoming bespoke development?

By stating what you hope to achieve from the retrospective in advance you stand a much higher chance of success! Ask your team for items they want to discuss, email around your proposed meeting topic with plenty of notice and ask your devs to bring their own ideas to the meeting.
Hopefully I’ve given a few helpful suggestions for you to consider. I don’t claim to be an Agile expert and I’m still struggling to follow lots of my own advice but every sprint we learn a little more… Isn’t that the point after all!?