Wednesday, 28 May 2008

Nothin' but .NET heading down under

I left a comment on JP Boodhoo's blog recently, and asked if there was any chance of him running a Nothin' But .NET course in Sydney, Australia. I got an email response from him a short time later:

"As far as the course in Australia!! I will be there next year [2009] to give a course in Sydney!!"

I've been really keen to attend this course for ages now, but the commute to Canada each day was pushing it a bit :). In case you don't know what the course is all about, here's a review (and links to other reviews) from Kyle Bailey's old blog. To quote a bit of the blurb from a recently scheduled course:

Nothin’ But .Net is a five day boot camp that will focus on pragmatically applying .Net within the context of developing a working N-Tiered application. Registrants will learn about advanced features of .Net (2.0/3.0/3.5) as they are applied to the task of building a complete application from the UI layer all the way down to the mapping layer.

Core Concepts Overview
  • Expanding the capabilities of developing with VS.Net - Enter ReSharper (a productivity add-in for Visual Studio .Net)
  • There’s more to life than generated code
  • Automation for the developer
  • Generics ( they’re not just for collections )
  • Back to basics - Rules Of Good Object Oriented Design
  • Dependency Injection
  • Object Relational Mapping in .Net
  • Applying the dependency inversion principle
  • Domain Driven Design
  • Passive View/Supervising Controller,MVC
  • Creating layered architectures
  • Driving out functionality and design through testing
  • Taking Control Of Databinding
  • Behavior (Test) Driven Development
  • Core design patterns applied
  • Pragmatic Productivity Tools For Developers

It sounds awesome. Hope to see a few like-minded Aussie developers there! In the mean time, if anyone knows of any current course in Sydney that covers any of this stuff please leave a comment or email me, as I'd try and attend that too during the looonnnggg wait 'til JP visits in 2009.

This free advertisement was brought to you courtesy of an excited coder. :-)

BDD test naming with AutoHotKey

Update 2008-05-29: JP has posted a much better version of this script (with suggestions from a few of his readers). I've updated the script on this post to work more like JP's version, but you're probably best off grabbing it from his post, or searching his site for his latest version.

Was having a chat earlier with my good mate JP Boodhoo... er, well, more accurately, I left a comment on his blog and he was nice enough to email me back. Anyway, JP has started trying AutoHotKey rather than his previous macro for BDD-style test naming.

I thought I'd post an extremely over-engineering version of this AutoHotKey script, which has a toggle-approach similar to the Emacs Everywhere script I posted earlier.

Once you have AHK installed, you can just extract the ZIP below and double click the .AHK file to load the script. The script will let you toggle "test-naming mode" (i.e. replacing spaces with underscores) using Ctrl + Shift + U. You can cancel out of test naming mode by pressing ENTER, ESCAPE or starting the method signature by typing a '('. Pressing Ctrl + Alt + U will insert a new test template before switching on test naming mode (although you might be better off using R# templates for this). All this is simply to make it easier to type out tests like this:

[Test]
public void Test_naming_mode_turns_spaces_to_underscores() {}

Version 2 of the script can be downloaded here:

Feel free to change the hotkeys and the dodgy icons :). I haven't had a good test of it yet so use at your own risk.

If you're happy with how it works you can add it to your Startup programs and have BDD-style test naming goodness whenever you like. Hope_this_helps! :-)

Change log

  • 2008-05-29: Uploaded v2, synching with JP's version 2, adding test templates, and made test mode exit after typing '(' for test method signature
  • 2008-05-28: Updated hotkeys to match JP's version
  • 2008-05-28: Original post

Tuesday, 27 May 2008

Top-down vs. bottom-up design

I've been having a think about top-down (a.k.a. outside-in) design during my recent iterative development exercise. In the series I've been putting off testing from the client layer down, primarily because GUIs have a reputation for being hard to test and harder to test-drive, and I wanted to make some early, easy progress on the core logic of the game.

I started to think that this approach might be a mistake. I'm dealing with the model that I think we'll need, not one demanded from the primary client of the model -- the GUI. Chad and Ben mentioned in their recent screencast that bottom-up implementation tended to lead to mistaken assumptions about infrastructure required by the top layers. I saw a similar point made on the BDD mailing list by Pat Maddox. Pat wrote (emphasis mine):

"I find an outside-in style of development to be very helpful... It forces you to think of your objects at a high level, so your design is driven by real need, and then you apply your design skills as you go on. When I use a pure bottom-up style, I write more speculative code and go down the wrong path far more often than I'd like. That's not to say that it's a problem inherent with that style, but rather a problem that I've personally experienced, and have more or less solved by using an outside-in approach."

This is opinion is echoed in an unrelated post to the TDD mailing list by Olof Bjarnason:

"I've been using TDD [bottom-up] for 2 years now, and it's been mostly a _great_ experience. The thing that bothers me most with "classic TDD" is that sometimes I build too much functionality in my classes, which isn't used in the end application after all. Even whole objects are wasted in the worst case."

The view here is that bottom-up design can lead to speculation and waste. By having a design driven directly by the overall, required behaviour, you only implement (and test) things that directly serve that behaviour. This can help eliminate speculative implementations of lower-level behaviour based on what you think the overall required behaviour will be.

Not so fast...

Sounds great! So what about inside-out / bottom-up / middle-out design? Ron Jeffries recently stated on the TDD mailing list that he generally prefers to start with the model (unless the project is simply to build a viewer). Maybe there's a bit more to it?

Digging further into that thread on the TDD list, there are a number of great points of view on the topic. Some TDD-ists argue that bottom-up design lets you build in small, easy steps, and refactor your way to the required behaviour that you would otherwise start with in top-down design. Others state that this leads to waste -- writing code and tests that just get refactored away. Which resulted in a couple of great quotes on the difference between refactored code and waste:

"I suppose we could also call the scaffold we use when constructing a large building as waste, or the safety harnesses as waste." -- John Roth to TDD list
"The analogy with scaffolding for a house is an excellent one - there is a lot of "stuff" constructed when building a house, *just* to support the construction - it is then discarded." -- Casey Charlton to TDD list

Top-down design can also lead to a "mockist" approach to TDD, where you need to mock all the required dependencies to implement the high level behaviour. This isn't necessarily a bad thing, but over-reliance on mocking can result in fragile tests. Martin Fowler has a great article on the pros and cons of "classic" and "mockist" TDD.

Enough rambling already!

While planning for part 3 of my recent development exercise I was coming to the conclusion that top-down was the way to go. After looking into it some more I was reminded of a whole host of advantages of bottom-up design. Even more importantly it reminded me that there is no silver bullet, and there are times when either, or a mix of both, approaches are fine. All this started to sound familiar, so firing up Google I noticed that I had read something to this effect in Jeremy Miller's excellent (as usual) post on the topic (search for "Bottom Up versus Top Down", although the whole post is worth reading).

I think the most important conclusion I've reached during this ramble is that if you are working in iterations to deliver a complete slice of the application (top and bottom) then you're never going to go too far wrong. Any "waste" from a bottom-up approach will be minimal as you'll be working toward and implementing the top almost immediately. And you'll still end up with higher-level behaviour specified with unit tests. Likewise starting top-down you'll still get the advantages of designing in small steps, particularly as you drive down into the design.

Wednesday, 21 May 2008

Disable theming for an empty ASPX

I recently added an ASPX page whose sole purpose in life is to redirect in various ways (yes, I could use a handler, no I didn't in this case). It had no content other than the usual <%@ Page ...%> declaration. No head, body, or html tag. I got the following error message:

Using themed css files requires a header control on the page. (e.g. <head runat="server" />).

So naturally I added <%@ Page EnableTheming="false" ...%>, and ... got the same error. Bit of Googling later and found this post from Damien White (which in turn references a Rick Strahl post). End result is that EnableTheming seems a bit useless (at least for this case):

<%@ Page Language="C#" Theme="" ... %>

Setting Theme to nothing works, EnableTheming="false" doesn't. Bit odd. I know this is old news, but given the trouble I had searching for a solution I thought an extra search result floating around wouldn't hurt anyone.

Tuesday, 20 May 2008

ReSharper 4.0 beta

Update 2008-05-22: The real beta release has just been announced. It is the same build (804) as the beta candidate, which pretty much answers my question below on the difference between the two :).

R# 4.0 beta candidate has been released. I'm not quite sure of the difference between a beta and a beta candidate, but I'm assuming its better than a standard nightly build :)

You can get it here, build 804. I've had a pretty good experience with most of the "works here" builds, so am looking forward to firing this up today :)

LINQ To SQL crippled prior to RTM

I was reading Frans' post on the marketing hype around Entity Framework this morning. He left an interesting comment there, quoting Matt Warren's post on writing an extensible LINQ to SQL DataContext. Here's a snippet from Matt's original post (emphasis mine):

"If only LINQ to SQL had a public provider model, I could simply plug a new one in and use it to intercept all interaction with the database. Oh, double irony, as there is no such provider model, at least not a public one. Grin.

LINQ to SQL was actually designed to be host to more types of back-ends than just SQL server. It had a provider model targeted for RTM, but was disabled before the release. Don’t ask me why. Be satisfied to know that is was not a technical reason. Internally, it still behaves that way."

Cue conspiracy theories! :)

Sunday, 18 May 2008

Garden Race Pt 2: Adding multiple players

This post is part of a series on the (very) basics of iterative development using the example of a simple Snakes and Ladders-like game. Links to each post in the series will be added to the index page.

Um, ok, so the customers (firstborn and I) weren't overly impressed with the demo from part 1. It did help illustrate the most pressing deficiencies though:

  • Doesn't support multiple players
  • Doesn't have anything even remotely resembling snakes or ladders, let alone fairies
  • No gui

Our story list currently looks like this:

  1. A player can roll the die, and then move that many spaces along the board.
  2. A player that ends his or her turn on a "feature square" (a square containing a creature or obstacle), will be moved to the square connected with that feature.
  3. There can be 1-4 players, and each player has their turn in sequence.
  4. A player that reaches the final square wins the game.

There are no GUI stories currently defined, but we'll need something resembling a GUI eventually. I am tempted to start working on some GUI stories, because I don't want to get too far through the code and then find that it won't play nice with a graphical interface. It is really the main point of this software after all. On the other hand, the Game class is still very basic, so maybe it would be a good idea to knock over one of the original stories on our list. Story 2 seems like it could tie in with the GUI pretty strongly -- the view will have to show the player's move, then perform some kind of animation in the event that the player lands on a feature square. How about Story 3? Pretty basic, and essential to the game. At least that way firstborn and I can race each other to the end of the command line demo :)

I'll just check with the customers... be right back.

Ok, customer is asleep, so I'll take that as "that's fine Dad" :)

Quick aside, normally we would estimate "points" or some other unit of how much effort each story would take, and how many units could be done in an iteration, then have the customer prioritise the stories for this iteration.

Our test list

What tests could we write for multiple players?

  1. Should be able to set the number of players for a new game
  2. For a new, 2 player game, both player's should be off-the-board (square 0)
  3. After first player's roll, current player should be player 2
  4. After first player's roll, current player's position should be off-the-board (square 0)
  5. First player rolls a 3, second player rolls a 2, then current player should be player 1 on square 3.

Frankly, I don't really like how these look. Implementation details keep coming to mind, and I want to ignore them and focus on what I want to achieve (not how I want to achieve it). Let's start with these anyway and we'll see how it goes.

Starting iteration 2

Running all our tests shows we are all green, and all good to go. The first test on the list looks easy -- set the number of players in the game. Let's do that one.

//From GameSpec.cs
[Fact]
public void Should_be_able_to_create_2_player_game() {
 var twoPlayerGame = new Game(10, 2);
 Assert.Equal(2, twoPlayerGame.NumberOfPlayers);
}
//From Game.cs
public int NumberOfPlayers { get { return numberOfPlayers; } }
public Game(int boardSize) {
 this.boardSize = boardSize;
}
public Game(int boardSize, int numberOfPlayers) {
 this.boardSize = boardSize;
 this.numberOfPlayers = numberOfPlayers;
}

What about the previous constructor that just takes the boardSize? Well that should probably just start a new one player game I guess. Let's write a test for how we think it should work.

[Fact]
public void New_game_should_have_1_player_by_default() {
 var onePlayerGame = new Game(10);
 Assert.Equal(1, onePlayerGame.NumberOfPlayers);
}

This fails because the number of players initialises to zero.

public Game(int boardSize) {
 this.boardSize = boardSize;
 this.numberOfPlayers = 1;
}

Fixed. Now let's look at test 2, checking the position of each player for a new game.

//From GameSpec.cs:
[Fact]
public void New_game_should_start_all_players_off_the_board() {
 var newThreePlayerGame = new Game(10, 3);
 var players = new[] {1, 2, 3};
 foreach (var player in players) {
  Assert.Equal(0, newThreePlayerGame.GetSquareFor(player));   
 }            
}

//From Game.cs:
public int GetSquareFor(int player) {
 return 0;
}

An obviously deficient implementation like this GetSquareFor() method suggests we need to writes some more tests to flesh out a better one.

[Fact]
public void Positions_should_be_correct_after_first_two_players_roll() {
 var threePlayerGame = new Game(10, 3);
 const int firstRoll = 3;
 const int secondRoll = 5;
 
 threePlayerGame.Roll(firstRoll);
 threePlayerGame.Roll(secondRoll);
 
 Assert.Equal(firstRoll, threePlayerGame.GetSquareFor(1));
 Assert.Equal(secondRoll, threePlayerGame.GetSquareFor(2));
 Assert.Equal(0, threePlayerGame.GetSquareFor(3));
}

Now we are potentially looking at a bigger step. We need Roll() to affect only the position of the current player. We don't have the concept of a current player. We'll also probably need an array or similar structure to store each player's position. Roll() will then store update the position of the current player, and change the current player to the next player. The CurrentSquare implementation will probably need to change to refer to the current player too. And then we'll have to add code to change the position in the event the player lands on a feature square! Argh!

Stop worrying! Try baby steps...

Let's back up a bit. I'm fairly confident we can write up the code above, but it will only be covered by one test and we are touching a lot of the Game class without direct guidance from the tests. We still have this test on our test list: "After first player's roll, current player should be player 2". This deals with the concept of the current player without requiring addition position arrays. It should only affect the Roll() implementation. Let's skip our last test by updating the attribute to [Fact(Skip="Too big a step for now")] (I could delete the test and rewrite it if we need it, but it did illustrate our need to deal with the current player concept, so I'll leave it for now). I started off coding our new test with two separate assertions:

var newTwoPlayerGame = new Game(10, 2);
Assert.Equal(1, newTwoPlayerGame.CurrentPlayer);
newTwoPlayerGame.Roll(2);
Assert.Equal(2, newTwoPlayerGame.CurrentPlayer);

The split asserts are ugly, and we can split this into two more specific tests. Here's the passing code, which was written one step at a time (not shown is chaining the Game(int) constructor to Game(int, int), so everything gets initialised properly in either case. Check the download at the end for the finished code):

//From GameSpec.cs:
[Fact]
public void Current_player_for_new_game_should_be_player_1() {
 var newTwoPlayerGame = new Game(10, 2);
 Assert.Equal(1, newTwoPlayerGame.CurrentPlayer);
}
[Fact]
public void After_first_players_roll_it_should_be_the_second_players_turn() {
 var newTwoPlayerGame = new Game(10, 2);
 newTwoPlayerGame.Roll(2);
 Assert.Equal(2, newTwoPlayerGame.CurrentPlayer);
}
//From Game.cs:
public int CurrentPlayer { get; private set; }
public Game(int boardSize, int numberOfPlayers) {
 this.boardSize = boardSize;
 this.numberOfPlayers = numberOfPlayers;
 this.playerPositions = new int[numberOfPlayers];
 this.CurrentPlayer = 1;
}
public void Roll(int dieValue) {
 CurrentSquare += dieValue;
 CurrentPlayer++;
}

Before we go back to the test we skipped, I'd like to flesh out more of the CurrentPlayer property. Fifth test on our list was "First player rolls a 3, second player rolls a 2, then current player should be player 1 on square 3". Let's do a simpler version and just verify that this scenario ends up with the correct CurrentPlayer.

//In GameSpec.cs:
[Fact]
public void After_all_players_have_had_a_turn_it_should_be_first_players_turn_again() {
 var newThreePlayerGame = new Game(10, 3);
 newThreePlayerGame.Roll(1);
 newThreePlayerGame.Roll(1);
 newThreePlayerGame.Roll(1);
 Assert.Equal(1, newThreePlayerGame.CurrentPlayer);
}
//In Game.cs:
public void Roll(int dieValue) {
 CurrentSquare += dieValue;
 CurrentPlayer++;
 if (CurrentPlayer > NumberOfPlayers) CurrentPlayer = 1;
}

A quick refactor from the green bar

We now have a green bar (well, yellow if you count the skipped test I guess). Time to take a look for potential refactoring opportunities. I've been a bit slack about this up to now as I haven't noticed anything obvious while coding and haven't explicitly stopped to think about refactoring. I have a bad habit of doing this -- I do design work while writing the code to pass the test, rather than deferring it to the refactoring stage. This can lead me to generalising to early or changing the design without getting clear direction from the tests and passing implementation. Note to self: premature generalisation is one of the many roots of all evil :)

In this case we've done the Right ThingTM and written simple code to pass the test, then looked at refactoring based on what the current implementation needs, rather than what we think it will need. The code within Roll() contains the logic for selecting the next player as well as for updating the current square. Let's Extract Method to make this more obvious.

public void Roll(int dieValue) {
 CurrentSquare += dieValue;
 nextPlayer();
}
private void nextPlayer() {
 CurrentPlayer++;
 if (CurrentPlayer > NumberOfPlayers) CurrentPlayer = 1;
}

This is purely a matter of taste. I find it reflects the intention more. If you don't, then leave it un-refactored. :-) Either way, key lesson here (for me, you probably know it already :)) is to defer design stuff until the production code shows a clear need, or until a test is too hard to write. Either way, design from the green bar whenever possible.

Time to face the music...

We probably shouldn't put it off any longer. Let's re-enable the test we skipped earlier:

//In GameSpec.cs:
[Fact]
public void Positions_should_be_correct_after_first_two_players_roll() {
 var threePlayerGame = new Game(10, 3);
 const int firstRoll = 3;
 const int secondRoll = 5;
 
 threePlayerGame.Roll(firstRoll);
 threePlayerGame.Roll(secondRoll);
 
 Assert.Equal(firstRoll, threePlayerGame.GetSquareFor(1));
 Assert.Equal(secondRoll, threePlayerGame.GetSquareFor(2));
 Assert.Equal(0, threePlayerGame.GetSquareFor(3));
}

This give the following assertion failure:

TestCase 'DaveSquared.GardenRace.Tests.GameSpec.Positions_should_be_correct_after_first_two_players_roll'
failed: Assert.Equal() Failure
Expected: 3
Actual:   0

This is failing because our implementation for GetSquareFor(...) stinks -- it's just returning 0. My fault, not yours. Let's get back to the green bar as soon as possible, then we'll worry about getting the design right. My original guess for passing this test was that we would need an array of player positions, and Roll() would just update the position for the current player. We have a current player concept in the code now, so let's chuck in an array and see how it goes:

//Bits and pieces from Game.cs:
public class Game {
    //...
 private readonly int[] playerPositions;
 //...
 public Game(int boardSize, int numberOfPlayers) {
  this.boardSize = boardSize;
  this.numberOfPlayers = numberOfPlayers;
  this.playerPositions = new int[numberOfPlayers];
  this.CurrentPlayer = 1;
 }
 public void Roll(int dieValue) {
  CurrentSquare += dieValue;
  playerPositions[CurrentPlayer - 1] = CurrentSquare;
  nextPlayer();
 }
 //...
 public int GetSquareFor(int player) {
  return playerPositions[player - 1];
 }
}

Running this fails with a new message:

TestCase 'DaveSquared.GardenRace.Tests.GameSpec.Positions_should_be_correct_after_first_two_players_roll'
failed: Assert.Equal() Failure
Expected: 5
Actual:   8

It is failing on our second assertion, Assert.Equal(secondRoll, threePlayerGame.GetSquareFor(2));. This gives us a good hint as to what's happening -- our first and second rolls of 3 and 5 are both being added to the same array index. Hold on, that's only half the story. Let's have a closer look at this:

public void Roll(int dieValue) {
 CurrentSquare += dieValue;
 playerPositions[CurrentPlayer - 1] = CurrentSquare;
 nextPlayer();
}

Brilliant Dave. What a fantastic coder I am :) I'm still adding all rolls to CurrentSquare, then assigning that to the current player position. In this case, CurrentSquare is 3+5=8 which fails our test. Why didn't you point this out? Luckily I had my tests to do it in your absence :) We'll fix it right now:

public void Roll(int dieValue) {
 CurrentSquare += dieValue;
 playerPositions[CurrentPlayer - 1] += dieValue;
 nextPlayer();
}

Tests pass. My own ineptitude aside, this test that was initially giving us troubles has been trivial to solve. We now have a green bar, so let's refactor. First obvious bit of duplication is the two square increments in the Roll() method. Let's update CurrentSquare to use our GetSquareFor(int player) method:

public int CurrentSquare { 
 get { return GetSquareFor(CurrentPlayer); } 
}
//...
public void Roll(int dieValue) {
 playerPositions[CurrentPlayer - 1] += dieValue;
 nextPlayer();
}

CurrentSquare is no longer a getter/setter, but is a convenient shorthand for GetSquareFor(int player). Our Roll() method is fairly clear. We could make it a little bit clearer by extracting a moveCurrentPlayer(int squares) method, but would also mean more indirection. I'll make you a deal, if we end up with a few playerPositions[CurrentPlayer - 1] style array indexes (the -1 is pretty ugly), then we do something about it. For now it is probably ok.

Looking at Game from the perspective of the S.O.L.I.D. principles, I think the main one we have to be wary of is violating the Single Responsibility Principle (SRP). Current Game is responsible for:

  • Number of squares on the board
  • Number of players
  • Keeping track of whose turn it is
  • Keeping track of each player's position
  • Knowing when the game has finished

Are these cohesive enough to count under the banner of one responsibility? I'm not sure, but I can't currently think of a better abstraction (feel free to leave comments :-)). For now let's stay conscious of this and we'll revisit it if it starts becoming a problem.

We're done? No we're not!

So are we done for our multiple players story? After running a larger test it appears so. However, after updating the demo we see some strange behaviour. An extract of from the demo code and the output are shown below:

//From main() in Program.cs:
const int numberOfSquares = 20;
const int numberOfPlayers = 2;
//...
Console.WriteLine("Creating a new game with " + numberOfSquares + " squares and " + numberOfPlayers + " players.");
var game = new Game(numberOfSquares, numberOfPlayers);
Console.WriteLine("Press any key to roll the die.");
while (!game.IsFinished) {
 Console.ReadKey(interceptKey);
 var dieRoll = GetDieValue();
 game.Roll(dieRoll);
 var currentState = (game.IsFinished) ? "You won the game!" : "Now on square " + game.CurrentSquare;
 Console.WriteLine("Player " + game.CurrentPlayer + " rolled a " + dieRoll + ". " + currentState);
}
//...
Creating a new game with 20 squares and 2 players.
Press any key to roll the die.
Player 2 rolled a 1. Now on square 0
Player 1 rolled a 3. Now on square 1
Player 2 rolled a 2. Now on square 3
...snip...
Player 2 rolled a 2. Now on square 18
Player 1 rolled a 2. Now on square 14
Player 2 rolled a 3. You won the game!

Why does player 2 have the first go? And why do they roll a 1 and yet are on square 0? The reason is highlighted in the code snippet above -- the Roll() method updates the Game so that it is the next player's turn. When the demo gets to writing out the current player's position and state, it is actually writing the details for the next player who is about to have their turn.

I believe this is a form of temporal coupling, or coupling in time. The CurrentSquare and CurrentPlayer methods depend on whether they are called before or after Roll. There is almost certainly going to be a problem with IsFinished as well, as that depends on the CurrentPlayer too.

I've been worried about this for a little while actually, especially when thinking about how the GUI will probably want to animate the initial move, then an additional move up or down the snake/ladder/critter type thing. It looks like we'll either have to trigger events from Roll, or break it up and have some kind of coordinator object.

I am quietly confident that we can change our design to support this when we get some tests around the "feature square" or GUI stories, and that these tests will drive us toward a decent design and implementation. Again, let's stay conscious of this coupling and work around it in our demo code. Remember that our demo code is not production code, so we are being a little less precious with it. Next iteration we'll make sure we write tests to cover this and drive a nicer design.

Here's the new main loop in the demo code:

while (!game.IsFinished) {
 var currentPlayer = game.CurrentPlayer;
 Console.ReadKey(interceptKey);
 var dieRoll = GetDieValue();
 game.Roll(dieRoll);
 var currentState = (game.IsFinished) ? "You won the game!" : "Now on square " + game.GetSquareFor(currentPlayer);
 Console.WriteLine("Player " + currentPlayer + " rolled a " + dieRoll + ". " + currentState);
}
Creating a new game with 20 squares and 2 players.
Press any key to roll the die.
Player 1 rolled a 5. Now on square 5
Player 2 rolled a 3. Now on square 3
(...snip...)
Player 2 rolled a 1. Now on square 10
Player 1 rolled a 5. Now on square 23
Player 2 rolled a 5. You won the game!

As predicted, our IsFinished property is having problems because of the coupling issue. We'll fix this, then we're done.

Test-first debugging

Let's write a test to expose the bug with the IsFinished implementation:

[Fact]
public void Game_should_finish_as_soon_as_any_player_reaches_the_end() {
 var threePlayerGame = new Game(5, 3);
 threePlayerGame.Roll(1);
 threePlayerGame.Roll(6);
 Assert.True(threePlayerGame.IsFinished);
}

This fails. At the time the assertion is evaluated player 2 has finished, but the current player is player 3, who is yet to finish. This should be straight-forward to pass from here:

public bool IsFinished {
 get {
   return playerPositions.Any(square => square >= boardSize);
 }
}

All the tests now pass. We've now removed the temporal coupling between Roll and IsFinished, and our demo now works as expected:

Creating a new game with 20 squares and 2 players.
Press any key to roll the die.
Player 1 rolled a 1. Now on square 1
Player 2 rolled a 1. Now on square 1
(...snip...)
Player 1 rolled a 2. Now on square 17
Player 2 rolled a 2. Now on square 15
Player 1 rolled a 3. You won the game!

Press a key to exit.

That's a wrap!

Not sure if this looks like a lot of work to you, but it actually represents only a couple of minutes of coding time, and a couple of minutes of thinking time (plus lots of time to write it all down in excruciating detail :-)). Point is that each iteration so far has been really quick despite (or because of?) involving lots of small steps.

You can browse or checkout the final code for this iteration from here. Thanks for making it this far! :)

Friday, 16 May 2008

Authorisation rule precedence in web.config

What will happen if the <authorization /> elements in a web.config conflict?

<?xml version="1.0"?>
<configuration>
 <system.web>
  <authentication mode="Windows"/>
  <authorization>
      <allow users="*" />
      <deny users="*" />
    </authorization>
 </system.web>
</configuration>

Most people that know anything about ASP.NET will realise that the authorisation rules are evaluated in order (from MSDN: "the authorization module finds the first access rule that fits a particular user account"), so in this case the <allow /> will be evaluated first and all users will get access. Unfortunately, I am not one of these gifted people, and have been blissfully ignorant of this fact despite working with ASP.NET since its release in 2002*.

Feel free to express your ridicule in the comments :)

In other news related to both web.config and my ignorance, I discovered when reading up on this at MSDN that you can use <allow users="./SomeLocalAccount" /> to reference the current computer if you are using local machine accounts, which has come in handy for the stuff I am working on today.

* By way of excuse for the inexcusable, a lot of my ASP.NET work has relied on old-style NTFS permissions (long story), or very basic rules like deny ? and allow *, so I've never ended up thinking much about this. When pressed on the topic I thought the strongest condition might take precedence :-\

Garden Race Pt 1: Snakes, ladders and iterations

This post is part of a series on the (very) basics of iterative development using the example of a simple Snakes and Ladders-like game. Links to each post in the series will be added to the index page.

For a while now I've wanted to write a Snakes and Ladders-style game for my daughter, both to be a nice nerdy Dad, and to practice some dev stuff. I was going to create "Warps and Wormholes", but firstborn was adamant she wanted fairies involved. And so I've ended up with "Garden Race", which is going to be a race for players to make it to one end of the garden aided by fairies, butterflies and other girlie stuff, while hindered by lizards, hoses, and other less-girlie stuff.

I intend to use iterative development for this project -- I'll start off with a thin slice of functionality and keep adding to it to build up a semi-usable game. This should accomplish two things: first, showcase my own ineptitude, and second, to help improve my TDD and development skills. While I'm not exactly sure how far I'll get with this project (free time is short at present), I can commit to being fairly honest during this process. If and when I stuff up, I'll write it down (I might excuse myself a quick spike here and there so the posts don't get bogged down to much, but the stuff ups will stay).

Note: MS has a free game design version of Visual Studio that might be useful if your aim is to make a good game for your kids (instead of just playing with dev stuff). There are also a few open source frameworks out there (like Childsplay).

For my starting point, I began with a rough solution structure (main Game project and a test project), chucked it in a local SVN repo, and setup some of the tools I'd need. I'm trying using a /src based configuration just for kicks, and might try nant just for something different. I am also trying XUnit.Net, instead of my usual NUnit test framework.

Requirements

Our customers, i.e. my firstborn (after some prompting) and I, want a Snakes and Ladders-type game involving fairies and other garden-dwelling folk. Here is the basic statement of what we want:

"Garden Race is a computer-based board game. Players take it in turns to roll a die, and then move the corresponding number of squares on the board. If the player lands on a square featuring a garden creature of obstacle at the end of their turn, then that creature or obstacle will move the player to a connected square on the board. The first player to reach the bottom of the garden (the end of the board) wins. We want fancy 3D graphics, surround sound, and it has to be ready yesterday."

Ever noticed how hard it is to succinctly describe a simple concept, even something as simple as this? Let's try and remove some ambiguity by boiling things down into user stories.

  1. A player can roll the die, and then move that many spaces along the board.
  2. A player that ends his or her turn on a "feature square" (a square containing a creature or obstacle), will be moved to the square connected with that feature.
  3. There can be 1-4 players, and each player has their turn in sequence.
  4. A player that reaches the final square wins the game.

That should probably be enough to get us going.

Planning and design for this iteration

In the spirit of iterative design we are going to first try to deliver a slice of functionality. As we are currently unsure of exactly how to present the customer with fancy 3D graphics and sound (at this stage the dev team (me) would like to try WPF or QT4, but we don't know all the requirements yet), let's focus on the core game functionality, which is pretty much captured by the user stories above.

For our first iteration we've agreed with the customer to deliver stories 1 and 4, which is basically a single player rolling a die and moving to the end of the board. Exciting game huh? But it should reveal some basics of how the game mechanics work, so it seems a safe place to start.

If we are picking nouns for potential classes in our game we might come up with Player, Die, Square, and Board, but we're definitely not going to use nouns as a basis for our design. A nice place to start might just be a Game or GameEngine class. What tests could we come up with for our first story?

  • A player should not be on the board until the roll the die and move.
  • A player that rolls a 4 should then be on the 4th square from the start.
  • A player that rolls a 2, and then a 6, should be on the 8th square from the start.
  • The game should finish once the player reaches the end.

We currently don't have enough information to implement all of this. How many squares are there on the board? What is the maximum value of the die used? What happens if the player is one square from the end, and rolls a 3? The first couple of points we will check with the customer, but it doesn't really affect our design. Let's test for the last case though, and we'll check with the customer if our assumption is correct:

  • A player that is one square from the end, and rolls a 3, should win the game.

Before we jump into this iteration, I'd be really interested to hear any up-front design ideas you have for this. If you were going to draw a UML class diagram or write up some CRC cards, what classes, data and relationships would you have? I've got my own ideas, but I don't want to influence my iterative design process too much at this point, nor do I want to deliberately come up with a shoddy upfront design and then marvel at how well my iterative design (hopefully) turns out. Please feel free to leave your design ideas in the comments or email me.

Right, let's start.

First tests

Let's look at the second test on our test list. It looks like an easy thing to do and should help us learn a little about the problem domain.

public class GameSpec {
    [Fact]
    public void Player_should_be_on_fourth_square_after_rolling_a_four() {
        var game = new Game();
        game.Roll(4);
        Assert.Equal(4, game.CurrentSquare);
    }
}

Not going to keep much of this, I'm pretty sure of that. But we need to start somewhere. By the way, if you aren't familiar with XUnit.Net, [Fact] == [Test]. Now let's pass the test:

public class Game {
    public int CurrentSquare;

    public void Roll(int dieValue) {
        CurrentSquare += dieValue;
    }
}

Now let's test two rolls, which is the third test on our list.

[Fact]
public void Player_should_be_on_eight_square_after_rolling_a_two_then_a_six() {
 var game = new Game();
 game.Roll(2);
 game.Roll(6);
 Assert.Equal(8, game.CurrentSquare);
}

This works without change, as we jumped straight to an obvious implementation for Roll(). We could have taken smaller steps and initially used CurrentSquare = dieValue; to pass the first test, the updated it to pass the second test, but we don't need to do that unless we aren't really sure how to proceed.

Let's add a third test to make sure the player starts off the board, or square 0.

var game = new Game();
Assert.Equal(0, game.CurrentSquare);

Again, this passes without modification. We also have a test on our list about finishing the game. We don't have too much information about how this works, so let's look at what we can test.

[Fact]
public void Game_should_finish_when_player_reaches_end_of_board() {
 const int boardSize = 10;
 var game = new Game(boardSize);
 game.Roll(boardSize);
 Assert.Equal(10, game.CurrentSquare);
 Assert.True(game.IsFinished);
}

This introduces two new concepts: board size, and the game state as finished or not finished. To get this to compile we need to add non-default constructor to Game, which means we also need to explicitly add a default constructor if we want to stop our other tests from breaking. We also need to add an IsFinished property to Game. The following implementation compiles and passes all the tests.

public class Game {        
 public int CurrentSquare;
 public Game(int boardSize) {}
 public Game() {}
 public bool IsFinished {
  get { return true; }
 }
 public void Roll(int dieValue) {
  CurrentSquare += dieValue;
 }
}

The IsFinished implementation obviously stinks, so let's also add a test around unfinished games.

[Fact]
public void New_game_should_be_unfinished() {
 const int boardSize = 10;
 var game = new Game(boardSize);
 Assert.False(game.IsFinished);
}

I first did a trivial implementation:

public bool IsFinished {
 get { return CurrentSquare == 0; }
}

Which failed both my IsFinished tests. Oops, that should be CurrentSquare != 0. Tests now pass, but the implementation still stinks. Let's try this one:

[Fact]
public void In_progress_game_should_be_unfinished() {
 const int boardSize = 10;
 var game = new Game(boardSize);
 game.Roll(5);
 Assert.False(game.IsFinished);
}

Which we can pass with this:

public class Game {
 private readonly int boardSize;  
 public Game(int boardSize) {
  this.boardSize = boardSize;
 }
 public bool IsFinished {
  get { return CurrentSquare >= boardSize; }
 }
 //...[snip]...

The last test on our list so far is to see what happens when we overrun the last square on the board.

[Fact]
public void Game_should_still_finish_when_player_overruns_last_square() {
 const int boardSize = 10;
 var game = new Game(boardSize);
 game.Roll(boardSize + 2);
 Assert.True(game.IsFinished);
}

This passes because we used >= for the CurrentSquare/boardSize comparison. One thing I haven't been doing is the refactor step of the TDD red-green-refactor process. Let's look at Game:

public class Game {
 private readonly int boardSize;
 public int CurrentSquare;
 public Game(int boardSize) {
  this.boardSize = boardSize;
 }
 public Game() {}
 public bool IsFinished {
  get { return CurrentSquare >= boardSize; }
 }
 public void Roll(int dieValue) {
  CurrentSquare += dieValue;
 }
}

Not much to refactor there, right? The tests have some duplication in the Game setup though. And the default constructor of Game looks fairly useless. Normally I would just whack that into a [SetUp] method, but XUnit.Net discourages this as it can make for non-obvious test contexts. My GameSpec tests currently want to execute in the one test context -- a new Game with 10 squares. It seems reasonable that my GameSpec HAS-A context, so let's add a game as a field with a descriptive name. I can then replace the game initialisation in each test with a simple reference to newTenSquareGame, and get rid of Game's default constructor.

public class GameSpec {
 private readonly Game newTenSquareGame = new Game(10);
 //...[snip]...
 [Fact]
 public void Game_should_finish_when_player_reaches_end_of_board() {
  newTenSquareGame.Roll(10);
  Assert.Equal(10, newTenSquareGame.CurrentSquare);
  Assert.True(newTenSquareGame.IsFinished);
 }
 //...[snip]...

If we start having lots of different contexts or complicated contexts we may want to revisit this, but the whole test fixture reads fairly well for now. Full disclosure: before this approach I mucked around with some crazy test structure ideas I have regarding tests and test contexts. I'm omitting that from this post as it was mainly for personal interest rather that something I would normally do.

So what's next? Our test list is empty, and we seem to have completed most of our first iteration, stories 1 and 4. If you remember, these basically covered moving a single player around the board, and being able to finish the game. This isn't really something we can show our customer though. You don't go showing a youngin' a bunch of unit tests when they are expecting a fairyised version of Snakes and Ladders. And we haven't even dealt with the concept of "rolling a die", we have just assumed a value. But we seem to have the basic functionality we promised for this iteration.

Customer demo

To finish this iteration, let's write a console app that will allow our customer to run through the current game logic. Here's what I'm thinking of:

  Creating new game with 20 squares.
  Press a key to roll the dice.
  You rolled a 4. Now on square 4.
  You rolled a 6. Now on square 10.
  ...
  You rolled a 2. You won the game!

At first I was thinking about creating a GameController class and writing some tests around that, then calling that from a simple console app. But we don't need that yet. So let's just do the simplest thing that will work for our demo. And because it is slapped together and not designed to specific requirements, let's just promise not to use any of this code in the actual product.

namespace DaveSquared.GardenRace.ConsoleFrontEnd {
    class Program {
        private static readonly Random random = new Random();
                
        static void Main(string[] args) {
            Console.WriteLine("Welcome to Garden Race! It's like Snakes and Ladders, only without the copyright violation!");
            Console.WriteLine();
            
            const int numberOfSquares = 20;
            const bool interceptKey = true;
            
            Console.WriteLine("Creating a new game with " + numberOfSquares + " squares.");
            var game = new Game(numberOfSquares);
            Console.WriteLine("Press any key to roll the die.");
            while (!game.IsFinished) {                
                Console.ReadKey(interceptKey);
                var dieRoll = GetDieValue();
                game.Roll(dieRoll);
                var currentState = (game.IsFinished) ? "You won the game!" : "Now on square " + game.CurrentSquare;
                Console.WriteLine("You rolled a " + dieRoll + ". " + currentState);
            }
            Console.WriteLine();
            Console.WriteLine("Press a key to exit.");
            Console.ReadKey(interceptKey);
        }

        static int GetDieValue() {
            return random.Next(1, 6);
        }
    }
}

A now for the moment of truth:

Console app showing our demo

Fantastic! Assert.That(this_game_rocks).SaidWith(sarcasm)! On the other hand, it took about 12 minutes to code this iteration up as well as write out tests (plus lots of time for me to type out this narrative), and our story list made it clear when we could stop. So let's go show our customers. I'm sure they'll be impressed...

To be continued...

Download

You can browse through or download this tremendously exiting code from davesquared.googlecode.com.

Thursday, 15 May 2008

Garden Race Series: Basics of iterative development and TDD

This page is an index page for the Garden Race series. This intention behind this series of posts is to teach myself a bit about the basics TDD and iterative development by working through an example of building a Snakes and Ladders-style game. Hopefully this example strikes a balance between being simple enough to write up as blog posts and being involved enough to for me to learn some things about iterative development that can translate to real work.

Note: This is post has been back-dated to appear before the other posts in the series. It was written after Part 2.

Wednesday, 7 May 2008

Enabling tracing for WCF (then making sense of the output)

I've been battling with a few of WCF's "endearing" foibles over the last couple of days (like this one). One thing that I really should have noticed earlier to help with this battle is that you can enable tracing for WCF. MSDN gives this example:

<configuration>
   <system.diagnostics>
      <sources>
            <source name="System.ServiceModel" 
                    switchValue="Information, ActivityTracing"
                    propagateActivity="true">
            <listeners>
               <add name="traceListener" 
                   type="System.Diagnostics.XmlWriterTraceListener" 
                   initializeData= "c:\log\Traces.svclog" />
            </listeners>
         </source>
      </sources>
   </system.diagnostics>
</configuration>

This produces a fairly unreadable mess, but you can use the Service Tracer Viewer (SvcTraceViewer.exe) that comes with the Windows SDK (C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin on my PC) to get some useful information out of it. This is actually quite a cool tool, providing a nice interface to view all the different activities happening behind the scenes, and highlighting errors that occur.

WCF Trace Viewer screen shot

Friday, 2 May 2008

Adding IPrincipal to the list of known types in WCF

WCF has a concept called Known Types, which lets WCF handle subclasses and interface implementations passed to services. Normally you can just whack a KnownTypeAttribute on your DataContract and you're good to go:

[DataContract]
[KnownType(typeof(Manager))]
public class Employee { ... }

In the example above, the service will be able to use the Manager subclass anywhere it expects an Employee.

This doesn't help much when you want to use non-DataContract types like IPrincipal. Trying to pass a GenericPrincipal to a service operation that expects an IPrincipal gives you an error message like this (line breaks added for slightly improved legibility):

System.Runtime.Serialization.SerializationException:
Type 'System.Security.Principal.GenericPrincipal' with data contract name 'GenericPrincipal:http://schemas.datacontract.org/2004/07/System.Security.Principal' is not expected. 
Add any types not known statically to the list of known types - 
for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

One solution is to decorate your service contract with a ServiceKnownTypeAttribute:

[ServiceContract]
[ServiceKnownType(typeof(GenericIdentity))]
[ServiceKnownType(typeof(GenericPrincipal))]
public interface ISomeService {
  [OperationContract]
  String DoSomethingWith(IPrincipal principal);
}

While I don't necessarily recommend exposing IPrincipal through your service, the technique is worth knowing about. Most of the search results I got mentioned KnownTypeAttribute and not ServiceKnownTypeAttribute.

Thanks to Steven Cheng who answered this question in his response to this post. Steven also provided a link to Bennie Haelen's fantastic post on Handling Data Contract Object Hierarchies in WCF, which covers more than you could ever want to know about this stuff :-).