Snooker Kata

I’ve been toying with the following TDD Kata. I like it a lot, it provides just enough complexity that it’s interesting, but not so much that the algorithm needs to be complicated.

The idea is to implement a game of Snooker. I’ll assume you either know the rules of snooker, or can find them here.

We need a class that keeps track of a frame of snooker, including which player is at the table, which colour ball they should be targeting, and provides methods that allow us to tell the class what happens with each shot.

The Methods needed are

Hit(colour)
Pot(colour)
Miss(colour)
InOff(colour)
Nominate(colour)

We also need a number of methods that will give us back details about the state of the two players.

int Score(player)
int HighestBreak(player)
int Potted(player, colour)
  1. Implement Hit(Colour)
    Game will keep track of which player is at the table, and whether they should be hitting a red or another color. If the player hits any red when a red is expected, or any colour when a colour is expected, it shall be deemed a valid hit, and play shall switch to the other player.
  2. Wrong Ball Hit
    If a red is expected but a colour is hit, or vice versa, the game shall detect the foul and award the correct number of points to the other player and play shall switch to that player.
  3. Implement Pot(Colour)
    Same logic as above, however the appropriate number of points shall be awarded to the player at the table and play shall remain with that player.
  4. Implement Miss(Colour)
    This method indicates that the player at the table missed the targeted colour. Award the appropriate points to the opponent and switch player.
  5. Implement InOff(Colour)
    This method indicates that the player potted the cue ball while targeting a player of the suggested colour. Award the appropriate points to the opponent and switch player.
  6. Implement Nominate(Colour)
    This method should be used after the player has potted a red, it designates the desired colour that will be targeted. If Nominate is followed by Hit or Pot of a different colour, that is a foul. Award points to opponent and switch player. if Nominate is followed by Hit or Pot of the nominated colour that is valid, award points to the player and he remains at the table.
  7. Change Nominated Ball
    Allow the player to change nominated ball by simply calling Nominate again, the most recent call counts.
  8. Replace Potted Balls
    Colours are replaced on the table after being potted, reds stay off the table when potted.
  9. No Reds Left
    Detect when all reds have been potted, the players must then play for the lowest valued colour. They can not nominate a different colour. When colours are potted at this stage of the game they remain off the table.
  10. End Of Frame
    Play ends when the table is cleared.
  11. Statistics
    The following statistics should be available for each player at any time during or on completion of a frame:
    Score
    Highest Break
    Number of pots for each ball colour

FitNesse Decision Tables

This entry is part 4 of 5 in the series FitNesse

In the last post, we set up a solution to demonstrate the use of FitNesse. The solution contained a Calculator Project, and a Calculator.Specifications project which contains an instance of FitNesse, and an Acceptance Test fixture for the Calculator project.

To show that everything was up and running we created a simple Decision Table test in FitNesse.
In this post we’ll look more closely and Decision Tables.

Decisions Decisions
A FitNesse Decision Table allows us to supply a number of input parameters and receive back a number of output values. A test passes or fails based on whether the expected outputs match the actual outputs.

In our last post we tested a simple calculation using our Calculator project. Let’s look at the Markup for that Table, line by line.

Line 1 defines the name of the table, and by convention this also tells FitNesse the name of the Class it should try to use when executing the test. In this case FitNesse will search our TestFixtures for a class called DoSimpleMath. Alternatively the Fixture name ‘DoSimpleMatch’ could have been used in the table.

The Exclamation mark at the start of Line one is interesting. If the Table name had been written without spaces as described above, FitNesse would have automatically turned the table header into a link.

The Exclamation mark prevents links being automatically created. Strictly speaking in this instance it’s not needed, since FitNesse does not try to create links where spaces exist. It is however good practice to include the exclamation even when not needed.

Line 2 defines the parameters of the test, but the input values we’ll sent to the test, and the output values we get back. In this case A, B and Op are all input parameters. Result is an output value as indicated by the question mark ‘?’.

Line 3 consists of the values to be used with the Test. We supply 1, 2 and + and we state that we expect the value 3 to be the result of adding 1 and 2.

!|Do Simple Maths  |
|A  |B  |Op|Result?|
|1.0|2.0|+ |3.0    |

Naturally, you can create multiple rows to test various scenarios.

!|Do Simple Maths  |
|A  |B  |Op|Result?|
|1.0|2.0|+ |3.0    |
|5.0|5.0|- |0      |
|2.0|3.0|* |6.0    |
|6.0|3.0|+ |2.0    |

Decision Table Fixtures
As mention above the name of the Table dictates the name of the class that FitNesse will attempt to execute the test.

It may be that a table name and the particular input and output columns are ideal for describing features of the system, but are not good names for objects in our domain model.

This is where Fixtures come in. Generally speaking we don’t want to write FitNesse tests that directly access the domain model. Apart from the fact that good names for tests may not make good interfaces for objects, there is also a brittleness from hooking up directly to a Domain Model that could change.

Test Fixtures provide a level of abstraction between FitNesse and our System Under Test. Fixtures are usually simple pass through objects that invoke the expected behaviour and return apropriate results.

We declare the inputs as public fields. There’s no benefit in declaring properties and private fields in a fixture. We want the simplest possible implementation that allows us to get values in and out.

public class DoSimpleMaths
{
    public decimal A;
    public decimal B;
    public string Op;

    public decimal Result()
    {
        if (Op == "+")
            return Calculator.Add(A, B);

        if (Op == "-")
            return Calculator.Subtract(A, B);

        if (Op == "*")
            return Calculator.Multiply(A, B);

        if (Op == "/")
            return Calculator.Divide(A, B);

        throw new NotImplementedException(string.Format("'{0}' is not an implemented Operator", Op));
    }
}

The following fixture implements the Result output as a function. If your Decision Table includes multiple outputs you can implement each as a separate function for each.

public class DoDivisionWithRemainder
{
    public int A;
    public int B;

    public int Result()
    {
        return A / B;
    }

    public int Remainder()
    {
        return A % B;
    }
}

If the work of the fixture can be implemented in a single method, you could consider the following alternative approach. Use public fields for all inputs and outputs, then use a method called Execute to populate all of the outputs.

FitNesse will run the ‘Execute’ method before evaluating the outputs.

public class DoDivisionWithRemainder
{
    public int A;
    public int B;
    public int Result;
    public int Remainder;

    public void Execute()
    {
        Result = A / B;
        Remainder = A % B;
    }
}

The following FitNesse Decision Table will work with either of the previous two Test Fixtures.

!|Do Division With Remainder|
|A  |B |Result? |Remainder? |
|13 |5 |2       |3          |

Beyond the Basics
We can do some interesting things beyond the basic decision tables shown above. For example if we have inputs that will be the same for each row in the table, we can define it once in the header.

!|AddAFixedPercentage        |10     |
|Principal                   |Result?|
|0                           |0.0    |
|10                          |11.0   |
|100                         |110.0  |

In the above example, the value 10 is passed into the constructor of the fixture. It can then be used for each row, without needing a column for it in the table.

public class AddAFixedPercentage
{
    public decimal principal;
    private decimal _percentage;

    public AddAFixedPercentage(decimal <span class="hiddenGrammarError" pre="">percentage)
    {
        _percentage</span> = percentage;
    }

    public decimal result()
    {
        return Calculator.AddPercentage(principal, _percentage);
    }
}

If you want to pass more than one parameter to the Fixture you can do that. Just add them to the first row in the table. Make sure that the constructor has the correct number of parameters of the correct types to accept the values in the table.

!|FixtureName  |10 |ABC |3.14 |

When testing our expected results against the actual results, we also have options. We don’t need to find an exact match in order to pass a test. Sometimes an approximate match, or a range of values may be sufficient. Let’s remind ourselves of the markup for an exact match.

!|Do Simple Maths  |
|A  |B  |Op|Result?|
|6  |2  |/ |3      |

If we use the ~= operator we can match on approximately equal values.

|22|7|/ |~=3.14      |

22/7 is the famous approximation of PI, but in reality it’s not all that close an approximation. In fact it all goes wrong if you look beyond 2 decimal places. The Test above will pass because at two decimal places, 22/7 matches 3.14.

We can also check that a value is Grater Than another.

|10|1|+ |>10      |

Or that a value falls within a given range.

|5|3|* |14<_<16   |

When Decision Tables Work Best
As mentioned above, Decision Tables are very useful when we have a set of clearly defined Inputs and Outputs. It may seem that most problems can be reduced to this sort of scenario, and that’s probably true, however we’ll see other options in subsequent posts for other types of scenarios.

Aha! Unit Tests – DDDBelfast

Sample Code

On Saturday I spoke at DDDBelfast. My Session was on Unit Testing. After the Test Driven Development session in Bristol, it occured to me that a more fundamental problem was Unit Testing itself. Whether the Tests are Written before or after the code is a non-issue if developers aren’t writing automated Unit Tests at all.

Here are the slides for the session.



The sample Code includes the Wizard project which includes a suite of Unit Tests, you’ll need to install MOQ and NUnit to run all the tests.

Also included are the three examples of injecting mocks, and the example of how traditional NTier code can violate the Single Responsibility Principal, and how to avoid that problem

Any questions about any of this, feel free to get in touch or leave a comment.

Adding FitNesse to your .Net Solution

This entry is part 3 of 5 in the series FitNesse

Sample Code

In the last post I mentioned Jeff Kwak’s blog post on FitNesse, specifically his way of creating a FitNesse wiki within your .Net solution.

The rest of the posts in this series will use a particular arrangement of projects based heavily on Jeff’s approach.

I’m not going to rehash his post, however I did have a few problems getting things to work the way Jeff did, and I also wanted to do some things a little differently. In this post I’ll discuss where my approach differs from his.

I’m providing a very basic Solution with FitNesse included and we’ll walk through creating and passing a first Test. Subsequent posts in this series will build incrementally on this Solution.

A Sample Solution
Download the attached zip file and extract it somewhere on your dev box. Mine is extracted to C:\Projects\FitNesseTutorial.

Open the resulting Solution. It has two Projects, Calculator (our system under test) and Calculator.Specifications (our tests).

Let me apologise right now for going down the well-trodden path of simple calculator examples. My goal with these first few posts is to get you using FitNesse in the simplest possible way. There will be time later to consider more realistic examples of how FitNesse might be used in real projects.

I’m not going to try and find some grand integrated application that illustrates all of the features of FitNesse. I will use simple standalone examples as required to best illustrate what I’m talking about.



Before we start worrying about FitNesse, build the solution. It should build successfully without any changes.

Setting up External Tools
This next step is optional, but I think it’s worth doing. I’d like a way to start and stop the FitNesse server from within Visual Studio, and pop up a browser running the Wiki, also from within the IDE. What I’ve got is not as clean as I’d like, but it’ll do until I find a better way.

Starting FitNesse
The sample Solution includes a batch file that runs FitNesse. The first thing we’re going to do is create an External Tool in Visual Studio to run that batch file.

In the External Tools Dialog, Add a Tool called ‘FitNesseStart’. Set the Command to

$(SolutionDir)Specifications\AcceptanceTests\startfitnesse.bat

set the Initial directory to

$(SolutionDir)Specifications\AcceptanceTests

and check the Use Output window checkbox.

The results should look like this



Opening FitNesse in the Browser
You need only start FitNesse once when you load your project. This starts the FitNesse server running. You seperately navigate to the FitNesse wiki using your browser.

You can start and stop your browser as often as you like, the server will keep running in the background.

We’ll set up another External tool which will load the Wiki on the proper page.

In the External Tools Dialog, Add a Tool called ‘FitNesseBrowser’. Set the Command to

Explorer.exe

set the Arguments to


http://localhost:9092/AcceptanceTests

The results should look like this



Stopping FitNesse
As mentioned above, the FitNesse server will continue happily running away in the background even when you start and stop your browser. Visual Studio External Tools provides a mechanism for shutting down tools, however it doesn’t work for FitNesse.

For now the only solution I’ve found is a separate Tool.

The sample Solution includes another batch file that closes FitNesse.

In the External Tools Dialog, Add a Tool called ‘FitNesseStop’. Set the Command to

$(SolutionDir)Specifications\AcceptanceTests\stopfitnesse.bat

set the Initial directory to

$(SolutionDir)Specifications\AcceptanceTests

The results should look like this



Here’s a curious little thing to note. If you look in the Solution Folder you’ll notice that the Calculator.Specifications project is in a folder called ‘Specifications’, and not ‘Calculator.Specifications’.

This is to make the configuration of the External Tools more generic. It means that when you load a different solution, the external tools will Start and Stop that Solutions own instance of FitNesse, as long as they too are kept in a folder called ‘Specifications’.

The first run
The first time you start FitNesse, the jar file will be extracted to create the Wiki. You saw this in the earlier post. Once everything is extracted the FitNesse server starts running. It all looks like this



First view of the Wiki
With FitNesse running, it’s time to take a look at our Wiki. Select the FitNesseBrowser tool from the Tools menu. What you see should look something like this



Not what you were expecting? Were you thinking you’d see the FitNesse Front Page?

What we’ve done here is make the Tool jump to a specific page in the Wiki, and not going to the regular Front Page. This avoids the need to navigate to our tests every time we start the Wiki.

Since we haven’t created this page yet we’re asked to edit it. So, let’s do that, copy and paste the following code, overwriting the existing contents of the page.

!path bin\Calculator.Specifications.dll

!|import |
|Calculator.Specifications.Fixtures|

This should do simple arithmetic

!|Do Simple Maths |
|A |B |Op|Result?|
|1.0|2.0|+ |3.0 |

Save those changes, but we’re not done with this page yet. Click on the Properties button and change the Page type to ‘Test’. Save the properties and you’ll now see that all important Test Button.



You can click it if you like but it won’t work yet. We have one more piece of setup to do first.

In your Browser, navigate to the URL


http://localhost:9092/root

Edit the ‘root’ page and overwrite the contents with the following

!define TEST_SYSTEM {slim}
!define COMMAND_PATTERN {%m -r fitSharp.Slim.Service.Runner,bin\fitsharp.dll %p}
!define TEST_RUNNER {bin\Runner.exe}

This tells FitNesse to use SLiM which is one of the two protocols that FitNesse can use for linking tests to code. We’re running the implementation of SLiM provided by fitsharp which lets us work with .Net assemblies.

Yes, we could have inserted this bit of configuration at the top of every Test Page, but by putting it in root we can forget about it and stop cluttering up our tests.

Save this page and return to


http://localhost:9092/AcceptanceTests

Now when you click Test, it should work. We have a Test that runs. Admittedly it’s a failing Test, but that’s what we want as a first step.



To get this test to pass we need to look at our code. Our Calculator class throws NotImplementedExceptions rather than implement the actual required logic.

public class Calculator
{
public static decimal Add(decimal a, decimal b)
{
throw new NotImplementedException("Add");
}

public static decimal Subtract(decimal a, decimal b)
{
throw new NotImplementedException("Subtract");
}

public static decimal Multiply(decimal a, decimal b)
{
throw new NotImplementedException("Multiply");
}

public static decimal Divide(decimal a, decimal b)
{
throw new NotImplementedException("Divide");
}
}

Let’s fix that Add method, rebuild and retest.

public static decimal Add(decimal a, decimal b)
{
return a + b;
}



If you’ve made it this far you now have a Solution that has a project under test and a project that has the tests themselves along with all the binaries needed to run FitNesse and use it to test .Net code.

We’ve set up some External Tools in Visual Studio that will make life a little easier.

If you’re a little unsure about how this all hangs together, don’t worry. Over the remaining posts in this series I’ll did a little deeper into the things you can do with FitNesse, and along the way you’ll learn what all the parts of the puzzle are. All posts will use this Solution structure as a basis.

Fluent Mocking

In which our hero shouts “Hold on thar pilgrims” at those who would hate Mocking Frameworks.

Here’s a scenario (for once not a hypothetical scenario, this is a real system I worked on). You’re building a wizard based app. To be more accurate you’re building lots of wizard based apps, so you’ve extracted all the wizardy stuff up into it’s own classes. Your apps can now focus on actual bread and butter functionality. When I say ‘You’ I mean ‘I’ but this is a writing device that sucks you into the narrative. I bet deep down you already care a little bit about how these Wizards turned out.

Two of the objects in your Wizardy Stuff code are a ‘Wizard’ and a ‘WizardStep’. A Wizard obviously contains a number of WizardSteps. You get the idea.

There are quite a few tests that we can write to make sure that navigation works. A Wizard has a current step, Moving Next or Previous should increment or decrement the current step. Moving next on the last step causes the Wizard to finish. It’s all very simple, and what you’d expect from a wizard.

Let’s look at an example of the kind of tests we might have to write, and what it means in terms of mocks and stubs. We have a requirement that says that when the user clicks ‘Move Next’ the current step gets to validate itself and decide whether it will allow the Move Next to happen. If it returns false, the Wizard will refuse to allow the user to move on.

To test a feature like this we can do the following:

  • Create a wizard with one step
  • Use a stub for step1 that returns false when the OKToMoveNext method is called
  • Start the wizard
  • Assert that we’re on the first step
  • Attempt to move next
  • Assert that we’re still on the first step

After the attempt to MoveNext we should still be on step1 (because step1 returns false when asked to validate itself).

We can implement the test in various ways. A key issue is how to implement the stub for step1 that simulates a step failing validation. Here’s one example, using the Moq Framework:

	// Listing 1
        [Test()]
        public void Validation_CanPrevent_MoveNext()
        {
            Mock<IWizardStep> step1 = new Mock<IWizardStep>();
            step1.Setup(s => s.OKToMoveNext()).Returns(false);

            Wizard wizard = new Wizard()
                                    .AddStep(step1.Object)
                                    .Start();

            Assert.AreEqual(step1.Object, wizard.CurrentStep);

            wizard.MoveNext();

            Assert.AreEqual(step1.Object, wizard.CurrentStep);
        }

I don’t like this code. It’s too busy. There’s too much “stuff” that’s related to the mocking framework. The intent of the test might be discernible, but only just. The shaded lines in particular need a second or third glance to make sure you’re reading them right. Our intent is to create a stub wizard step that can’t move next. Our test should be screaming that intent so clearly that it cant be missed by someone reading the code.

I suspect that scenarios like this are one of the reasons why some developers find themselves edging back towards hand-rolled mocks and stubs. The equivalent code using hand-coded classes is much simpler and the intent of the test is clearer:

	// Listing 2
        [Test()]
        public void HM_Validation_CanPrevent_MoveNext()
        {
            IWizardStep step1 = new WizardStepThatIsNotOKToMoveNext();

            Wizard wizard = new Wizard()
                                    .AddStep(step1)
                                    .Start();

            Assert.That(wizard.CurrentStep == step1);

            wizard.MoveNext();

            Assert.That(wizard.CurrentStep == step1);
        }

The shaded code tells most of the story. Because we’re creating a simple class for a specific purpose, we can be very explicit with our naming.

Although listing 2 is an improvement over the code we produced using the Moq mocking framework, it’s not without it’s troubles. Our suite of tests is going to need a lot of different mocked WizardSteps to cover the various scenarios. Many will be very similar, or will have parts that are identical to parts of others. For example, we might have half a dozen version of the class that need to prevent a user Moving Next, but each may need to do that in conjuction with some other different behaviour.

We could try to make our Handmade mocks more intelligent, but that’s a slippery slope. Once you start adding in “one more little tweak, to facilitate one more test”, you quickly find yourself with a mock that’s more complex than the code you’re trying to test.

One interesting option is to go back to using our Mocking Framework, but hide the messiness of it behind a slightly nicer abstraction. Imagine being able to write a test like the one in Listing 3:

	// Listing 3
        [Test()]
        public void step_can_stop_move_next()
        {
            IWizardStep step1 = new MockWizardStep()
                                    .ThatCannot.MoveNext
                                    .Object();

            Wizard wizard = new Wizard()
                                    .AddStep(step1)
                                    .Start();

            Assert.AreEqual(step1, wizard.CurrentStep);

            wizard.MoveNext();

            Assert.AreEqual(step1, wizard.CurrentStep);
        }

This is a fluent style interface, but behind the scenes it’s doing all the same stuff that our first test did. The beauty of a mocking framework is that you can assemble the functionality you desire at runtime, rather than needing to code a specific class for the specific case you want to test. Once you’ve written the Factory that spits out mocks, you can use it to spit out other variations of the MockWizardStep:

	// Listing 4
            IWizardStep step1 = new MockWizardStep()
                                    .ThatCan.MoveNext
                                    .Object();

            IWizardStep step1 = new MockWizardStep()
                                    .ThatCan.MoveNext
                                    .ThatCannot.MovePrevious
                                    .Object();

Once you have the fluent interface in place it gets a lot easier to create exactly the right mock for the scenario you want to test. The test becomes clearer, and to a certain extent you’ve abstracted your tests away from the specific mocking framework that you are using.

It’s not all ribbons and bows. One problem is that you have to actually build the fluent interface. You can’t really make a generic one of these. A fluent interface by it’s nature is a Domain Specific Language. You implement a language based on the properties of the objects you’ll be mocking.

Creating the Fluent Interface isn’t a particularly complicated task (see Listing 5), but it’s enough work that you need to think carefully about whether it will pay for itself. The example here is also artificially simple, showing only a few stub methods. When you get into creating a fluent interface that allows you to configure Mock behaviour, like verifying method calls etc, things could get a little hairy.

It’s worth looking more closely at the shaded code in Listing 5, we what appears to be a readonly property, modifying fields within the class. What madness is this? It’s nothing really, just a trick used in constructing fluent grammars to avoid having parenthesis after every term in a statement.

    // Listing 5
    public class MockWizardStep
    {
        private Mock<IWizardStep> _step;
        private bool _thatCan = true;

        public MockWizardStep()
        {
            _step = new Mock<IWizardStep>();
        }

        public MockWizardStep ThatCan
        {
            get
            {
                _thatCan = true;
                return this;
            }
        }

        public MockWizardStep ThatCannot
        {
            get
            {
                _thatCan = false;
                return this;
            }
        }

        public MockWizardStep MoveNext
        {
            get
            {
                _step.Setup(v => v.OKToMoveNext()).Returns(_thatCan);
                return this;
            }
        }

        public MockWizardStep MovePrevious
        {
            get
            {
                _step.Setup(v => v.OKToMovePrevious()).Returns(_thatCan);
                return this;
            }
        }

        public IWizardStep Object()
        {
            return _step.Object;
        }

        public Mock<IWizardStep> Mock()
        {
            return _step;
        }
    }

So, where does that leave us? Are mocking frameworks saved from those who would hate them? Well, probably not, but for everyone else here’s one more tool in your toolbox for that day when the perfect scenario presents itself.

So Over Mocking Frameworks

In which our hero peddles more of the stuff that wasn’t good enough to make it into his TDD Session, and passes it off as an interesting blog post. Welcome to the blog equivalent of the “extras” section of a DVD.

During the course of preparing and presenting my session on Test Driven Development, I had quite a few interesting conversations with quite a few interesting people. Some were the face to face kind of chats that you inevitably have after presenting a session, some were via email.

One theme that popped up more than once was the notion of being “over” mocking frameworks. And when I say “over” I mean it in the “girlfriend from college that you’d rather not see any more” sense of the word.

It appears that when it comes to mocking, TDD practitioners go through a number of phases.

  • Ignorance – How to I test this object, it has all these dependencies?
  • Interest – Hmmm I can create classes that implement the same interface as a dependency.
  • Excitement – Holy crap, mocking frameworks are da shizzle, I want to use them everywhere.
  • Hmmm – Why is it complicated to do this with a mocking framework. A hand coded class would be so much simpler.
  • Disillusionment – Holy crap, mocking frameworks are a pain, I don’t want to use them anywhere.
  • Righteous Indignation – Dude! You’re using Mocking Frameworks? that’s like so 2009.
  • Perspective – Mocking frameworks, handrolled? Meh! Both have their place

As with virtually everything else in life, extreme views for or against Mocking frameworks are unlikely to be helpful to anyone. They’re a tool. Ignoring them completely (or consciously not using them) is no more helpful than surrendering to them and using them blindly.

In a future post I’ll look at how to mitigate some of the issues that cause people to “get over” Mocking Frameworks. I’ll also look at some of the issues that need to be addressed when using hand rolled mocks and stubs.

Test Driven Development – Pushing Through The Pain

Sample Code
TDD Sample Code for DDD South West

Last weekend I presented a session on Test Driven Development at DDD South West in Bristol. I actually presented the session twice thanks to being voted onto the repeat track, and in total I had 120 brave souls who came along to see the session.

I’ve taken the past week to go back over the sample code that accompanies the session and tidy it up a bit, add some ‘discussion’ comments about various issues, and also factor in a few suggestions that I received on the day.

The code can be downloaded from the link at the top and bottom of this post. The slides can be viewed here:



Thanks to everyone who came along, that especially to everyone who left feedback, and virtually everyone did. This session started with a 90 minute running time, I cut it to 1 hour for DDD South West, but it still felt a little rushed. My hope is to cut it dramatically in time for DDD North (if I’m fortunate enough to be invited) and cover less ground, but in more detail and with more time for interaction and questions from the floor.

If you have any problems with the code, or if you’d like to point out some issues with it then leave a comment or find me on twitter (@richardadalton).

Thanks for stopping by.

Sample Code
TDD Sample Code for DDD South West

Retro Fitting Unit Tests to Legacy Code

This post references a StackOverflow thread which you can read
here

One of the problems with TDD is that those who try it, often begin by booting up NUnit or something similar, writing a few trivial tests to get the lie of the land, then instead of doing TDD (i.e. Writing a test and then writing some code to make the test pass) they do something much much harder, under the mistaken impression that it will actually be a way to ease themselves into TDD.

They do what I did, they start out by trying to write some unit tests for existing code. Either a past project, or more likely the project they are currently working on. They quickly discover that these projects are (from their perspective) virtually impossible to test.

The reason why is obvious, 1) They are new to writing automated tests, which is a tricky enough skill to master, but more importantly 2) They are new to writing testable code which is actually a significantly bigger challenge than writing tests. The chances that their old projects contain testable code is virtually nill.

So, our protagonist is actually starting their journey to TDD with an obstacle that is actually beyond the ability of some seasoned TDD practitioners. Think a video game with the ultimate Boss level as the very first thing you do, before you learn the controls or understand much of anything about the game. That right there is a game that you’ll probably throw in the bin after about an hour, if you last that long.

In my research for my TDD session at #dddsw I found lots of interesting questions, blogs and articles, most of which I didn’t have time to fully discuss during the session, but I’ll point you in the direction of some of them over the next few days/weeks.

The first is a Stack Overflow discussion on how to write automated tests for a complicated function with lots of dependencies.

It’s notable because it’s not an uncommon problem, and the answers cover the usual spectrum from practical solutions to pragmatic advice to questioning the validity of the original question etc.

It’s also notable because Uncle Bob contributes an interesting Step By Step on how to add tests to existing code (in an kludgy way) and then how to refactor both the original code and the kludgy test handling.

Original Thread Here

Enjoy.

Switch to our mobile site