Test Driven Development (TDD) vs. Traditional Testing

TDD can get you pretty far, but integration testing is necessary.

The subject of this post is a bit of a misnomer, because the two are not mutually exclusive. That is to say, test driven development is not a replacement for testing. In fact, test driven development has less to do about testing than it does about design. TDD should drive your class design in such a way that makes it easier to get to the real testing phase. There are certain cases that are not going to be apparent during the initial class design, so when developing any application, testing should begin as soon as possible. TDD Can get you there faster, because a lot of the pieces of the application can be faked since the design is testable!

Anything that gets mocked in a unit test can be faked in a built and deployed application, so business users, UX specialists, and designers will get a chance to play with the app to tweak requirements very early in the process! This early change is a lot less risky than late change when an application is “done” because the whole system is less complex.

Take for example my most recent project for which I am using TDD. It is a gesture library for desktop games using XNA (not windows 8 store games). I created a GestureProvider object which relied on an ITouchEventProvider interface to receive raw TouchEvent objects and return GestureSample objects. Using just four conceived objects, I wrote some simple tests that would prove Tap, Drag, and Pinch gestures could be detected given the proper touch events.

The tap test went something like…

[TestMethod]  
public void single_tap_registers_from_one_touch()  
{  
    // Given a mock ITouchEventProvider that returns the following
    _container  
        .Arrange<ITouchEventProvider>(p => p.Events)  
        .Returns(new List  
        {  
            new TouchEvent  //    touch down at 0,0
            {  
                Id = 1,  
                Position = Vector2.Zero,  
                Action = TouchEvent.TouchEventAction.Down,  
                TimeStamp = DateTime.Now  
            },   
            new TouchEvent  //    touch up at 0,0
            {  
                Id = 1,  
                Position = Vector2.Zero,  
                Action = TouchEvent.TouchEventAction.Up,  
                TimeStamp = DateTime.Now.AddMilliseconds(200.0)  
            }  
        });  

    var gestureProvider = _container.Instance;  

    // Get gestures from the real GestureProvider object (system under test or SUT)
    var samples = gestureProvider.GetSamples();  

    // Assert that there is one GestureSample object for a Tap at 0,0 
    var gestureSamples = samples.ToList();  
    Assert.AreEqual(1, gestureSamples.Count);  

    var tap = gestureSamples[0];  
    Assert.AreEqual(Vector2.Zero, tap.Delta);  
    Assert.AreEqual(Vector2.Zero, tap.Delta2);  
    Assert.AreEqual(Vector2.Zero, tap.Position);  
}

I did that test, and another for Drag and Pinch. Everything seemed to be going so well that I wanted to test them out, because I had a sneaking suspicion that I was missing something. I wrote up a quick test for a real ITouchEventProvider implementation that would use an interop library to listen for events, and provide them to the GestureProvider. I fired up a real game and added the necessary code to use the GestureProvider. I noticed one thing right away: Tap was not registering as a tap, but instead it was a drag. I double checked my tests, and it all looked ok, so I had to debug a bit. Eventually I found that my assumption about what events would fire for a tap was flawed. There could be any number of “move” events between “down” and “up”. I made the quick fix to add one move event to the test arrangement and fixed the GestureProvider so that the test passed, and then it worked. This proves that integration testing is a very important step in any system.

My unit test alone did not make the whole system work, but via TDD, I had a designed the classes such that there was a clear path to fix the test so that it satisfied the real-world scenario instead of the erroneous assumption I made. Chalk up another TDD win!

How does JavaScript Scope work?

In a previous post, I reviewed how JavaScript treats the “this” keyword.. In this post, I want to talk about how JavaScript defines scope. As a C# programmer coming to JavaScript a few years ago, I did not know this fact, and thus I assumed my C# knowledge of “this” and scope would follow to JS.

Only functions create scope in JavaScript

Take the following C# code for example:

public int x = 1; // this is a class member, and thus is scoped to the class instance
void Foo()
{
    if (true)
    {
        int i = 1;
    }
    // i is inaccessible here, because it is scoped to the if block
}

And the following javascript code:

var x = 1; // Variables not declared in a function are global
function foo() {
    if (true) {
        var i = 1;
    }

    alert(i); // This is perfectly legal, and I is accessible here.

    // Any variables declared here are scoped to the function foo.
    // To force scope:
    (function () {
        var y = 1;
        z = 2; // Declare a variable in the global scope by leaving out the var keyword!
    })();
    // y is not accessible here, because it was declared inside of a function
    // an anonymous self executing function still creates scope
}

alert(z); // z is undefined
foo();
alert(z); // z is 2 after running foo().
alert(window.z); // z is attached to the window object because it was declared without var!

Pay attention to the comments, please. Especially the bit about leaving out var, creating a globally scoped variable attached to window.

This can be a big sticking point for developers coming from C# or Java where scope is very different. Many bloggers will take this type of post to the extreme and explain other concepts like closures and prototype, as well as combining the topic of context binding the “this” keyword, but I am keeping this succinct for a reason. I’ve already covered “this” in a previous post, and I can probably do a post on closures and using the prototype more in depth another time.

In my opinion, this topic stands on its own as one of the most confusing points for a developer that is new to JavaScript, so it deserves a separate post.

Multi touch and gesture input in Windows with DPI scaling

I mentioned in a previous post that I am working on a new project related to gesture input. That very day, I hit a wall regarding desktop scaling, and last night I broke through it! Perhaps a topic for another post: with some applications, TDD can get you to a certain point, but integration testing is a must pretty early on.

The FRBTouch project is no exception! There are a few different problems to solve with this project:

  • Touch event capturing
  • Gesture detection
    • Taking touch events and making gestures
    • e.g. One touch event down then up is a tap
  • Coordinate translation
    • Taking window coordinates and translating them in an application (e.g. a FlatRedBall game)

The first two bullet points turned out to be the easiest, because they were mockable. For instance:

        public void single_tap_registers_from_one_touch()
        {
            // Arrange
            _container
                .Arrange<ITouchEventProvider>(p => p.Events)
                .Returns(new List<TouchEvent>
                {
                    new TouchEvent
                    {
                        Id = 1,
                        Position = Vector2.Zero,
                        Action = TouchEvent.TouchEventAction.Down,
                        TimeStamp = DateTime.Now
                    },
                    new TouchEvent
                    {
                      Id = 1,
                      Position = Vector2.Zero,
                      Action = TouchEvent.TouchEventAction.Move,
                      TimeStamp = DateTime.Now.AddMilliseconds(10)
                    },
                    new TouchEvent
                    {
                        Id = 1,
                        Position = Vector2.Zero,
                        Action = TouchEvent.TouchEventAction.Up,
                        TimeStamp = DateTime.Now.AddMilliseconds(200.0)
                    }
                });
            var gestureProvider = _container.Instance;

            // Act
            var samples = gestureProvider.GetSamples();

            // Assert
            var gestureSamples = samples.ToList();
            Assert.AreEqual(1, gestureSamples.Count);

            var tap = gestureSamples[0];
            Assert.AreEqual(Vector2.Zero, tap.Delta);
            Assert.AreEqual(Vector2.Zero, tap.Delta2);
            Assert.AreEqual(Vector2.Zero, tap.Position);
        }

That’s the test that proves a tap gesture is detectable given how the touch events are provided. It was easy to setup a mock scenario for drag and pinch as well, and just assert the required gesture return values. The TouchEvent object maps pretty closely to the events that User32.dll provides, also, so there wasn’t that much to test for actually capturing events.

The major problems came when attempting to translate coordinates from touching an XNA game window into world coordinates. I use a surface pro for all development, and it is pretty much a necessity to have 150% scaling on at all times, because the size of the screen is small. Windows scales all windows up, but in doing so it breaks the coordinate system for touch input. This is not something you can see or solve with test driven development (at least not traditional unit tests), because it requires a live scaled window and graphics object to operate.

To solve the problem, one simply has to disable the auto scaling, and tell Windows that the application will handle understanding the DPI settings. You have to make your application DPI Aware. (More info). The window will then not auto-scale, and the coordinate system will not be broken, so normal translation routines will work.

Touch Input in Windows 7 or 8 desktop mode.

I am the proud owner of a Surface Pro 128GB, a Lumia 822, and I had an HTC Trophy Windows Phone 7 when it first came out. I have been an XNA enthusiast since about 3.1, and I have blogged about input management before. I only mention this because I am a fan of the Gesture API that the XNA team released for WP7. A decision they made, though, was to release that API only for WP7 and left it out of the XNA 4 PC libraries. I decided to write a library to do gesture sampling in a very similar way!

I am excited to announce a new project I am working on! Though named FRBTouch (because eventually it will aim to integrate with the FlatRedBall engine), will have components that will work on any system with the XNA libraries installed. It already detects gestures like tap, freedrag, and pinch, providing GestureSample objects that are identical to the XNA WP7 implementation!

Here is some example code that already uses the library in an XNA game:

    public partial class TouchScreen
    {
        private GestureProvider _gestureProvider;

        void CustomInitialize()
        {
            _gestureProvider = new GestureProvider(new QueueingTouchEventProvider(FlatRedBallServices.Game.Window.Handle));
        }

        void CustomActivity(bool firstTimeCalled)
        {
            var gestures = _gestureProvider.GetSamples();

            if (gestures != null)
            {
                foreach (var gestureSample in gestures)
                {
                    switch (gestureSample.GestureType)
                    {
                        case GestureType.Tap:
                            FlatRedBall.Debugging.Debugger.CommandLineWrite("Tap");
                            break;
                        case GestureType.FreeDrag:
                            FlatRedBall.Debugging.Debugger.CommandLineWrite("Drag");
                            break;
                        case GestureType.Pinch:
                            FlatRedBall.Debugging.Debugger.CommandLineWrite("Pinch");
                            break;
                        case GestureType.DragComplete:
                            FlatRedBall.Debugging.Debugger.CommandLineWrite("DragComplete");
                            break;
                        case GestureType.PinchComplete:
                            FlatRedBall.Debugging.Debugger.CommandLineWrite("PinchComplete");
                            break;
                    }
                }
            }
        }
    }

Think of the CustomInitialize function as the constructor,and the CustomActivity function as the game loop (this is just how Glue from FRBDK organizes a screen).

I hope to be completing out the gestures and adding flags to enable and disable certain gestures as time goes on!

JavaScript and the “this” keyword

One of the things that tripped me up when I first learned JavaScript was the “this” keyword. I came from a pure OO world, where classes were clearly defined objects, and “this” always referred to the object in context. JavaScript is a prototype based scripting language, though, and as such, doesn’t have the concept of a class. The “this” keyword means something very different in JavaScript.

According to the ECMAScript language specification:

The this keyword evaluates to the value of the ThisBinding of the current execution context. 

And the “ThisBinding” keyword is:

The value associated with the this keyword within ECMAScript code associated with this execution context.

So, both definitions refer to the other, which I was always taught in elementary school was not to be done! In my opinion, this definition is rather useless to the new JavaScript developer. Practical examples are much more useful!

In JavaScript in a browser, all global functions are bound to the Window object. You can see the behavior by running this bit of code in any browser’s developer console:

(function () {
    console.log(this); // [object Window]
})();

It’s a self executing function that exists in the global scope, and the console.log(this); line should write out [object Window] or something similar. That’s because “this” is a reference to Window. In a function like this, anything that exists on the Window object is also available through the “this” keyword:

(function () {
    this.alert(0);
})();

Because the alert function exists in the global scope, it is attached to the Window object. A related phenomenon occurs when you declare global variables:

hello = function() {
    alert('hello');
}

(function () {
    this.hello(); // same as calling window.alert('hello');
})();

This is the default behavior, but that’s only when functions are declared, or rather, bound to the global scope when executed. One can easily rebind a function with .call() or .apply():

var newobj = {
    alertit: function (message) {
        alert(message);
    }
};

var func = function (message1, message2) {
    this.alertit(message1 + " " + message2);
};

func.call(newobj, 'hello', 'world'); // alerts hello world
func.apply(newobj, ['hello', 'world']); // alerts hello world

the .call() and .apply() functions are both used to change the “this” keyword binding, or the “ThisBinding” as described in the ECMAScript spec. They do the exact same thing, but they pass parameters into the called function differently. The .call() function takes a dynamic parameter set, and the .apply() function takes an array of parameters. Either way, you can see that ‘func’ is called the same way, with its “this” keyword bound to the newobj object.

In the case where a function is already scoped to an object, the “this” keyword will reference the parent object:

var NewObj = function () {};

NewObj.prototype.alert = function (message) {
    alert('NewObj alert: ' + message);
};

NewObj.prototype.test = function (message) {
    this.alert(message);
};

var newobj = new NewObj();
newobj.test('test'); // alerts NewObj alert: test
newobj.test.call(window, 'test'); // alerts test

In this case, the first newobj.test() is called while using the default binding, which is the instance of NewObj that was created, so when it calls this.alert(), it is calling the object’s prototype.alert() function.

The second time it is called, I forced a rebind to the window object, by using .call(). This causes the normal global alert() function to be the one called, since in this call, “this” is bound to window.

I hope this clears up a common problem for someone. I certainly had a hard time understanding “this” when I first learned JavaScript, but hopefully it makes more sense after seeing a few examples.

King Randall’s Party by Jesse Crafts-Finch

A friend and fellow indie developer who is trying to make it on his own has launched a Kickstarter campaign for his game, King Randall’s Party. King Randall’s Party is a mash-up between a Minecraft and tower defense. I love the concept, and I backed his game.

He has been working on the game for a while now, and he’s using the FlatRedBall engine, while using some of the tile map technology that I developed. King Randall’s Party actually drove some of the requirements for what I wrote, so he helped me as well.

Please back his project for whatever you can. I know this blog is not high traffic or anything, but I hope it reaches some people at least!

Experiment: Switching from Chrome to IE10

A long time ago, I was a Linux enthusiast. I grew up in a time where all the cool geeks hated Microsoft, but we didn’t really know why. So, we looked to Linux to save us from the evil corporation, and we installed Linux distributions on our extra hardware or dual booted it. We lived in shell accounts and command lines and secretly dreamed of graphics. At some point in my life, probably when XNA came out, I changed my viewpoints. Now, most people would label me a Microsoft “fanboy”, but I am not convinced that is the case. Closer to the truth is the fact that Google has been scaring me for some time with how much data they’re collecting, and they have been retiring tools left and right. I have been slowly moving all of my services to the Microsoft stack and it has meant a better experience so far. I switched from Gmail.com to Outlook.com a while back and love it, switched from Google.com to Bing.com and love it, and I barely used Google docs, but I find that the Skydrive document interface is a lot closer to office anyway! The one thing I still use for the majority of my web browsing has been Chrome. Until yesterday.

I made the switch! I got the patch! I went cold turkey! Whatever!

The worst of it is that I miss my Ctrl-K shortcut, but I have been dealing just fine. Favorite sync isn’t there yet, but there are ways to do it. If I find that I really do need it, I can always change my favorites to point to my Dropbox folder. It’s not a scary thing. It’s just a web browser, right?

Latest changes

I just got done adding a bunch of sites as authentication sources, and therefore I made it required to have a login to post comments. That said, the login doesn’t have to be with the blog itself anymore, because you can use many different social media sites to authenticate with GeekPowers.com now!

I added a ton, so hopefully your favorite is listed. Please, anyone is welcome to comment, and I welcome feedback of all kinds!

I also added a new background to the site that I made from a cheeky unit test. I figured it was better than a plain background, and it’s real code. I had to tweak a lot of the styles and images to look good with the dark background, so hopefully it all works. If you notice something wrong, please let me know!

Test driven development (TDD) should drive your class design (Part 2 of 2): The right way

Update (9/16/2013): Example source code is now attached, including source for parts 1 and 2.

In the previous post, I proposed a simple example:

You work for Company A, and they want you to write a simple web portal for them. You learn that there is a process in place already that spits out about 30 images as email attachments, and they would much rather see these displayed on a web site. The images will have to be categorized into main, sub, and chart type

In that post, I outlined how one might develop a library for such a site without TDD. Erase that code from your memory. DELETE.

In this post, I will be showing how test driven development can vastly improve the flexibility of the code you write, using the same example. I will be using a 3rd party tool called JustMock from Telerik. I highly recommend at least finding some mocking tool, as this will greatly enhance the TDD process. You can read a previous post for more on the subject of dependency injection, IoC, and mocking. It is through these principles and patterns that TDD becomes a really powerful method for class design. Let’s get started!

Sometimes staring at a blank test class can be rather daunting.

dont-panic-circle

Calm down!

DON’T PANIC!

LET GO!

*SLAP*

Feel better? Me too… I got to slap you!

In all seriousness, think of the test area as your white board. Your API isn’t written yet, but you get to use it already!

What is the most basic thing you need to do? Load charts from somewhere right? What holds things? A container? Perhaps… but, let’s call it a Repository. We know it needs to return an enumerable collection of Chart objects. We also know that something is going to depend on this “Repository” object to load its charts from. Let’s say we haven’t settled on the architecture yet (MVC, WebForms, HTML5 with a WebAPI service). We need to test that SOMETHING can load the charts using a repository just to get started, so let’s call it ChartLoader. I think we have enough to write our first unit test. I typically start by renaming the class and first test method, and inserting my standard AAA comments:

	[TestClass]
    public class when_loading_charts
    {
        [TestMethod]
        public void chart_loader_returns_charts_from_repository()
        {
            // Arrange
            // Act
            // Assert
        }
    }

TDD has a cadence to it. You will:

  1. Write a test.
  2. The you run all tests.
    1. New test fails because the requirement isn’t met yet
  3. Do the simplest thing to make all tests pass again
  4. Refactor
    1. Only after everything passes do you refactor. It may be tempting, but don’t do it earlier! Get a good baseline first.
  5. Repeat for the next requirement

The first test

	[TestMethod]
	public void chart_loader_returns_charts_from_repository()
	{
		// Arrange
		var container = new MockingContainer<ChartLoader>();
		container.Arrange<IChartRepository>(r => r.Charts).Returns(new List<Chart>
		{
			new Chart
			{
				FileName = "file1.png",
				Category = new ChartCategory
				{
					Main = "main",
					Sub = "sub",
					Type = "type"
				}
			}
		});

		// Act
		ChartLoader loader = container.Instance;
		IEnumerable<Chart> result = loader.GetCharts();

		// Assert
		Assert.AreEqual(1, result.Count());
		Assert.AreEqual("file1.png", result.First().FileName);
		Assert.AreEqual("main", result.First().Category.Main);
		Assert.AreEqual("sub", result.First().Category.Sub);
		Assert.AreEqual("type", result.First().Category.Type);
	}

So, we have a test for this fictitious ChartLoader object, and we know it needs to load from a repository, so ChartLoader needs some abstract definition of a repository (IChartRepository), and we know it needs to get charts… IChartRepository.Charts is going to be an IEnumerable, but it’s undefined so far. The Arrange call is essentially setting up a return value from the chart repository, so that when ChartLoader hits it, it will get the list as defined in the .Returns() call. We’ll see that in the next code section. So, the next thing to do is call the method in the ChartLoader to get the charts, and then assert that everything the ChartLoader returned, matched exactly what the repository returned (and you know exactly what it’s going to return, because you mocked it!)

So now there is a test with a bunch of red lines, because nothing is real yet. This is why I love tools like ReSharper, which let me auto generate the classes very quickly. What gets generated:

    public interface IChartRepository
    {
        IEnumerable<Chart> Charts { get; }
    }

    public class ChartLoader
    {
        public IEnumerable<Chart> GetCharts()
        {
            throw new NotImplementedException();
        }
    }

    public class ChartCategory
    {
        public string Type { get; set; }
        public string Main { get; set; }
        public string Sub { get; set; }
    }

    public class Chart
    {
        public ChartCategory Category { get; set; }
        public string FileName { get; set; }
    }

Now, the test will fail, but at least everything compiles. This is where you go to step 4 in the process. Do the simplest thing to make all the tests pass. In this case it’s 1 test, but get in the habit of running all tests… find the keyboard shortcut for doing this and learn it! Optionally, if you’re really into it, you can get a tool that automatically runs your tests like NCrunch

Here, there is a certain pattern that IoC containers work with: Your class constructor should take parameters for all of its dependencies. Here is the implementation of ChartLoader I came up with to get the tests to pass:

    public class ChartLoader
    {
        private readonly IChartRepository _chartRepository;

        public ChartLoader(IChartRepository chartRepository)
        {
            _chartRepository = chartRepository;
        }

        public IEnumerable<Chart> GetCharts()
        {
            return _chartRepository.Charts;
        }
    }

Now typically, you will do whatever refactoring that is necessary, which includes moving classes into appropriate folders and projects, etc, because all of the generated code I’ve shown is at the bottom of the test file. That would be out of the scope of this post, though, and sometimes it’s ok to leave them inline while you’re still writing tests.

This might actually be a good time to create a fake IChartRepository implementation on the front end site and actually give the business something to look at!

Hah! Did you think TDD was slow? How much quicker did we just deliver something to business and get feedback? This is VERY early on, and it is invaluable, because business requirements change when the people using a system get to play with it. You can and should show them something as soon as possible.

Back to TDD. The second test:

We have an object that can get charts, but we still don’t have anything loading from disk. Let’s write another test (because in TDD we always write a test before a feature):
I typically start a new test class when I’m dealing with a new system under test, but for this example, I won’t bother.

        [TestMethod]
        public void chart_repository_returns_charts_from_directory()
        {
            // Arrange
            var container = new MockingContainer<DirectoryChartRepository>();
            container.Arrange<IDirectory>(d => d.GetFiles()).Returns(new List<string>
            {
                "file1.png",
                "file2.png"
            });

            // Act
            DirectoryChartRepository repository = container.Instance;
            IEnumerable<Chart> result = repository.Charts;

            // Assert
            Assert.AreEqual(2, result.Count());
            Assert.AreEqual("file1.png", result.ElementAt(0).FileName);
            Assert.AreEqual("file2.png", result.ElementAt(1).FileName);
        }

Here I just want to prove that charts can load from a directory. Now, what really makes this a special scenario (and why I chose this example) is that there is an inherent dependency on the file system in the requirement: Charts will be loaded off the hard drive. This is about class design and controlling inputs in order to test things properly, though. I don’t want a hard drive to have to spin up in order to run a unit test. Tests should execute in milliseconds and be self contained units. The arrange section of a unit test HAS TO contain all of the dependency mocking, or it is going to be a brittle test that requires too much setup. Furthermore, System.IO.Directory.GetFiles(path) is static and can’t be overridden, so it’s impossible to mock (without a major effort or something that can fiddle with system libraries at runtime).

So, now let’s do some more class generation.

    public interface IDirectory
    {
        IEnumerable<string> GetFiles();
    }

    public class DirectoryChartRepository : IChartRepository
    {
        public IEnumerable<Chart> Charts { get; }
    }

So now everything compiles, but the new test still fails, because the DirectoryChartRepository object doesn’t actually use IDirectory and isn’t building any chart objects from the directory. So we have to do more to get it to pass:

    public class DirectoryChartRepository : IChartRepository
    {
        private readonly IDirectory _directory;

        public DirectoryChartRepository(IDirectory directory)
        {
            _directory = directory;
        }

        public IEnumerable<Chart> Charts
        {
            get
            {
                // TODO: I'm going to need a way to inject the path
                return _directory.GetFiles().Select(f => new Chart
                {
                    FileName = f
                });
            }
        }
    }

Now both tests should pass, and we can move on. How do charts get categories? NEW TEST! Seeing the pattern now? (Good, because I’m going to go faster):

Going faster. The third test:

	[TestMethod]
	public void chart_repository_categorizes_charts_from_categorizer()
	{
		// Arrange
		var container = new MockingContainer<DirectoryChartRepository>();
		container.Arrange<IDirectory>(d => d.GetFiles()).Returns(new List<string>
		{
			"file1.png"
		});

		container.Arrange<IChartCategorizer>(c => c.GetChartCategory(Arg.IsAny<Chart>()))
			.Returns(new ChartCategory
		{
			Main = "main",
			Sub = "sub",
			Type = "type"
		});

		// Act
		DirectoryChartRepository repository = container.Instance;
		IEnumerable<Chart> result = repository.Charts;

		// Assert
		Assert.AreEqual("main", result.ElementAt(0).Category.Main);
		Assert.AreEqual("sub", result.ElementAt(0).Category.Sub);
		Assert.AreEqual("type", result.ElementAt(0).Category.Type);
	}

    public interface IChartCategorizer
    {
        ChartCategory GetChartCategory(Chart chart);
    }

Tests compile but fail again. Add a dependency on IChartCategorizer to the DirectoryChartRepository, and use it. New DirectoryChartRepository class:

    public class DirectoryChartRepository : IChartRepository
    {
        private readonly IDirectory _directory;
        private readonly IChartCategorizer _chartCategorizer;

        public DirectoryChartRepository(IDirectory directory,
            IChartCategorizer chartCategorizer)
        {
            _directory = directory;
            _chartCategorizer = chartCategorizer;
        }

        public IEnumerable<Chart> Charts
        {
            get
            {
                return _directory.GetFiles().Select(f =>
                {
                    var chart = new Chart
                    {
                        FileName = f
                    };
                    chart.Category = _chartCategorizer.GetChartCategory(chart);
                    return chart;
                });
            }
        }
    }

Tests pass. Things are really starting to come together at this point. We still want to load categories from that XML file perhaps, but who’s going to maintain the XML file? What if they want to be able to manage categories themselves? Things are really starting to get going now, and with this class design, to implement any categorization requirements, it’s simply an implementation of IChartCategorizer. XMLChartCategorizer or SQLChartCategorizer? Well for now let’s do DictionaryChartCategorizer since we’re going to be the only ones maintaining the categories for now.

Fourth test:

	[TestMethod]
	public void dictionary_categorizer_loads_categories_from_dictionary()
	{
		// Arrange
		var container = new MockingContainer<DictionaryChartCategorizer>();
		container.Arrange<IChartCategoryDictionaryProvider>(d => d.GetCategories()).Returns(new Dictionary<string, ChartCategory>
		{
			{
				"file1.png",
				new ChartCategory
				{
					Main = "main",
					Sub = "sub",
					Type = "type"
				}
			}
		});

		// Act
		var result = container.Instance.GetChartCategory(new Chart
		{
			FileName = "file1.png"
		});

		// Assert
		Assert.AreEqual("main", result.Main);
		Assert.AreEqual("sub", result.Sub);
		Assert.AreEqual("type", result.Type);
	}

    public interface IChartCategoryDictionaryProvider
    {
        Dictionary<string, ChartCategory> GetCategories();
    }

    public class DictionaryChartCategorizer : IChartCategorizer
    {
        public ChartCategory GetChartCategory(Chart chart)
        {
            throw new NotImplementedException();
        }
    }

Partway through writing the Arrange section, I realize that I need a way to control the dictionary of categories, and this is a good time to make a new IChartCategoryDictionaryProvider object, because I can implement that interface for XML, SQL, a Code Only version, or this mock version! We have a compiling test that fails due to exceptions. Let’s fix that:

    public class DictionaryChartCategorizer : IChartCategorizer
    {
        private readonly IChartCategoryDictionaryProvider _chartCategoryDictionaryProvider;

        public DictionaryChartCategorizer(IChartCategoryDictionaryProvider chartCategoryDictionaryProvider)
        {
            _chartCategoryDictionaryProvider = chartCategoryDictionaryProvider;
        }

        public ChartCategory GetChartCategory(Chart chart)
        {
            var categories = _chartCategoryDictionaryProvider.GetCategories();
            ChartCategory category;
            if (categories.TryGetValue(chart.FileName, out category))
            {
                return category;
            }
            return null;
        }
    }

With that new implementation of DictionaryChartCategorizer, everything passes again. So, we have the basic structure of our API down that satisfies all of the requirements, but STILL no call to System.IO.Directory.GetFiles() and no loading charts from XML? What gives? We’ve reached the point where we need real implementations in order to call this done, but we could easily skip that and write the whole front end website. As noted, we could have done that a long time ago as soon as we had the ChartLoader object.

Now let’s finish this thing out

The test for this is basic, because there’s not much to arrange or assert:

	[TestMethod]
	public void filesystem_directory_does_not_throw_exception()
	{
		// Arrange
		var directory = new FileSystemDirectory("C:\");

		// Act
		var result = directory.GetFiles();

		// Assert
		// Pass if no exceptions
	}

    public class FileSystemDirectory : IDirectory
    {
        private readonly string _path;

        public FileSystemDirectory(string path)
        {
            _path = path;
        }

        public IEnumerable<string> GetFiles()
        {
            return System.IO.Directory.GetFiles(_path);
        }
    }

You’ll notice I didn’t mock anything, because this class doesn’t have a mockable dependency. It goes directly to a static method to get files off the disk, and that’s exactly what we didn’t want polluting our classes making testing them hard. It has to be done at some point, though, and at least we have a single class to handle it and it’s tucked away neatly in an abstraction. As a side note, this opens up the possibility of having a non filesystem directory (store image byte arrays in SQL?), which is a pretty neat concept, and no code would have to change.

Almost done!

	[TestMethod]
	public void xml_categorizer_loads_categories_from_xdoc()
	{
		// Arrange
		var document =
			new XDocument(new XElement("charts",
				new XElement("chart", new XAttribute("maincategory", "main"), new XAttribute("subcategory", "sub"),
					new XAttribute("type", "type"), new XAttribute("filename", "file1.png"))));

		var categorizer = new XmlChartCategorizer(document);

		// Act
		var category = categorizer.GetChartCategory(new Chart
		{
			FileName = "file1.png"
		});

		// Assert
		Assert.AreEqual("main", category.Main);
		Assert.AreEqual("sub", category.Sub);
		Assert.AreEqual("type", category.Type);
	}

    public class XmlChartCategorizer : IChartCategorizer
    {
        private readonly XDocument _document;

        public XmlChartCategorizer(XDocument document)
        {
            _document = document;
        }

        public ChartCategory GetChartCategory(Chart chart)
        {
            var chartElement = _document.Descendants("chart").FirstOrDefault(x => x.Attribute("filename").Value == chart.FileName);
            if (chartElement != null)
            {
                return new ChartCategory
                {
                    Main = chartElement.Attribute("maincategory").Value,
                    Sub = chartElement.Attribute("subcategory").Value,
                    Type = chartElement.Attribute("type").Value
                };
            }
            return null;
        }
    }

That’s it. We have everything we need, and the library has tests for all business functionality. The design is a LOT different, no? You might not see the value in such a design pattern at first, but consider how flexible it is to change. I’ve already outlined some changes that would be very simple, but more than just simple changes, even complex changes are not going to damage the integrity of the rest of the library. Changing the Categorizer implementation to a SQLChartCategorizer does not have anything to do with where the files come from on disk. Files could come from cloud blob storage, and categories could come from an infinite monkey array… the rest of the code won’t care.

If you implement the infinite monkey array, though, I want to see the code.


(Contains 1 attachments.)

Test driven development (TDD) should drive your class design (Part 1 of 2): The wrong way

Consider the following scenario. You work for Company A, and they want you to write a simple web portal for them. You learn that there is a process in place already that spits out about 30 images as email attachments, and they would much rather see these displayed on a web site. The images will have to be categorized into main, sub, and chart type. Sounds simple enough, right?

I want to attack this problem from two angles to show how test driven development can, and should, drive your class design. Again, TDD should drive your class design. Simply put: if you do it right, TDD should cause you to actually change how you design your classes and their dependencies into a much looser, flexible, and less brittle pattern.

First, let’s look at it from how one might write this without TDD. This theoretical person is still good with object oriented programming, but hasn’t quite made the leap to TDD. Maybe you fit this bill? Maybe you’ve said “I don’t even know what this is going to look like, so how would I write a unit test for it before it’s written??” to yourself in the past? Let’s get started.

Obviously from this example, one can imagine a Chart object, and perhaps a ChartCategory object:

    public class Chart
    {
        public string FileName { get; set; }
        public ChartCategory Category { get; set; }
    }

    public class ChartCategory
    {
        public string Main { get; set; }
        public string Sub { get; set; }
        public string Type { get; set; }
    }

One might then surmise that they need a way to load charts from disk:

public class ChartReader
    {
        public IEnumerable LoadChartsFromDisk(string path)
        {
            var files = System.IO.Directory.GetFiles(path);

            var charts = files.Select(f => new Chart
            {
                FileName = f
            }).ToList();

            foreach (var chart in charts)
            {
                chart.Category = GetCategory(chart, path);
            }

            return charts;
        }

        private ChartCategory GetCategory(Chart chart, string path)
        {
            var doc = XDocument.Load(path + "\charts.xml");
            var chartElement = doc.Descendants("chart").FirstOrDefault(x => x.Attribute("filename").Value == chart.FileName);
            if (chartElement != null)
            {
                return new ChartCategory
                {
                    Main = chartElement.Attribute("maincategory").Value,
                    Sub = chartElement.Attribute("subcategory").Value,
                    Type = chartElement.Attribute("charttype").Value
                };
            }
            return new ChartCategory();
        }
    }

GREAT! You even had the foresight to load categories from an XML document. This is going to work well, right? Let’s say you wire this all together and make a great front end website for them (I’m going to skip this part since it’s not all that relevant right now). You have your charts displaying on page, and business likes how it looks. You get a pat on the back for getting this done in a few days.

Now they want to add new features. They want charts to have a description. Come to find out, charts are only ever categorized into two main categories, and two static chart types, and they always want one chart type on the left of the page, and the other on the right. You make these changes. Later down the line, someone comes back and says well there could be a different chart type, and this chart type is actually a grouping of charts that, as a group, have to be shown together.

The point I’m trying to make is that this code is brittle and untestable. One guaranteed point in software development is that the requirements will change over time, and the later in the process you get change, the riskier it is.

Why is this code untestable?

Well, technically it’s not impossible to test this code, but let’s try writing a simple unit test. One that proves a chart gets its category from the xml document:

        [TestMethod]
        public void charts_get_their_categories_from_xml_documents()
        {
            // Arrange
            var reader = new ChartReader();

            // Act
            var charts = reader.LoadChartsFromDisk("c:\unittests").ToList();

            // Assert
            Assert.AreEqual("main", charts.First().Category.Main);
            Assert.AreEqual("sub", charts.First().Category.Main);
            Assert.AreEqual("type", charts.First().Category.Main);
        }

Halfway through this test, it becomes apparent that the ChartReader object has 2 major dependencies: the file system, and the xml document. That is to say, in order to pass this test, the C:unittests folder will have to contain image files and an xml document to simulate the assertions. This causes a few problems:

  1. Disk IO is slow
  2. This test is very brittle, as the arrange section is not really arranging anything.
    1. The test parameters are setup on disk and are easy to modify by anyone
  3. In order to deploy this to any type of build server that runs unit tests, the same filesystem dependencies need to be met.

While this class design got the job done, I hope you can see that it is not ideal, but how can TDD help? Click here to find out!