Archive

Archive for the ‘Unit Testing’ Category

Make it run, make it right: The three implementation strategies of TDD

I’ve been doing TDD for a while now, as well as running TDD-based code dojos. I really like it as a method of programming, and use it for the majority of the production code I write.

However, there’s one important area I’ve never got quite straight in my head, around the point at which you go from ‘making it pass quickly’ to ‘implementing it properly’. I’ve always followed the rule (picked up at some past dojo) to make the test pass in the simplest way possible, then refactor if necessary before continuing with the next test. Making it pass simply often involves returning a hard-coded value, but I’ve never fully got a handle on when that value should get replaced with the ‘real’ implementation, and related to that, when certain things should be refactored.

Following some recommendations, I finally read Kent Beck’s Test-Driven Development By Example, an influential book on TDD published back in 2002. Yay!  Finally, the last piece of the puzzle was revealed. Well OK, probably not the last, but an important one…

There are several useful guidelines in the book – for example he specifies the TDD cycle as ‘Write a test, Make it run, Make it right’ (similar to the more commonly used ‘red, green, refactor’ – not sure which came first).  The one I’m focussing on today is his strategy for the implementation of functionality, i.e. the ‘make it run’ and ‘make it right’ phases.

To take the descriptions from the book, the three options you have are:

Fake It – Return a constant and gradually replace constants with variables until you have real code

Obvious Implementation – Type in the real implementation

Triangulation – Only generalize code when we have two examples or more

This is already getting interesting – we now have three well-defined methods of proceeding.  Looking back, I think part of my problem has been trying to stick to one rule in the many and varied situations that arise when coding a solution with TDD.

Lets have a look at these in a bit more detail, with some example code.  The examples are based on the Checkout kata, which involves implementing a supermarket checkout system which calculates the price of items bought. I haven’t included every step, but hopefully you can fill in the blanks.

Fake It

One of the guiding principles behind these strategies is that you want to get a passing test as quickly as possible.  If that means writing some dodgy code, then so be it – it’s not a concern, because one of the other principles is that the code should be constantly and aggressively refactored.  So get the test passing, then you have a safety net of passing tests which enable you to refactor to your heart’s content.

Often, the quickest way to get a test passing is to return a hard-coded value:

[Test]
public void scanning_single_item_gives_single_item_price() {
    var till = new Till();
    till.Scan("Apple");
    Assert.That(till.Total, Is.EqualTo(10));
}

public class Till {
    public void Scan(string product) {}

    public int Total {
        get {
            return 10;
        }
    }
}

Once that’s done, we can immediately get to refactoring. Kent’s main goal of refactoring is to remove duplication anywhere you can spot it, which he believes generally leads to good design. So where’s the duplication here? All we’re doing is returning a constant. But look closely and you’ll see it’s the same hard-coded constant defined in the tests and the code. Duplication.

So how do we get rid of it? One way would be to have the checkout take the value from the test:

[Test]
public void scanning_single_item_gives_single_item_price() {
    var applePrice = 10;
    var till = new Till(applePrice);
    till.Scan("Apple");
    Assert.That(till.Total, Is.EqualTo(applePrice));
}

public class Till {
    private int _applePrice;
    public Till(int applePrice) {
        _applePrice = applePrice;
    }

    public void Scan(string product) { }

    public int Total {
        get {
            return _applePrice;
        }
    }
}

Well, not how I’d usually implement it, but that makes sense I guess – the checkout would be getting it’s prices from somewhere external, and passing them in like this helps keep the checkout code nice and self-contained, and adhering to the open/closed principle.  Maybe removing duplication really can help with a good design..

Of course, the checkout would need all prices passing in, not just the price for one product.  But as usual with TDD, we’re taking small steps, and only implementing what we need to based on the current set of tests.

Obvious Implementation

One of the ‘rules’ of TDD which I make people follow in dojos has been to always start with the simplest possible implementation.  This is a concept which mightily annoys some experienced devs when they first try TDD – ‘Why return a hard-coded value’, they ask, ‘when I know what the implementation’s going to be?’.

Well, they will be most pleased with the second option, which states that if the implementation is obvious and quick – just type it in!

So if for our next test we end up with

        const int applePrice = 10;
        const int bananaPrice = 15;
        Till till;

        [SetUp]
        public void setup() {
            till = new Till(new Dictionary<string, int> {
                {"Apple", applePrice},
                {"Banana", bananaPrice}
            });
        }

        [Test]
        public void scanning_different_item_gives_correct_price() {
            till.Scan("Banana");

            Assert.That(till.Total, Is.EqualTo(bananaPrice));
        }

If we’re feeling plucky, we might just go for it:

    public class Till {
        private Dictionary<string, int> _prices;
        private string _scannedItem;

        public Till(Dictionary<string, int> prices) {
            _prices = prices;
        }

        public void Scan(string product) {
            _scannedItem = product;
        }

        public int Total {
            get {
                return _prices[_scannedItem];
            }
        }
    }

However, if you have any doubts, get a failing test, or it’s just taking too long – you’ve taken the wrong option. Back out your changes, and go back to Fake It.

Triangulation

The last option is the least favoured by Mr Beck, reserved for those times when he’s ‘completely unsure of how to refactor’, and ‘the design thoughts just aren’t coming’.  For me, going by the rules I’ve learned in past dojos, it’s one I quite often end up using.  Essentially it involves using using Fake It to get a test passing, but instead of going straight to the real implementation, entering another test to force you into writing a generalised solution.

Now, we’re starting to scan multiple items:

        [Test]
        public void scanning_multiple_items_gives_sum_of_prices() {
            till.Scan("Apple");
            till.Scan("Banana");

            Assert.That(till.Total, Is.EqualTo(applePrice + bananaPrice));
        }

We have to update the code a little, but can fake the important bit:

    public class Till {
        private Dictionary<string, int> _prices;
        private List<string> _scannedItems = new List<string>();

        public Till(Dictionary<string, int> prices) {
            _prices = prices;
        }

        public void Scan(string product) {
            _scannedItems.Add(product);
        }

        public int Total {
            get {
                if (_scannedItems.Count == 2) {
                    return 25;
                }
                return _prices[_scannedItems[0]];
            }
        }
    }

Obviously, checking the number of scanned items isn’t going to work for long, but instead of refactoring immediately we can write another test which will force us to change it.

        [Test]
        public void scanning_different_multiple_items_gives_sum_of_prices() {
            till.Scan("Banana");
            till.Scan("Coconut");

            Assert.That(till.Total, Is.EqualTo(bananaPrice + coconutPrice));
        }

And now we enter the general solution:

        public int Total {
            get {
                return _scannedItems.Sum(item => _prices[item]);
            }
        }

Since using these strategies, I have also found that Triangulation isn’t needed much, as if you stick strongly to the ‘refactor away duplication’ rule, a single Fake It with immediate refactoring usually does the job.

Conclusion

It’s fair to say that I haven’t mastered TDD yet, even after so long, but I’m pretty happy with it now, thanks to the guidance like this. I still find situations where I’m unsure how to proceed, but they are getting rarer. Trying to follow these three strategies has certainly helped, and the ‘refactor to remove duplication’ concept by itself has been very useful. I hope you get some benefit from them too.

Categories: C#, TDD, Unit Testing

Testing DateTime.Now (and other things) with an Ambient Context

September 30, 2013 Leave a comment

One issue you’re likely to face while writing automated tests is that it can be tricky to check anything related to DateTimes, as they are typically accessed statically using:

var startTime = DateTime.Now;

The approach I’ve typically used is to create some kind of IDateProvider interface, and supply that as a dependency as needed using Dependency Injection.  However, with things used throughout a system like DateTime can be, this becomes quite a chore and make the code more complex with an ever-increasing list of dependencies.

One of the great tips given by Ian Russell at an Agile Yorkshire meetup recently was to use the Ambient Context pattern in this, and other similar situations.

Note: I didn’t write the code below, I found it in various places online, particularly this Stack Overflow question by Mark Seemann, author of Dependency Injection in .Net.  I was having trouble finding the details online, which is why I’ve posted them here.

So, to take full control of DateTime.Now, you need an abstract TimeProvider:

public abstract class TimeProvider {
   private static TimeProvider current =
   DefaultTimeProvider.Instance;

   public static TimeProvider Current {
      get { return TimeProvider.current; }
      set {
         if (value == null) {
            throw new ArgumentNullException("value");
         }
         TimeProvider.current = value;
      }
   }

   public abstract DateTime UtcNow { get; }

   public static void ResetToDefault() {
      TimeProvider.current = DefaultTimeProvider.Instance;
   }
}

A concrete implementation used in your live system:

public class DefaultTimeProvider : TimeProvider {
   private readonly static DefaultTimeProvider instance = 
      new DefaultTimeProvider();

   private DefaultTimeProvider() { }

   public override DateTime UtcNow {
      get { return DateTime.UtcNow; }
   }

   public static DefaultTimeProvider Instance {
      get { return DefaultTimeProvider.instance; }
   }
}

And a mock for testing, for example here set up with Rhino.Mocks:

var fakeTimeProvider = MockRepository.GenerateStub();
fakeTimeProvider.Expect(x => x.UtcNow).Repeat.Once()
   .Return(new DateTime(1999, 12, 31, 11, 59, 59, 999));
fakeTimeProvider.Expect(x => x.UtcNow).Repeat.Once()
   .Return(new DateTime(2000, 1, 1, 0, 0, 0, 0));

For this to work, instead of calling dateTime.Now (or DateTime.UtcNow as we’re using here) from your code, you need to call:

var startTime = TimeProvider.Current.UtcNow;

One last thing – don’t forget to reset the provider after you mock it out, otherwise your mock will remain as the time provider:

[TestCleanup]
public void TearDown() {
   TimeProvider.ResetToDefault();
}

As suggested in the title, this can be used for things other than DateTime, but that’s the only place I’ve tried it so far.

Happy testing!

Categories: Patterns, TDD, Unit Testing

Nice up those Assertions with Shouldly!

October 19, 2010 1 comment

One thing I noticed while having a play with Ruby was that the syntax for their testing tools is quite a lot more natural-language like and easier to read – here’s an example from an RSpec tutorial:

describe User do
  it "should be in any roles assigned to it" do
    user = User.new
    user.assign_role("assigned role")
    user.should be_in_role("assigned role")
  end
it "should NOT be in any roles not assigned to it" do
    user.should_not be_in_role("unassigned role")
  end
end

Aside from the test name being a string, you can see the actual assertions in the format ‘variable.should be_some_value’, which is kind of more readable than it might be in C#:

Assert.Contains(user, unassignedRoles);

or

Assert.That(unassignedRoles.Contains(user));

Admittedly, the second example is nicer to read – the trouble with that is that you’re checking a true/false result, so the feedback you get from NUnit isn’t great:

Test ‘Access_Tests.TestAddUser’ failed:  Expected: True  But was:  False

Fortunately, there are a few tools coming out for .net now which address this situation in a bit more of a ruby-like way.  The one I’ve been using recently is Shouldly, an open source project on GitHub.

Using Shouldly (which is basically just a wrapper around NUnit and Rhino Mocks), you can go wild with should-style assertions:

age.ShouldBe(3);

family.ShouldContain(“mum”);

greetingMessage.ShouldStartWith(“Sup y’all”);

And so on.  Not bad, not bad, not sure if it’s worth learning another API for though.  However, the real beauty of Shouldly is what you get when an assertion fails.  Instead of an NUnit-style

Expected: 3

But was:  2

- which gives you a clue, but isn’t terribly helpful – you get:

age

should be    3

but was    2

See that small but important difference?  The variable name is there in the failure message, which makes working out what went wrong a fair bit easier – particularly when a test fails that you haven’t seen for a while.

Even more useful is what you get with checking calls in Rhino Mocks.  Instead of calling

fileMover.AssertWasCalled(fm => fm.MoveFile(“test.txt”, “processed\\test.txt”));

and getting a rather ugly and unhelpful

Rhino.Mocks.Exceptions.ExpectationViolationException : IFileMover.MoveFile(“test.txt”, “processed\test.txt”); Expected #1, Actual #0.

With Shouldly, you call

fileMover.ShouldHaveBeenCalled(fm => fm.MoveFile(“test.txt”, “processed\\test.txt”));

and end up with

*Expecting*

MoveFile(“test.txt”, “processed\test.txt”)

*Recorded*

0: MoveFile(“test1.txt”, “unprocessed\test1.txt”)

1: MoveFile(“test2.txt”, “unprocessed\test2.txt”)

As you can see, it’s not only much more obvious what’s happening, but you actually get a list of all of the calls that were made on the mock object, including parameters!  That’s about half my unit test debugging gone right there.  Sweet!

Shouldly isn’t a 1.0 yet, and still has some missing functionality, but I’d already find it hard to work without it.  And it’s open source, so get yourself on GitHub, fork a branch, and see if you can make my life even easier!

Extract and Conquer!

October 19, 2009 Leave a comment

..Or ‘Extract and Override’ as it’s otherwise known

 

I started working on a Dynamics CRM project recently, and a technique I read about in Roy Osherove’s book has started to come in really handy, which he calls ‘Extract and Override’.

Not that it’s specific to CRM, or any particular type of development – indeed, Roy states that he always tries to use this technique first and only defers to other methods of testing if it isn’t possible.  I had certain reservations when I first read about it, but having given it a try over the last few weeks I am now a convert.

The purpose of this technique is to insert a ‘seam’ into your code – a place where you can replace dependencies on other classes & services with fake versions, so you can test one class at a time.  Previously, I’d always done this using constructor injection, whereby you pass the dependencies into the class constructor:

Simple Robot Class

Simple Robot Class

This way, when we want to test the robot mood logic in KillHumans(), we can create fake versions of IWeaponSystem, ICommunication and IMoodManager, and just test the Robot logic.  In the actual system, the real versions of these things would be supplied by a Service Locator/IOC container or similar.

This is all very well, but doesn’t work with CRM because you don’t control creation of classes.  Basically you get passed a service and have to use that for all of your communication with CRM.  To stay with the robot example, it would look something like this:

Robot Class using CRM-Style Service

Robot Class using CRM-Style Service

Because all communication is going through RobotService.Execute(), it’s very difficult to fake this, especially when it’s called multiple times and you need different return values.

To get over this, we can use Extract and Override.  This works by putting the calls to the external services in their own methods, and then overriding them while we’re testing.  This way, we don’t have to create fake services at all!  Just a single fake version of the class we’re testing.  The code in Robot would now look something like this:

Testable Robot Class

Testable Robot Class

Notice that the extra methods are ‘virtual’ so we can override them.  they are also ‘protected’ so they’re accessible from classes which inherit from them.  So now instead of creating fake services, we’d create a testable version of the robot class, like this:

Overriden Robot Class, for Testing

Overriden Robot Class, for Testing

We now have full control over what gets returned from those methods, and we can record when got sent into them.  As such, we can happily test the mood logic in KillHumans() without worrying about those dependencies.

Now, this isn’t limited to the CRM situation described – you can use this technique any time you have a dependency on another service, as an alternative to Dependency Injection.  You can read a bit more about it in one of Roy’s blog posts, which probably explains it a bit better!  Although sadly without the use of robots.

Categories: Unit Testing Tags: ,

Code Coverage with PartCover

September 5, 2009 5 comments

I’ve been getting more into Test Driven Development (TDD) recently, so I’ve been building up my unit testing toolset as I go along.  I’ve got the basics covered – the industry-standard NUnit as my testing framework & test runner, and Castle Windsor if I need a bit of IOC, are the main things.

But I’m at the stage now where I know the basics so I’m trying to improve my code and my tests, as because anyone in TDD will tell you, if your tests are no good, they may as well not be there.  So the next obvious step was a code coverage tool.  At the basic end, this is a tool that you use to find out how much of your application code actually gets tested by your unit tests, which can be a useful indicator of where you need more tests – although it doesn’t say whether your tests are any good or not, even if you have 100% coverage.

Open Source Tools

Being Scottish by blood, I’m a bit of a skinflint, so like most of my other tools I wanted something open source, or at least free.  This actually proved more difficult than I first imagined – most of the code coverage tools seem to be commercial, often part of a larger package.  Some also required that you alter your code to use them, by adding attributes or method calls – definitely not something I wanted to do.  The main suitable one I came across was PartCover, an open source project hosted on Source Forge.  Thankfully, it was easy to install and set up, and did everything I wanted.

Using PartCover

There are two ways of running PartCover – a console application, which you would use with your build process to generate coverage information as XML, and a graphical browser, which lets you run the tool as you like and browse the results.  I should point out I haven’t tried the console part, or using the generated XML reports, which you would probably want to do in a larger-scale development environment along with Continuous Integration etc.

Either way, the first thing you have to do is configure the tool – you need to define what executable it will run, any arguments, and any rules you want to define about what assemblies & classes to check (or not):

PartCover Settings

PartCover Settings

You can see here that I’m running NUnit console – you don’t actually have to use this with unit testing.  If you want, you can just get it to fire up your application, use your app manually, and PartCover will tell you what code was run – which I imagine could come in quite handy in itself in certain situations.  But as I want to analyse my unit test coverage, I get it to run NUnit, and pass in my previously created NUnit project as an argument.

Rules

I also have some rules set up.  You can decide to include and exclude any combination of assemblies and classes using a certain format with wildcards – here I’ve included anything in the ‘ContactsClient’ and ‘ContactsDomain’ assemblies, apart from any classes ending in ‘Tests’ and the ‘ContactsClient.Properties’ class.  It can be useful to exclude things like the UI if you’re not testing that, or maybe some generated code that you can’t test – although you shouldn’t use this to sweep things under the carpet that you just don’t want to face!

Analysis

With that done, just click ‘Start’ and you’re away – NUnit console should spring into life, run all of your tests, and you’ll be presented with the results:

PartCover Browser

PartCover Browser

As you can see, you get a tree-view style display containing the results of all your assemblies, classes and methods, colour coded as a warning.  But that’s not all!  Select ‘View Coverage details’ as I’ve done here, and you can actually see the lines of code which have been run, and those which have been missed.  In my example above, I’ve tested the normal path through the switch statement, but neglected the error conditions – it’s exactly this type of thing that code coverage tools help you to identify, thus enabling you to improve your tests and your code.

At this point, I feel I have to point out a potential issue:

Warning!  Trying to get 100% test coverage can be addictive!

If you’re anything like me, you may well find yourself spending many an hour trying to chase that elusive last few percent.  This may or may not be a problem depending on your point of view – some people are in favour of aiming for 100% coverage, but some think it’s a waste of time.  I like the point of view from Roy Osherove’s Book, that you should test anything with logic in it – which doesn’t include simple getters/setters, etc.

But 100’s such a nice, round number, and I only need a couple more tests to get there..

Follow

Get every new post delivered to your Inbox.

Join 246 other followers