To Blog or not to Blog? This is my answer! RSS 2.0
 Friday, January 16, 2009

I use Visual Studio 2008 in combination with MSTest to do Test Driven Development. One of the most important and frequent tasks when practicing TDD is running your tests. Much has been said about NUnit’s better fit with TDD (in great part due to their standalone test runner that simply re-runs all your tests when the assembly is rebuilt), but it doesn’t have to be as bad as it may be out of the box with only a few tricks and tweaks to Visual Studio.

Firstly, it’s extremely important to know your keyboard shortcuts. It always amazes me when I see developers write a whole bunch of code using both hands on the keyboard and then reach for the mouse to click the green Play button to run it. Ctrl-F5 runs your code, F5 debugs it; it’s that simple. With TDD, however, there is another step between writing and running your code. It is running your tests. Visual Studio’s approach to test management is very QA oriented, but it does have the simpler commands for running tests within the current context as well as ALL tests and they have keyboard shortcuts defined by default. Here they are and they all perform a build first if necessary as well:

Shortcut Command
Ctrl-R A Run all Tests
Ctrl-R T Run Tests in Current Context
Ctrl-R Ctrl-A Debug all Tests
Ctrl-R Ctrl-T Debug Tests in Current Context

Note that these in fact are keystroke macros and mean that you first press Ctrl-R and then press A by itself.

Sometimes, a complete rebuild is required to flush old binary artifacts and this by default requires going into the menus. Ctrl-Shift-B shortcut builds the solution so I find it useful to map Ctrl-Alt-Shift-B to the Rebuild Solution command. You can do this easily from the Tools->Options Menu:

Bind Rebuild Solution Command in Options Dialog
Click to enlarge

Finally, the test-runner window could become cluttered with test results once the number of tests increases significantly. This makes finding the failed test somewhat painful. If you look at the 4 possible Result values for the tests—Pending, In Progress, Failed, and Passed—you may notice that all but Passed have an ‘i’ in them and we only care about tests that don’t pass. So if you filter the Test Result window to only show tests with an ‘i’ in the Result you get a list of all tests in Progress or Pending but which filters out the successful tests and leaves only the Failed ones behind after the test run is done.

image
Click to enlarge

Unfortunately, the filter setting doesn’t stick between VS restarts and you have to repeat the process but it’s quick and simple.

With these settings I find writing and running tests a breeze in Visual Studio.  These suggestions will work in Visual Studio 2005 as well although VS 2005 test runner’s performance issues are a mroe difficult issue to overcome.

Friday, January 16, 2009 2:01:23 PM (Pacific Standard Time, UTC-08:00)  #    Comments [0] -
Development | TDD | Technical
 Wednesday, November 07, 2007

I am playing around with the XNA Framework and in the process of writing a game, I need to perform in essence a graph traversal. Given a 3D board (of w x h x d cells), I need to from a starting position and "up" direction to go around the board and figure out all reachable locations. So If you have a cube in space and you start on one of the faces, I need to get all cells on the surface of the cube. It gets a bit more complicated once you throw in rules like "you can't traverse through walls" and "if you reach an edge, you in essence go over it and rotate" (sort of like going around the globe, but around a cube... if that makes sense).

Anyway... I am trying to do as much Test Driven Development as possible and this problem got me thinking. It's nothing new to write some code that will iterate through a graph, keeping track of visited cells and figuring out others, but I was trying to figure out how to do this in a testable manner without exposing all kinds of internals about the traversal class. After all, if it's private, it's an implementation detail. But I needed to say "do one pass and show me the node list" type of thing. So I decided to use .Net 2.0 iterator method instead. It allows you to create a function that returns an IEnumerable<T> and the iterate over the results within a foreach loop. Within the method you can use yield return statements to return values as they are generated and the method execution will continue with IEnumerable<T>.MoveNext() method is called. When there are no more results to return, a yield break statement is used to end the iteration process.

Here's what a method that returns nothing looks like.

        internal IEnumerable<StarLocationInfo> GetStarLocations()
        {
            yield break;
        }

As I progressed through writing various tests, I could simulate conditions such as "when on a plane, return the current position and four children next to it". In the spirit of TDD it could look something like this:

        internal IEnumerable<StarLocationInfo> GetStarLocations()
        {
            yield return new StarLocationInfo(startPosition);
            yield return new StarLocationInfo(startPosition + new Vector3(1, 0, 0));
            yield return new StarLocationInfo(startPosition + new Vector3(0, 1, 0));
            yield return new StarLocationInfo(startPosition + new Vector3(-1, 0, 0));
            yield return new StarLocationInfo(startPosition + new Vector3(0, -1, 0));
            yield break;
        }

So all of this allowed me to write tests like this:

        [Test]
        public void OnPlaneFourChildrenAreReturned()
        {
            GameBoard testBoard = CreatePlane();
            GameBoardStarTraverser traverser = new GameBoardStarTraverser(testBoard, new Vector3(2, 2, 0), new Vector3(0, 0, -1));

            List<StarLocationInfo> expectedList = new List<StarLocationInfo>(5);
            expectedList.Add(new StarLocationInfo(2, 2, 0));
            expectedList.Add(new StarLocationInfo(1, 2, 0));
            expectedList.Add(new StarLocationInfo(3, 2, 0));
            expectedList.Add(new StarLocationInfo(2, 1, 0));
            expectedList.Add(new StarLocationInfo(2, 3, 0));

            RunTraversalAndVerifyExpectations(traverser, expectedList);
        }

where the last function basically runs through the results of traverser.GetStartLocations() with a foreach loop and removes items from the expected list as it gets them from the enumerator. It also makes sure that all of the expected values were recorded.

In the end I ended up with a traversal algorithm that much resembles a typical graph traversal (its breadth first) and all of its details hidden away in a iterative method, yet I can test its behavior by setting the start conditions and essentially inspect its results as they come out. To sum up:

  • I was able to use TDD methods to drive the behavior of the algorithm
  • I kept the details of the implementation hidden, since all it takes to invoke the "traverser" is a single function call.
  • I used a neat feature of .Net 2.0.

Note: this can be done with .Net 1.1 of course, but it's not as neat as one would need to implement both an IEnumerable and IEnumerator interfaces in a couple of classes.

Wednesday, November 07, 2007 9:40:31 PM (Pacific Standard Time, UTC-08:00)  #    Comments [0] -
Development | TDD
Categories
Archive
<February 2012>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2012
Alexey Kouzmitch
Sign In
Statistics
Total Posts: 10
This Year: 0
This Month: 0
This Week: 0
Comments: 0
Themes
Pick a theme:
All Content © 2012, Alexey Kouzmitch
DasBlog theme 'Business' created by Christoph De Baene (delarou)