XNA Game – Rotation – Designing the first game objects and tests – Part 3

I’m really into my TDD. It gives you direction. TDD is good if you write meaningful tests that test the intention of your code. Far too often (and I’ll try not to go down too much of a tangent here) I see developers writing test code like this:

var obj = new MyObject();

Tests like this achieve nothing. You are testing that the CLR is doing it’s job.  A test needs to capture the intent of an object (or set of objects) and how they are meant to function together. A well designed test makes writing the code much simpler. One could argue that this is BDD, in my eyes the line between these two is quite blurred (let’s not go down that avenue).

The first two classes that I need to define are a letter (which will simply represent a letter and a value) and a collection of letters that holds a collection of all possible letters.

This first class

public class Letter
	public Letter(int points, char value)
		Points = points;
		Value = value;

	public int Points { get; set; }
	public char Value { get; set; }

	public bool IsVowel
		get { return false; }

This defines the letter class.  The letter class pairs a char with a value and adds an extra property so that we can tell if the letter is a vowel.  Strictly speaking I suppose we shouldn’t add this property just yet as we have no need to know if a letter is a vowel but thinking ahead to board composition (and checking if the game is playable) we will do.  The next class I need is a lookup collection of all of the possible letters:

public class LetterLookup : ILetterLookup
	private IEnumerable<Letter> _letters;

	public IEnumerable<Letter> Letters
		get { return _letters; }

As you can see this class returns an IEnumerable.  Where possible it’s best to return the least constricting type possible.  The purpose of this class is to be a static collection of all of the possible letters and their values (a master list if you will).  Notice that I’ve extracted an interface (ILetterLookup).  This gives me better de-coupling as all of the classes that I will write later on that need a list of letters (LetterLookup) will only need to depend on the ILetterLookup interface.  Meaning that I could potentially swap out the list per level or mid game quite easily for example.

Now to write our first test.  Rather than list out all of the code for the test I’m going to just write them in the Given, When, Then syntax:

Given I have a letter lookup interface

When I create the interface

Then I should have 26 letters

And all of the letters should be different

This test is clear in it’s intent.  You could look at this test for the first time and it would be obvious what the letter lookup class does.  It holds letters, there are 26 of them and each of them should be different.  For my unit testing framework I’m using sub spec.  Created by Phil Haack (amongst others) it’s built on top of xunit and uses extension methods on string.  This means that you can write your tests in the following way:

"Given I have something".Context(() => {/*context here*/});

"When I do something".Do(() => {/* do stuff */});

"Then I should see a result".Observation(() => {/* assert stuff */});

What I like about this syntax it is clean and readable.  There is not much fluff getting between you and what the test is trying to achieve.  As an aside for the Then step you can use Assert or Observation.  The difference being that Assert will re-run you context and do statements for each assertion (which I guess is the way it should be) and an observation will observe the result and then the next observation will run on the same result without re-running the context and do steps.  I make a point of not altering my result in my observation step (something you should never do) so using observation simply speeds up my tests.

We can now run this test and see that it fails and then go ahead an implement it.  Implementing it is as simple as creating a list of all of the letters in the constructor of LetterLookup and returning it through the Letters property.  Now we can re-run the test and check that it passes, bingo our first green light.

Next time I’m going to talk about how the rest of the game objects fit together plus a look at NCrunch a fabulous continuous testing tool and publish a first edition of the source code.



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s