Page 1 of 2 in the refactoring category Next Page
Welcome back to the 4.5th part of my multi-partite series that traces my progress into refactoring some old code that implements a chess board control – specifically, the rules engine that referees piece movement. Unfortunately, I’m a bit late with this as some life events intervened, and as a result I’ve had to abbreviate what I wanted to do with this installment. Hence, version 4.5!
So far, we’ve covered a bit of ground getting the stage set for aggressive refactorings with source control, code analysis tools, unit testing and refactoring aides. We’ve restructured our solution, moved test projects around, uploaded them to a web-based repository for sharing and devised some tests to exercise the engine across some valid and invalid moves.
Today, we’re going to look at a helper object in the engine (formerly FENAnalyzer, now FENTranslator) that is responsible for setting up the chessboard in a variety of states using a specially-formatted string. The motivation for examining this object is to be able to test the rules engine with more complex, in-progress game states without having to run-through an entire set of moves as we’ve done with the unit tests for replaying a complete game.
Catching Up…
Before I get too far, some quick notes on changes to the source that you might notice. If you’re following along at home, I recommend deleting your working copy and pulling down the latest version of the solution – we should be at revision 32 right now:
- There’s a new solution folder called Tests where I’ve re-located RNChessBoard.RNChessRulesEngine.Tests, and where all future NUnit test assemblies will be stored.
I’ve updated the ChessRulesEngineTestFixture class using the Extract Superclass refactoring to create BaseChessRulesEngineTestFixture which allowed me to move some common methods for running the game-move replay methods up the inheritance chain and make them more widely-available. This is one of the most common refactorings I do when writing unit tests – sometimes, I just cut out the middle-man and write a base class to start off.
I also introduced a new method into this base class for replaying a series of multiple games using jagged-arrays called ReplayTestGameBattery, and added some new replay arrays for testing black and white pawn moves (BlackPawnTestMoves and WhitePawnTestMoves).
- Renamed FENAnalyzer to FENTranslator to better reflect its dual purpose (ie. constructs and interprets FEN strings)
- Did some minor renaming and cleaning up of the solution after moving things around – you’ll see this under the imaginative comments of “clean up on aisle x”.
Building new tests with Forsyth-Edwards Notation
While crafting the test arrays for the black and white pawn openings, I found myself wanting to construct mid-game scenarios to enable faster, more precise testing – say, for an emerging en-passant capture. As it stands, I can only do this by constructing an array of sequential moves to replay the scenario – I wanted to jump right in with a preset board state.
Fortunately, I had already built this exact kind of functionality into the rules engine oh-so-long ago with a helper object called FENTranslator. This class implements an engine that translates a simple string in Forsyth-Edwards Notation (FEN) into a basic array that the rules engine can then use to set piece positions and game states; conversely, it can also create a FEN string from a current board set up. Here’s how it’s used in the WinForms control to set the default start game position:

Quick FEN Primer
FEN strings are comprised of six space-delimited fields that represent the current position of pieces on the board, side to play, castling availability, en passant state and half and full moves. The first field defines the eight ranks of the chessboard, with the black side pieces in lower-case letters (rook, knight, bishop, queen, king and pawn) and the white in upper-case; squares that have no pieces are represented by numbers. The FEN notation for the start of a game would be:
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
For example, after the typical white-side queen’s pawn opening, the FEN notation would be:
rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq - 0 1
Black’s response with his king-side knight to F6:
rnbqkb1r/pppppppp/5n2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 2
The “KQkq” markers indicate whether either side has used their sole opportunity to castle king-side or queen-side. For example, if white castles king-side, here’s how the board state would be represented in FEN:
rq2kbnr/pppbpppp/2n5/3p4/2BP4/4PN2/PPP2PPP/RNBQ1RK1 b kq - 0 5
Note that white’s indicator is removed, while black’s remains. In order to better see how the curtrent board’s FEN changes, I’ve added an additional textbox to our test app that calls the WinForm control’s GetCurrentPositionAsFEN() method, which in turn uses the FENAnalyzer object to generate the string:

Testing the FENTranslator Object
This turned out to be a little easier than I thought: Initially, I was quite concerned about the edge and corner cases that this object might present since the typical FEN string has a lot of potential to be malformed. As it turns out, I accounted for this with some regular expressions.
First Tests – Not Null and Default States
I began my testing by creating the FENTranslatorTestFixture and did the routine Assert.IsNotNull check, and then followed with a more ambitious test containing several assertions to validate the default state for the FENTranslator object. This object can be instantiated one of two ways, with either a FEN string or an array. To begin, I needed to supply the the object with a 64–element integer array representing the start state of the board:
27 private static readonly int[] START_BOARD_ARRAY = new int[64] 28 { 29 -4,-2,-3,-5,-6,-3,-2,-4, 30 -1,-1,-1,-1,-1,-1,-1,-1, 31 0,0,0,0,0,0,0,0, 32 0,0,0,0,0,0,0,0, 33 0,0,0,0,0,0,0,0, 34 0,0,0,0,0,0,0,0, 35 1,1,1,1,1,1,1,1, 36 4,2,3,5,6,3,2,4 37 };
Negative numbers represent the black pieces, positive numbers white and zeroes indicate an empty square – in practice, the rules engine maintains the current board state with a similar array, so this is a practical setup step. My test, New_ValidFENString_NotNull instantiates the FENTranslator with this array and checks each of the object’s default states to ensure they are correct:
57 [Test] 58 public void New_ValidFENString_NotNull() 59 { 60 FENTranslator fen = new FENTranslator (FEN_START_WHITE); 61 62 Assert.IsNotNull(fen, "FENBuilder failed to instantiate."); 63 Assert.IsTrue(fen.WhiteKingsideCastle, "Initial white king-side castle state is invalid."); 64 Assert.IsTrue(fen.WhiteQueensideCastle, "Initial white queen-side castle state is invalid."); 65 Assert.IsTrue(fen.BlackKingsideCastle, "Initial black king-side castle state is invalid."); 66 Assert.IsTrue(fen.BlackQueensideCastle, "Initial black queen-side castle state is invalid."); 67 68 Assert.AreEqual(1, fen.FullMoveNumber, "Initial full move number is invalid."); 69 Assert.AreEqual(0, fen.HalfMoveClock, "Initial half-move number is invalid."); 70 Assert.AreEqual(PlayerTurn.White, fen.ActiveColor, "Initial player turn is invalid."); 71 72 Assert.IsNotEmpty(fen.ChessBoardArray, "Initial chessboard array property is invalid."); 73 Assert.AreEqual(START_BOARD_ARRAY, fen.ChessBoardArray, "Initial chessboard array state is invalid."); 74 75 Assert.AreEqual("-", fen.EnPassantTargetSquare, "Initial En Passant target square is invalid."); 76 }
I added and tested each Assert individually to check my board state – they all passed, so I now had a good baseline regression test that I could move forward from. Next, I decided to focus on tests that instantiated the object with a FEN string as I thought there would be a lot more work to do here. To keep things brief, I’m going to review just a few of the tests – you can pull down the source to see more detail and my thinking process at the time.
Next Test – Inverse Relationships with ToString()
One of Hunt & Thomas’ unit testing maxims suggests that you should be able to validate your code by checking inverse relationships. In other words, is there a way to validate an object’s methods using its output as an input – in our case, this could be done by instantiating the object with the array used in New_ValidFENString_NotNull and call the object’s ToString() implementation:
18 private const string FEN_START_WHITE = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
78 [Test] 79 public void ToString_ValidStartFEN_Equality() 80 { 81 FENTranslator fen = new FENTranslator (FEN_START_WHITE); 82 Assert.AreEqual(FEN_START_WHITE, fen.ToString(), "Invalid FEN string was returned."); 83 }
Line 18 shows the string constant I’m using to test for a valid default FEN string; by calling ToString() on a freshly-instantiated FENTranslator object, there should be no difference – and indeed this test passes. Of course, this test does suggest that we need to look at some edge cases for instantiation using an array - we’re placing a lot of trust in the ToString() method – but this will do as a backstop for the moment.
Expected Exceptions Tests
A good portion of the tests I added address concerns around instantiating the object with a malformed FEN string. To support these tests, I un-commented some lines of code in the ImportFEN() method to throw an ArgumentException when it detects fewer than six space-delimited fields:
205 string[] fenFields = FENString.Split(new char[] {' '},6); 206 if(fenFields.GetLength(0) < 6) 207 { 208 throw new ArgumentException 209 ("FEN input string does not contain the required six space-delimited fields."); 210 }
I tested for this using the ExpectedException attribute for my unit test:
85 [Test,ExpectedException(typeof(System.ArgumentException))] 86 public void New_BadFENString_NoSpaceDelimiters_ArgumentException() 87 { 88 string testFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNRwKQkq-01"; 89 FENTranslator fen = new FENTranslator (testFEN); 90 }
But this isn’t quite right – it’s not so much the argument that’s the exception, but the format. Accordingly, I modified the throw on line 208 to use a FormatException instead and updated my tests.
Next, I did some minor refactorings within the PopulateBoardArrayFromFEN() method to throw a FormatException when presented with a malformed FEN rank string - things weren’t nearly as expressive or complete as I wanted. So, we went from this:
261 int sqIndex=0; 262 for(int rankIndex=0; rankIndex<fenRanks.GetLength(0); rankIndex++) 263 { 264 string rank = fenRanks[rankIndex]; 265 if(!CheckFENRank(rank)) 266 { 267 throw new ApplicationException 268 ("The FEN piece placement field contains an incorrect rank string:\n" + 269 "[" + rank + "]"); 270 }
to this:
271 int sqIndex=0; 272 for(int rankIndex=0; rankIndex<fenRanks.GetLength(0); rankIndex++) 273 { 274 string rankString = fenRanks[rankIndex]; 275 if(!IsFENRankStringValid(rankString)) 276 { 277 string rankException = "The FEN string at rank {0} is not well-formed: [{1}]"; 278 throw new FormatException(string.Format(rankException, rankIndex, rankString)); 279 }
I tested this fragment change in several tests, eg. New_BadFENString_BadBlackRank8_abcdefgh_FormatException, New_BadFENString_InvalidRank3_SpaceCount9_FormatException, New_BadFENString_BadBoardDelimiters_FormatException, etc.
Of course, this led to refactoring the IsFENRankStringValid – just to tighten things up a little, from this:
446 private bool CheckFENRank(string FENRankString) 447 { 448 // Analyze FEN rank for space count 449 MatchCollection mcSpaces = Regex.Matches(FENRankString,"[1-8]"); 450 int spaces=0; 451 foreach(Match m in mcSpaces) 452 { 453 spaces+=int.Parse(m.Value); 454 } 455 if(spaces>8) return false;
to this:
455 private bool IsFENRankStringValid(string FENRankString) 456 { 457 // Parse the FEN string ranks for empty squares 458 MatchCollection mcEmptySquares = Regex.Matches(FENRankString,"[1-8]"); 459 int emptySquareCount = 0; 460 foreach (Match m in mcEmptySquares) 461 emptySquareCount += int.Parse(m.Value); 462 463 if(emptySquareCount > 8) return false;
Incidentally, this method does all the heavy-lifting for validating the FEN string ranks that I was concerned about – by leveraging the Matches method, I can iteratively apply a pattern against a string which makes validating the FEN empty squares and piece positions a snap.
Next Steps: More edge tests, boundary tests, state tests
So far, we’ve made some good progress testing the FENTranslator object in this post, and learned a little about Forsyth-Edwards Notation along the way, but there’s obviously more to do. As I’ve mentioned above, there’s room to ensure the values boundaries for the test arrays are within acceptabled ranges (ie, -6 to 6), that the FEN strings for castling and en passant are working, etc. Ultimately, though, the FENTranslator object wasn’t intended to be an engine as much as a helper class, which I need to keep in mind as I work through refactoring it.
Once I’ve added enough edge/corner case tests to bolster my confidence in the FENTranslator, I can return to constructing additonal regression tests for validating piece movements and their outcomes in the rules engine before moving into any refactoring of that code. While this may all seem a bit tedious, it is necessary to ensure we don’t make any fatal changes that would break the engine.
As always, you can obtain the latest release of the codebase from http://rnchessboardcontrol.googlecode.com/svn/trunk to see what’s been accomplished so far and to monitor progress as we go along. Cheers!
Greetings and welcome to the fourth installment where you, gentle blog reader and better practices enthusiast, have the opportunity to pair-program with me as I tackle some old and hoary code I wrote four years ago in an attempt to buff it into respectability. While the app in question is a .NET Windows Forms component that implements a chess board, this series is focusing on the rules engine behind it.
Today, I’ll be demonstrating how I crafted unit tests to exercise the rules engine with replays of classic (and not so classic) chess games – specifically, I want to ensure that I have a baseline of tests that demonstrate legal moves, captures, checks and mates.
Housekeeping
In my last post, I mentioned that the goal for this article would be to have the source code available for download via an online repository – as of Monday, I set up a Google Code Subversion repository for this purpose and will be using it going forward so that you can follow along with the revisions to the code as they’re made. I also mentioned that we’d be getting into some beefier tests – while this is the case, it’s not as beefy as I’d have liked as I ran into some unexpected difficulties. More on that later.
Unit Test Goal: Replaying Classic Chess Games
I the last installment, I wanted to craft some unit tests that I could use to replay classic chess games from history like Capablanka v. Alekhine 1927 or Stahlberg v. Petrov 1938 – the purpose was manifold:
- These games are usually 25+ moves in length, and because of the skill of the players involved, incorporate a wide array of moves and techniques;
- Because the games are historic, I know that each move is legal and the outcome for each move;
- Pushing the moves into the engine would validate the baseline behaviour for the MakeMove() method;
- Most importantly, the returned PlayerMoveResult struct type provides metadata to validate the outcomes for each half move (per side) telling us a great deal about how the internals of the engine are functioning.
With this objective in mind, I set about thinking of how to capture or generate test data for classic games that I could easily consume inside a unit test. My first instincts were to set up a delimited file with the algebraic coordinates for each move, along with validation flags for the move type and outcome – ooh! Maybe use XML, have some XPath queries to fetch the half moves and outcomes…
Stop. Stop it right there! As cool as this would be, it was also introducing complexity where I didn’t need it since I’d now have to be accountable for ensuring that the code to process the XML was tested and valid. Instead, I decided to do the simplest thing that works and began roughing-in a simple string array with delimited fields that would identify each half move along with corresponding expected outcomes for move type and result:
34 class TestGames
35 {
36 // Capablanca vs. Mieses 1913
37 public static string[] Capablanca_Mate_Mieses_1913 = new string[]
38 {
39 "D2-D4//nc/G8-F6//nc",
40 "G1-F3//nc/C7-C5//nc",
41 "D4-D5//nc/D7-D6//nc",
42 "C2-C4//nc/G7-G6//nc",
43 "B1-C3//nc/F8-G7//nc",
44 "E2-E4//nc/E8-G8//O-O",
45 "F1-E2//nc/E7-E6//nc",
46 "E1-G1//O-O/E6-D5//x",
47 "E4-D5//x/F6-E8//nc",
48 "F1-E1//nc/C8-G4//nc",
49 "F3-G5//nc/G7-C3//x",
My intent here is to have a simple string delimited with forward-slashes “/” to indicate each half move, result and type starting with white:
12 /// The strings for each move are structured in the following manner:
13 /// "{white from}-{white to}/{white result}/{white move type}/
14 /// {black from}-{black to}/{black result}/{black move type}"
Next, I wanted to validate the result for each move and indicate if the move resulted in material capture, castling, en passant capturing, pawn promotion, etc. I decided to borrow the codes and symbols for move results and types that are used in Standard Algebraic Notation for games to keep things intuitive and simple:
19 /// {result} has the following expected values:
20 /// "": Legal move, no immediate consequence
21 /// "!": Illegal move
22 /// "+": Move has placed opponent in check
23 /// "++": Move has placed opponent in check mate
24 ///
25 /// {move type} has the following expected values:
26 /// "x": Capture
27 /// "nc": Non-capturing move
28 /// "O-O": King-side castle
29 /// "O-O-O": Queen-side castle
30 /// "xep": En-passant capture
31 /// "!": Illegal move
32 /// "^": Pawn promotion
So far, so good. However, I soon began to realize a new problem with the arrays – they’re laborious to construct and prone to errors when entered by hand, especially because I was transcribing the moves from a book that used the old-style notation. I solved this problem by creating a quick WinForms app that used the existing chessboard control to capture moves and transcribe them into a format I could easily cut & paste into my array definitions:

This might seem like cheating: After all, if my purpose of tests is to validate the engine’s behaviour, how can I be certain that what I’m capturing here is valid to use as input? Simply put, I’m using my own knowledge to verify that the moves and results correspond to the outcomes for the game, ie. captures, checks and mates – in other words, I’m following the first principle in Hunt & Thomas’ maxim about unit tests: Are the results right?
For the curious, I’ve added the above app to the solution under the RNChessBoardControl.DemoApp project which you’ll notice when you pull down the latest revision 11 or later of the code. I won’t delve into this for now so as to keep things brief, but you can easily see by viewing the code that it’s quite lightweight and didn’t take too much effort to build out. In this situation, crafting a quick tool that will save time later on is worth the time investment, especially to get test input data that we can be confident about.
Writing the Playback Tests
Using the tool, I captured three games into static string arrays that placed into a separate class, TestGames, which I kept in the same namespace as my test fixture for easy reference. At a high level, my plan for the playback test was simple:
- Iterate over the array for a sample game;
- Split each move string into constituent parts for the moves and results for each side;
- Push each move into the engine;
- Use Assertions to validate the move result and type.
My first cut at this method had everything happening in a single method so I could capture the essence of what I wanted to do:
Rev 6: makemove_fullgametomate_legal()
Definitely not pretty, however I wanted to capture the logic and validate the behaviours. There was definitely a little trial and error that I had to overcome with respect to parsing the moves, which I eventually consigned to some Regex pattern matching. Also note the GetMoveResultStringAsSAN() and GetMoveTypeStringAsSAN() methods which convert the PlayerMoveResult and MoveType enumerations returned for each move into strings that correspond to the SAN codes I’m using in the arrays:
Rev 6: GetSAN_helper_methods
While this test ran and corroborated the results, it needed to be refactored because it wasn’t very well focused – in other words it was exhibiting some code smells.
Step 1: Apply the Extract Method Refactoring
In order to address my smelly code, it seemed a good idea to split the array iteration/move entry code from the test method. Easy-peasy: Using the Refactor! Pro Visual Studio add-in, all I needed to do was highlight the code within the method definition and then click the elipses (…) that appeared below to trigger the Extract Method refactoring:

Clicking Extract Method, I’m prompted to specify where I want the new method to go and what it would be called:

I decided to move the new method below the test method stub, so I hit the down key and then enter – presto, our method has been riven in twain:

In order to make this change more meaningful, I decided to rename the method and add an argument for passing in a string array for the test game:

I then rebuilt the tests and ran them to verify everything was in working order before committing the changes to the repository under revision 8, and then added additional test methods for the other two games in revisions 9 and 10.
Step 2: DRY Refactorings
In the Pragmatic Programmer text, Hunt and Thomas introduce a concept that serves as the root for many refactorings called the DRY Principle or “Don’t Repeat Yourself”. This means we should avoid duplicating code wherever possible and collapse those segments we find into separate methods. If we look in the PlayTestGame method, there’s definitely some duplication happening:

The code segment above is practically identical to the block for validating the black test game move – the only differences are the string elements from the moveParts array that identify the moves and expected results and type. Refactor! Pro suggested that I extract this block into a new method with two arguments: moveIndex and moveParts[]:

Close, but no banana. The suggested method, GetPmr(), while a step in the right direction is locked to the ordinal positions for white’s move from the split array (ie, indices 0,1,2) – I’d end up creating a duplicate method for black’s move! It's also rather poorly named for my purposes. I decided to let the tool stub-out the method for me, but renamed it and changed the signature slightly:

I applied some renaming refactorings to make the intent of the method more generic for its new purpose:

All I had to do now was revise the calling method arguments, build and test. Note that at this point, I did not apply the refactoring the black move methods below – I wanted to confirm that the refactored code I had introduced was in fact working:


Awesome – all that was needed now was to replace the duplicate code for black with a similar method call to ExecuteTestGameMove() and pass in the elements from moveParts[]:

As we can see, even here in our test fixture we’ve gained some advantages for refactoring our code – our tests will be easy to read and maintain and we’ve consolidated four Asserts into two within an isolated method.
Rounding out this session, I finished up with additional test methods to run the two other sample games I added to the TestGames class.
Next Steps…
For the next installment in this series, I’ll add some additional test methods and finally get back to tackling the refactorings I’ve wanted to introduce to the DoMove() method. Check the code repository for updates to the codebase as I won’t be writing about them all as we go forward – in fact, there are additional tests for some edge cases that I’ll be adding over the next day or so. Cheers!
A quick post for this morning – I’m still working on the material for the next post in the “Refactoring” series, but I did want to advise that I’ve created a Google Code project where I have posted the source code to a SVN (Subversion) repository that I’ll be using for the duration of the project. This will allow those of you following along at home to pull down copies of the code by revision number – ie. you can “get latest” or anything up to that point.
Accessing the Source
The Google Code site can be found here:
http://code.google.com/p/rnchessboardcontrol/
The SVN repository can be found here:
http://rnchessboardcontrol.googlecode.com/svn/trunk
You will need a Subversion client to pull the code down to your local machine. There are several flavours of Subversion that are available, as well as client apps – personally, I use the following:
CollabNet’s Open Source Subversion Server and Client
Download the Server and Client for Windows from here:

Tortoise SVN Windows Explorer Extension
SVN is primarily a command-line tool, which if you get proficient with it is fairly quick. But I’m generally happy with the advances the GUI has afforded us. So I use Tortoise SVN to provide me an easy way to work with Subversion right from the Windows Explorer.
Download the Tortoise here:

Bringing up the RepoBrowser
The TortoiseSVN Repo-browser allows you to navigate remote or local Subversion repositories through a simple modeless window. You can bring it up by right-clicking in any open folder space and navigating the context menu thus:

This will bring up the Repo-browser window where you can now enter the URL for the remote repository:

Once the connection to the remote repository is established, expand the “trunk” folder to see the source elements:

Downloading the Source
Right-click the trunk folder in the Repo-browser and select “Check Out” – this will bring up the following dialog where you can specify the location where you want to locate your working copy:

If the folder doesn’t exist, TortoiseSVN will create it for you – click OK and you’ll begin pulling the source. Here’s what a successful checkout should look like:

Navigate to your working copy folder and you’ll see the latest revision of the code, which is currently at 2. This number will increase as we roll along, but you can opt to revert to any version you wish quite easily so you can view diffs and quickly see changes as they happened.

Have fun!
Welcome back for the third installment in my series (see Part 1, Part 2) wherein I chronicle my efforts refactoring some code I wrote over four years ago to implement a chess rules engine and WinForms control using C# under .NET v1.1. I’m hoping to demonstrate over the next few posts a few tips, techniques and tricks to improve established code with refactorings, unit tests and application of best practices that you might find useful in your own endeavours.
Last week I mentioned two tools that I’ll be using from this point forward to support constructing and running unit tests so we can backstop our new code against making destructive changes that would otherwise bust the build or introduce new bugs that we didn’t intend: NUnit and TestDriven.NET. For the impatient out there, we will be getting into refactoring soon, but as we’ll see below, I ran into a little issue as a result of setting up my tests that necessitated some backtracking.
Briefly, here’s a quick overview of each tool:
In spite of rumours on its demise, NUnit is very much the de facto if not the de jure free (as in beer) unit test suite for the .NET Framework. Yes, Visual Studio 2005 in the Team Editions supports its own unit test framework, which looks a lot like NUnit tests with differently-named method and class decorators, but I prefer the original. NUnit is modeled after JUnit, the Java unit test suite which in turn was based on seedwork by Kent Beck in Smalltalk – it has, therefore, a pretty solid pedigree.
NUnit provides you with a framework for writing regression test assertions to validate code behaviours along with both a console and GUI test runner harness. If you haven’t done any Test Driven Development (TDD) before, this will be a pleasant experience as you won’t have to roll-your-own test harnesses to see if your code works – you’ll just run the test assemblies and get immediate feedback on whether they passed or failed.
Another upshot to using a framework like NUnit is the option of later “hooking” your tests into a continuous integration suite like CruiseControl.NET which can synthesize your code versioning, build and tests to run automatically on code check-ins or other triggering events.
I’ve installed the latest stable version of NUnit for this exercise: 2.4.3 for .NET 2.0.
While NUnit is the cat’s pajamas for unit testing, and does support some IDE integration, it lacks a certain panache since its test-running goodness is run via an external app. This can be a throw-the-hands-in-the-air point for some folks who just cannot live without doing everything in Visual Studio, and will forever despise writing and running unit tests without some IDE support. So, to kick things up a notch and keep these folks interested, on-board and insanely productive, I recommend downloading and installing the TestDriven.NET Visual Studio add-in.
I won’t go much further into the addin except to say that it allows you the ability to run your tests simply by right-clicking inside either the test fixture class or test method – easy peasy. If you want to know more, check out the developer’s site for excellent overviews and tutorials. Ok, here’s a quick screen cap, just to whet the appetite:

I’m using the latest stable version: 2.8.2130 – It runs in all versions of Visual Studio except the Express Editions, which is for a whole host of reasons.
Getting ready to test: Adding a test fixture project
Once NUnit is installed, all of its core libraries are available to all and sundry projects through the GAC, so all we need to do is create a new library for housing our test classes (aka Test Fixtures) and add a reference to the NUnit.Framework to get access to the all the unit testing goodness. There are a number of schools of thought on how tests could/should be organized and named – below is my preference:

In this way, I create an NUnit test assembly for each assembly or executable I’m testing and it is clearly identified with the .Tests suffix. Now, I’ll add references for the RNChessRulesEngine and RNChessBoardCommonTypes projects, since there are dependencies between them; next, I’ll add a reference to the nunit.framework assembly via the .NET tab in the Add Reference window. Finally, I’ll rename the stubbed-out class ChessRulesEngine.TestFixture.cs, add some namespace references and an NUnit TestFixture attribute to indicate that this class will be used for containing test code:

Now that I’m this far, I’ll do a quick build and commit the new project to source control before proceeding.
Supporting the rules engine with preliminary unit tests
In the last installment, I decided to start my refactoring within the DoPlayerMove(int32,int32) method in the rules engine as it had not only a high cyclomatic complexity score, but was also an obvious entry point for running subsequent routines. This brings up an some questions: How do we know if the engine is running correctly right now? Subsequently, what kind of tests should we be writing?
Note: If you’ve never written a unit test before, don’t panic: It’s dead easy. Check out the NUnit Quickstart tutorial for some examples.
At a fundamental level, we want to craft tests that will demonstrate that the basic operations of the engine are sound, ie. that we trap for bad input, process moves correctly and can play out a game to mate. My first inclination is to code up a test that would play a well-known, classic game like Capablanca vs. Alekhine 1927 – French Exchange. This way, I know for certain what the outcomes after each move should be, the material captured, number of half moves (white) and full moves (black) that have occurred, check states for either side’s king and checkmate state.

Algebra rears its ugly head. Well, sort of.
Sounds like we have a plan, right? Of course, there’s always a little trip-up: DoPlayerMove() is a private method that is called by another private method, CommitPlayerMove(), which in turn is called by the publicly-accessible MakeMove(). We have our work cut out for us: In order to run a sample game through the engine, we need to validate the behaviours for MakeMove() which takes input from two strings representing the Standard Algebraic Notation (SAN) for the “from” and “to” squares, using the numbers 1–8 and letters A-H to represent the ranks and files (rows and columns of squares)respectively. Thus, if we want to make a basic Queen’s pawn opening, we’d want to move from “D2” to “D4”.
Let’s build-out a test to verify that the input “D2” and “D4” results in a valid move. First, we need to add a member object for the rules engine so we can test it, and a special NUnit method to instantiate the object when the battery of tests are run for the first time called TFSetUp():

Note the [TestFixtureSetUp] attribute that tells the NUnit framework to run this method exactly once for every run of our test fixture class. Next, let’s add a method to exercise MakeMove() with the SAN I mentioned above:

A few things to note here:
- The [Test] attribute, which indicates that this method is a unit test and should be executed by the NUnit framework;
- The test method name follows a convention to make it easy to identify (hat tip to Roy Osherove) the method, test state and expected outcome for the test.
- I’m using a classic NUnit assertion, Assert.AreEqual(), which compares an expected value (MoveResult.Legal enum) against the actual value returned from the PlayerMoveStatus property, which is a struct defined in RNChessDataTypes.cs. I’ve also added a descriptive message that will be returned when the test fails so that we can get meaningful feedback.
Observant keener types will notice that in my Assertion, I’m expecting MoveResult.ILLEGAL. This is because I want the test to fail first – this way I can be assured that the method is running correctly. Right-click inside the test method and select Run Test(s) from the context menu – you’ll see the following in the Output pane:

Blammo! We have our first validation point that the engine is working correctly – it’s taking input for a valid move and is returning a confirmation. Moving on, we adjust the method to check for PlayerMoveResult.LEGAL and the we get a pass:

Let’s add another test to check out an illegal opening move – say the King’s pawn, three squares forward. We’ll follow the same pattern as above:

And the same drill as before: Run the test, watch it fail, then adjust to assert on MoveResult.ILLEGAL; run the test and it should pass easily.
Note that I’ve re-instantiated ChessRulesEngine on line 41 – I wanted to revert the object to its default state so that I could properly test the opening move. However, why not use the object’s ResetBoard() or UndoLastMove() methods to do the same thing? Because we want to make sure that our tests can be run in isolation of each other and test only the operations we’re controlling. By calling in ResetBoard() or UndoLastMove() inside a test method, we’re assuming that they work properly – until we know otherwise, we need to do like Fox Mulder and trust no-one!
So, I need to refactor my test code. I want to reset the state of the ChessRulesEngine object before each test without having to new one up. We can do this via a method decorated with the SetUp attribute:

We can take out line 41 in the MakeMove_OpenE2E5_Illegal() test method, build and run the tests for sanity and revel in our Homer Simpson-style productivity gains. Don’t forget, we’re starting off easy here – this will pay dividends later on.
Defining What to Test
So far, it seems like we’re being somewhat arbitrary in our tests – while testing this input is good, and we do have a goal for writing a test to run through a sample game, we should have a few “rigor rules” to guide our efforts to make sure we’re writing valuable tests and not just ad hoc queries to satisfy curiosity. This is where I like to refer to advice from Andy Hunt and Dave Thomas, the original Pragmatic Programmers.
In their book, Pragmatic Unit Testing in C# with NUnit, 2nd Ed., Hunt and Thomas wrap up their experiences for writing top-notch unit tests with three acronyms:
- Good tests are A-TRIP: Automatic, Thorough, Repeatable, Independent and Professional
- Write tests using your RIGHT-BICEP
- Ensure that boundary conditions are CORRECT
I won’t rehash the acronyms here (you can check out the link above), however, suffice to say that we need to write tests that focus on one thing at a time, can be run independent of one another (ie, they don’t require prior tests to be run first) and exercise the code’s extremities, ie. anything that might break and anything that does break.
Let’s Try Breaking MakeMove()
To round out this post, let’s try writing a test to push in bad input to the MakeMove() method to see what happens. I have no idea what to expect, so I decide to try this:

Running the test, I got the following results:

A-ha! Now we have grounds for a new assertion – the engine does appear to validate input, throwing an ArgumentException if things are out of whack. We can test for expected exceptions by adding the ExpectedException attribute to our test definition:

I’ve dispensed with writing this test to fail-first with a different exception, since my initial run provided me with the expected exception. An important thing to note here is that I’m not writing the tests to pass, but using my knowledge of the system and code as I go to validate assumptions – which can change later on, depending on refactorings.
Next: More tests, web-accessible source
For the next installment, I’ll be getting into more meaty tests to validate inputs using Hunt & Thomas’ unit test guidelines and I’m also going to look into setting up web access for the source tree to provide the latest versions of the code via Subversion as we go along. As part of this effort, I’ll be writing some tests that I’ll share to validate the moves in a historical game. Until then, as always I welcome input on the posts so far and any constructive criticisms. Cheers!
In my last entry, I outlined my ambitions for revisiting the code for my .NET 1.1 WinForms chess board control - specifically the rules engine. This component is responsible for analyzing each move made on the chess board control against the known rules of the game for:
- Legality - Is the piece being moved from/to legitimate squares on the board according to the type? Is the move blocked?
- Material Captures - Does the move result in material capture? This includes special capture moves such as en passant, which incidentally has a known bug.
- Check - Does the move result in either placing the player's or the opponent's king under direct attack?
- Check-mate - Does the move result in placing the player's or the opponent's king under attack that cannot be evaded?
There are also some additional methods in the engine that should probably be extracted, since they do not directly relate to the class’ core responsibilities, ie. Standard Algebraic Notation and FEN notations for recording moves and bit-board initialization and manipulation routines.
By the way, don't worry if you're not a chess fanatic or chess programming whiz - I certainly wasn't when I tackled the project! You should still be able to grok what’s going on – let me know if I’m glossing over material.
Before we get much further, you might want to pull down a copy of the original source code so you can follow along. Download it here. Opening the solution in Visual Studio, here’s where you’ll find the rules engine artifacts:

One thing to note here is the green orbs beside each element in the view – these are Subversion source control status flags that are provisioned via the Visual SVN plug-in for Visual Studio. Since we’re going to be ripping into the code, it is an absolute must that we use some form of code versioning. Subversion is free (as in beer), and is professional-grade, with features that I feel rival TFS. It has a small footprint and can be set up easily on a local box, web server or network share. In sum, it’s a great all-round tool for managing your code – I’ll do a posting on getting started with Subversion for .NET development in the near future for the curious.
The class file that contains the rules code I’ll be refactoring is contained in ChessRulesEngine.cs, a rollicking roller coaster of code over 1400+ lines deep (excluding comments) with 121 methods, 164 fields and eight types! Almost all of it necessary – I think. Well, except for the 24 #regions – which we all now know are completely evil (right, Bil?).
First thing we do: Kill All The #regions
I know that I promised to get into my strategies for tackling the high cyclomatic complexity, but before we can get to any refactoring, we need a clean surface. Looking at this old code, I cringe because it’s a little messy, and I want to make it more in-line with my current habits.
So I began by first removing all the #region statements so that I could see the code I was dealing with without having to mess around with little “+” swizzles and to reveal all the code in its naked glory. However, I did want to retain some markers about what each block of methods represented, so I did some global S&R to change all “#regions” to “// GROUP:” and “#endregions” to “// — GROUP END —” I then added GROUP as a task list macro (Tools—>Options—>Environment—>Task List) so that I could easily view and navigate to each section within the IDE:

Now, I could easily move around to each code grouping using descriptive markers. At this point, I committed my changes to the repository to serve as my new baseline. As an aside, when using any modern CVS, it is generally a good practice to provide a brief message about the changes you’re committing – getting into this habit will make your life a lot easier should you ever have to revert to a specific revision later on:

Next: In-depth code analysis
In my earlier post I mentioned two motivations that would provide an initial guide to establishing my refactoring plan: Maintainability and Cyclomatic Complexity. Each is complimentary in a yin/yang sense – by tackling methods and types with high CC scores, I would be making strides toward improving maintainability, and vice-versa.
Refactor! Pro provided me with a whack of methods with high CC scores. In general, methods that have a CC of 15 or higher are strong candidates for refactoring. CC metrics of 20–30+ should be aggressively refactored to split them up.
Now, while the Refactor! Pro metrics provide a good indication of some hotspots, I wanted to mine out some more information about my code to get a better sense of its overall health and to begin constructing a baseline “map” to evaluate my changes against. I needed to bring in a heavier duty tool.
Enter: NDepend
NDepend is a static (ie. non-runtime) code/assembly analysis tool for measuring an application's design (recall: all code is by nature, design) against a series of metrics that gauge type/assembly interdependencies, complexity, stability, couplings, abstraction and cohesion - among many others. Basically, all the things that help define code that not only functions well, but maintains well.
While initially a bit intimidating, NDepend can be your best friend once you get around the idiosyncrasies, and is invaluable in putting together a comprehensive picture of how an app is structured. Initially released as a free tool, it is now quasi-commercial at a cost of $400 USD for a single license. That said, you can use it for free (with some feature crippling) for non-commercial apps – works for me!
Running the analyses
There are some excellent tutorials on the NDepend site for getting started and how to use the tool, so I won’t go into a deep-dive in this post. Basically, we want to use the VisualNDepend GUI to create a new project from our VS2005 solution (sorry, no 2003 support) and focus on analyzing just the RNVirtualChessboard and RNChessBoardCommonTypes assemblies – we can remove the RNChessBoard assembly as that contains the code for the control GUI:

At this point, we can now launch the analysis and view the results in the VisualNDepend GUI (click to enlarge):

In the above capture I’ve reset the views in the GUI to focus just on code metrics. The middle pane with the bubble-blocks is a high-level view of the methods in the assemblies that are organized in relative size to one another according to the current metric, which is set to show cyclomatic complexity. The scores for CC are in turn provisioned via the CQL queries in the pane just below.
Right. CQL – That’s pretty cool. Wait, what?
CQL is an acronym for Content Query Language – in a nutshell, it allows you to run SQL-like queries against the metrics that NDepend has gathered so you can quickly view pertinent results according to adhoc criteria. OOTB, VisualNDepend has over 60 of these queries that you can run and modify. This feature alone makes NDepend a tool worth having, IMHO.
Note that we’re seeing only two methods, IsCastleLegit and DoPlayerMove, from the CC query as opposed to the 20–odd that Refactor! Pro was showing. This is because by default, the CQL query NDepend uses shows the top-10 results for methods with a CC score of 20 or higher. By editing the query to show methods with CC scores of >= 15, we get ten methods returned:


As cool as this is, we can glean even more targets through NDepend’s additional code quality queries, but for now I’d like to pursue the top-three in this list starting with DoPlayerMove, as I suspect that from here I will touch a lot of other methods. By right-clicking on the method in the results pane, I can access a context menu for drilling down into dependencies:

From here, I want to know what methods are directly consumed by DoPlayerMove – this query reveals the following shortlist:

Of these, the first two, UpdateMoveBitBoards and GetPieceTypeBitBoard have CC scores of 14 and 15. Almost immediately we can start to see the broad brushstrokes for our refactoring plan and we’re more aware of the dependencies that we can run up against.
Strategies for Dealing with Cyclomatic Complexity
Because cyclomatic complexity is a measure of the branching and looping elements that exist within a method or type, it makes sense that the strategies we’ll want to employ for refactoring will be concerned with mitigating the effects. Briefly, this means that we want to look at:
- Branching requirements
- Loop unrolling
- Switch/Case optimizations
- Segmenting code into smaller functions
Additionally, we want to be on the lookout for any low-hanging fruit that will improve the readibility of the code, such as introducing constants for any “magic numbers”, renaming methods where appropriate, collapsing redundant code, etc.
Refactoring-Ho!
For the remainder of the posts, we’ll be going through our target methods to begin sorting them out through the application of various refactorings. As an aide, I’ll be using the Refactor! Pro add-in to make suggestions on the changes we can make to improve the design of the code. While we should endeavour to recognize refactoring opportunities in our code without tools, they can provide us productivity gains and be instructive at the same time. However, as with any power tool, we need to employ a little TFD (thought-first development) and try to do as Norm Abrams recommends and measure twice, cut once.
Note: If you haven’t already a copy, I highly recommend getting Martin Fowler’s book, Refactoring: Improving the Design of Existing Code. While it is an older text (1st edition in 2000) it is the seminal work that defines the reasons and strategies for revising code through the identification and cataloging of “code smells”. Additionally, you may want to review Joshua Kerievsky's catalog of Refactoring to Patterns as well as Fowler’s online Refactorings Catalog which has current revisions and additions.
If we look at the DoPlayerMove code, we can readily see a number of “low-fruit” opportunities such as this block, which checks for the movement of either white rook as a pre-condition for determining the legality of a special defensive move called castling:

Refactor! Pro has picked up from my selection that I have the opportunity to employ several refactorings, including Replace with Constant – note that it even observed I already have a defined constant for the value that I can use! Taking a step back, we can also see that there’s an opportunity to employ the Extract Method refactoring:

However, now we’re starting to get ahead of ourselves: We need to backstop our code with some unit tests so that we can be assured that the changes we’re planning on making don’t break the build or introduce new bugs. For this, we’ll be using NUnit unit-testing framework v2.4.3 for .NET 2.0 and then adding a new project to our solution for containing our tests, which I’ll be covering in my next post!
In the next installment: Setting up Unit Tests
Your homework for the next installment is to install and become familiar with NUnit and a complimentary add-in for Visual Studio, TestDriven.NET as I will be covering the fundamentals of each only briefly as they relate to managing and running our tests. As always, if you have any questions feel free to post them below.
|