Learning Unit Testing III – Emergent Design

So having seen the answers on my own StackOverflow question on TDD Design, I’ve decided to go ahead with the ‘emergent design’ crowd and see what happens. It appears that the refactoring and mid-stream redesigning is an integral part of the TDD process. It’ll all, of course, be described here (the process might be a little bit stream-of-consciousness) as I go through my design decisions ‘out loud’).

I got up to the end of page 9 last time, about to start on the Movement section. In keeping with the single responsibility principle, I’ll be putting movement logic in it’s own class. Movement happens in a strict order – all chargers are declared and moved first, then any compulsory moves are made, and finally ‘everything else’ movement. This would be represented in the MovementManager class as having an internal phase structure, just like the GameManager.

The question is, where should this be called from? The decision to stop moving chargers and move onto the next sub-phase is a player choice, therefore a user interface trigger (just as IncrementPhase). It is not something that can be automated or inferred. Should the IncrementPhase method (and associated fields) be moved out into a TurnManager class which is owned by GameManager – GameManager can then expose valid actions based on what phase and whose turn it is. Would that even need to be moved out into another class – if I am deciding actions based on what the GameManager will expose to a user interface, the turn logic can remain in GameManager.

Alternatively, the MovementManager can broadly restrict actions based on the properties of it’s parent (GameManager) and regulate it’s own, internal restrictions based on sub-phase and a variation of that logic. This seems like the simplest solution – I can raise a custom exception if a method is called on the MovementManager that is invalid (wrong sub-phase, or wrong phase entirely). Time for a new cl- uh, test class, obviously. Some of the tests can be cribbed from the existing GameManagerTests, but there’s no real worry about whose turn it is.

[TestClass]
public class MovementManagerTests
{
[TestMethod]
public void IncrementSubPhase_RollsBackToMoveChargersAfterEverythingElse()
{
MovementManager movementManager = new MovementManager();
movementManager.IncrementSubPhase(); // Go to compulsory moves
movementManager.IncrementSubPhase(); // Go to everything else
movementManager.IncrementSubPhase(); // Go back to Move Chargers
Assert.AreEqual(MovementSubPhase.MoveChargers, movementManager.CurrentSubPhase);
}
[TestMethod]
public void IncrementSubPhase_MovesForwardSubPhase()
{
MovementManager movementManager = new MovementManager();
MovementSubPhase firstPhase = movementManager.CurrentSubPhase;
movementManager.IncrementSubPhase();
MovementSubPhase secondPhase = movementManager.CurrentSubPhase;
Assert.AreNotEqual(firstPhase, secondPhase);
}
}

As expected, after resolving build errors (new class, property and method stubs) the two tests fail. And with the barest minimum of code:

public class MovementManager
{
public MovementSubPhase CurrentSubPhase { get; private set; }
public void IncrementSubPhase()
{
if (CurrentSubPhase == MovementSubPhase.EverythingElse)
{
CurrentSubPhase = MovementSubPhase.MoveChargers;
}
else
{
CurrentSubPhase++;
}
}
}

It all passes. Next up, there needs to be a way of preventing the Movement sub-phase from advancing when it is not the Movement phase at all. The expected behaviour for this should be a custom exception to be thrown, and dealt with elsewhere (presumably, the hypothetical UI). To fool it that it is not the Movement phase, it needs to have a reference to the GameManager – passed in as a constructor parameter to the MovementManager. The GameManager passed in for this test also needs to be mocked, so it will need to be given a public interface. One quick mocking later:

[TestMethod]
public void IncrementSubPhase_ThrowsExceptionIfNotMovementPhase()
{
bool correctExceptionThrown = false;
try
{
Mock<IGameManager> mockGameManager = new Mock<IGameManager>();
mockGameManager.Setup(item => item.CurrentPhase).Returns(TurnPhase.Shooting);
MovementManager movementManager = new MovementManager(mockGameManager.Object);
movementManager.IncrementSubPhase();
}
catch (WrongPhaseException ex)
{
correctExceptionThrown = true;
}
Assert.IsTrue(correctExceptionThrown);
}

Which is passed by:

private void ValidatePhase()
{
if (_gameManager.CurrentPhase != TurnPhase.Movement)
{
throw new WrongPhaseException("Cannot perform Movement actions in the " + _gameManager.CurrentPhase.ToString() + " phase.");
}
}

And calling that at the beginning of the IncrementSubPhase method.

Now it’s time to make some changes to the (as yet unused) Model class. Now it starts to get into things in a bit more of a distinct rule structure – the next line states that ‘models can move up to their move rate in inches in any direction’. I’m deciding that ‘inches’ refers to an arbitrary (and divisible) number, so a decimal will serve very well to decide how far they’ve moved, and how far they can move. The movement manager can either take in a co-ordinate to specify the target position, and change the model’s position to as far as it can go towards that point, or take in a distance and direction and move the model as specified.

It’ll probably be easier to sort out the distance and direction at the moment – those calculations will need to be made in the code that calls the MovementManager – though at some future point, these could be made into helper methods on the MovementManager. To work out where the model’s new position is, we need diagrams – this will have to wait until the next post!

This has been a nice long post that gets about halfway through page 10. I’m still not sure I’m allowing the design to emerge – I am, for example, thinking a few tests ahead of where I am – but at this stage, I’ve not (consciously) made a decision about design based on that forewarning, only on the basis of ‘I want Movement code separate from Game Manager code). This is more to do with the single responsibility principle than some master design drawn upfront.

This is a learning project I am documenting in order to teach myself TDD and unit testing – as I publish this, I have already written many parts in advance but I want to know what I’m doing wrong! If you see improvements or corrections, either to the code or the process, please leave a comment and let me know! Introduction to this project can be found here.

Learning Unit Testing II – TDD vs. Traditional Design

As you can see, I’ve only done a small amount of Test-Driven Development so far. I notice that for small classes – so far, there’s only a very simple turn tracker – it’s easy to write a test first when there’s only very little code and no interaction with other classes. When things get a little more complex, will it still be so easy?

I am wondering how people use TDD when they have big projects (as this will invariably become). Is it possible to stick to just writing code to pass tests all the way through to the end? Surely, at some point, major refactoring will need to be done when something comes right out of nowhere. I can see one example I’ll run into at some point: in Necromunda, a model may go on ‘Overwatch’. This allows them to fire in their opponents turn, shooting at a target before it’s move, after it’s move or during it’s move. That’s probably going to require a major change to the Movement code (to account for the opponent taking an action), which could itself lead to a lot of refactoring. Should I try and design around this idea now, or wait until much, much later when I get to the Overwatch section to worry about it?

Whether or not there is a simple solution to that particular problem will depend on many things – not least, the movement and shooting code that is written before it. I would traditionally sit down and try to work out exactly how to architecture the whole thing, taking into account things like shooting, overwatch, etc before I sit down to code. TDD seems to suggest that I write the test, then the code, and then eventually get around to a new test that – had I known – would have influenced the code I wrote earlier. I can see that would have some benefits (for example, the Bowling Game Kata shows the change in design to a simpler one due to TDD) but I don’t know how likely it is that writing code just to pass the test will lead to a design path that isn’t optimal given later functionality requirements.

Maybe I am worrying about nothing, and the forced simplicity of design for TDD will ultimately lead to a good solution. Maybe I’m missing the point entirely, and there will be major refactoring down the road, and that’s a good thing. If that’s true, isn’t TDD going to end up taking a lot more time than is useful? Is there a secret, undocumented art to writing code following TDD where certain things are written first entirely to limit this sort of refactoring? If that’s the case, I may be handicapping myself by slavishly following the rulebook.

After reading the accepted answer on this StackOverflow question,  I’ve decided to push ahead with my TDD experiment. I need to understand the beast. I’ve got an idea of how certain things should be done, but we’ll see if it makes sense once I’ve laid the foundations using TDD. It’s going to be an interesting way to do the work!

This is a learning project I am documenting in order to teach myself TDD and unit testing – as I publish this, I have already written many parts in advance but I want to know what I’m doing wrong! If you see improvements or corrections, either to the code or the process, please leave a comment and let me know! Introduction to this project can be found here.

Learning Unit Testing I – The Basics

Right, so I’ve chosen my project and I’m ready to begin. I’ll skip past the introduction, straight to page 8 of the rulebook. The characteristics section. This is basically a class layout, nothing too heavy, so I’ll start off by creating Model.cs:

class Model
{
public string Name { get; set; }
public int WeaponSkill { get; set; }
public int BallisticSkill { get; set; }
public int Strength { get; set; }
public int Toughness { get; set; }
public int Wounds { get; set; }
public int Initiative { get; set; }
public int Attacks { get; set; }
public int Leadership { get; set; }
}

Nothing really testable here yet. No point in testing basic getters and setters.

Next up is a description of the turn structure – this calls for a game manager of some sort. How about GameManager.cs, with an enum (TurnPhase)?

class GameManager
{
    TurnPhase CurrentPhase { get; private set; }
    int _numberOfPlayers;
    int _currentPlayersTurn;
}
enum TurnPhase
{
Movement,
Shooting,
CloseCombat,
Recovery
}

I think I’ll also add in an integer to GameManager to determine the number of players, and the number of the player whose turn it is. That should be enough to track that for now. To increment the turn onwards, though I’m not sure how that will be triggered yet, I need to add some actual logic! This should have a unit test. In proper TDD fashion, the test will be written first.

[TestMethod]
public void IncrementTurnPhase_RollsBackToMovementPhaseAfterRecovery()
{
GameManager manager = new GameManager();
manager.IncrementPhase(); // Go to Shooting
manager.IncrementPhase(); // Go to Close Combat
manager.IncrementPhase(); // Go to Recovery
manager.IncrementPhase(); // Go back to Movement
Assert.AreEqual(TurnPhase.Movement, manager.CurrentPhase);
}

This looks about right – but I’ll need to give GameManager a bit of a tidy up and make things a little more accessible. Now the code to pass that test:

public void IncrementPhase()
{
if (CurrentPhase == TurnPhase.Recovery)
{
CurrentPhase = TurnPhase.Movement;
}
else
{
CurrentPhase++;
}
}

That’s nice and neat. But I found that without writing any code in that method, it still passes – since the turn phase is still Movement. Another test to make sure that it only increments one space will probably be in order.

[TestMethod]
public void IncrementTurnPhase_MovesForwardPhase()
{
GameManager manager = new GameManager();
TurnPhase firstPhase = manager.CurrentPhase;
manager.IncrementPhase(); // Go to Shooting
TurnPhase secondPhase = manager.CurrentPhase;
Assert.AreNotEqual(firstPhase, secondPhase);
}

This one does the trick. Makes sure that the phase has changed within the turn.

Finally, the last couple of paragraphs on page 9 say that control alternates between players. I know from experience that there could easily be multiple players, and I want to be ready for that. So the GameManager will increment _currentPlayersTurn every time the turn finishes (after the Recovery phase), and reset the _currentPlayersTurn integer back to 1 when it exceeds _numberOfPlayers.

Once more, write a test to check that it increments at the end of a turn:

[TestMethod]
public void IncrementTurnPhase_ChangesPlayerAtEndOfTurn()
{
GameManager manager = new GameManager();
int firstTurn = manager.CurrentPlayersTurn;
manager.IncrementPhase(); // Go to Shooting
manager.IncrementPhase(); // Go to Close Combat
manager.IncrementPhase(); // Go to Recovery
manager.IncrementPhase(); // Go back to Movement
int secondTurn = manager.CurrentPlayersTurn;
Assert.AreNotEqual(firstTurn, secondTurn);
}

Now to test the next bit, it’ll be necessary to add a proper constructor with a parameter – number of players. Here’s the test:

[TestMethod]
public void IncrementTurnPhase_ReturnsToFirstPlayerAfterAllHaveHadTurn()
{
GameManager manager = new GameManager(2);
manager.IncrementPhase(); // Go to Shooting
manager.IncrementPhase(); // Go to Close Combat
manager.IncrementPhase(); // Go to Recovery
manager.IncrementPhase(); // Go back to Movement
manager.IncrementPhase(); // Go to Shooting
manager.IncrementPhase(); // Go to Close Combat
manager.IncrementPhase(); // Go to Recovery
manager.IncrementPhase(); // Go back to Movement
Assert.AreEqual(1, manager.CurrentPlayersTurn);
}

And the code that passes both of those tests:

public GameManager(int numberOfPlayers)
{
NumberOfPlayers = numberOfPlayers;
CurrentPlayersTurn = 1;
}
public void IncrementPhase()
{
if (CurrentPhase == TurnPhase.Recovery)
{
CurrentPhase = TurnPhase.Movement;
if (CurrentPlayersTurn == NumberOfPlayers)
{
CurrentPlayersTurn = 1;
}
else
{
CurrentPlayersTurn++;
}
}
else
{
CurrentPhase++;
}
}

After adding the requirement for a number of players to the other tests, all the tests so far pass. There is, as I’ve been warned, more test code than real code (67 lines in GameManagerTests compared to 40 in GameManager) but seeing all those little green ticks is definitely a psychological boost. As I’ve neatly finished page 9 and the ‘Rules’ section, I will start the ‘Movement’ section next time. This will have a bit more design than the fairly sparse classes here, and a bit more deliberation over where to put particular bits of code. I know a big idea of TDD is to write, then refactor, but I don’t want to do too much refactoring. It could become quite a hassle, especially later in the day. We’ll see when we get there!

This is a learning project I am documenting in order to teach myself TDD and unit testing – as I publish this, I have already written many parts in advance but I want to know what I’m doing wrong! If you see improvements or corrections, either to the code or the process, please leave a comment and let me know! Introduction to this project can be found here.

My Next Learning Project

I’ve long ago established that I learn best from doing things. Even if those ‘things’ never get anywhere, the journey through real problems helps me get a handle on what they are. My army list program got me through WPF, and then MVC. It’s faltered, since I don’t really have the enthusiasm for it that I once did (I’ve spent over a year on it, and as it is a learning project I keep needing to redesign things…)

This brings me to my new idea. Everyone who is anyone in .NET programming at the moment is unit testing. I’ve read a lot about unit testing, and dependency injection, and all those things but I am not entirely convinced I am doing it right. It was when I tried to apply these things to the wargame tools / army list program that I realised I had lost my direction with that one, and it was time to move to something new. Sticking with what I knew best, I initially thought about a WFRP (second edition, naturally) calculator or helper of some sort – then quickly abandoned that idea as madness.

But what about an easier system? Necromunda is a relatively simple game system. Something to calculate the effects of it’s combat, shooting modifiers, exotic weapons and the many charts and tables for the end-game clean-up would be ideal. If I felt adventurous, I could even add in Gorkamorka variants.

The scope I am envisioning is a disconnected class library, capable of managing and running a game of Necromunda. In theory, I could hook it up to a Silverlight, WPF or XNA (ha!) frontend, and all the functionality will be there to go. I would just need to connect certain bits for display. As it is all pure logic, it should be a good way to practice unit testing using a Test-Driven Development approach.

I’ll be documenting each step of the way in here, so I am forced to think about and describe what I’m doing. The rules for the game are available for free (click on the image to get them) from Games Workshop, so it shouldn’t be a problem me mentioning the odd one or two, followed by reams of code.