Reducing Unit Testing Friction…

June 26, 2008

Gears.jpgIt doesn’t matter if you’re a TDD purist or a test-as-you-go guy, having a quick way to execute the tests that you’ve created is critical to them actually getting run as regularly as they need to be. To that end, here is the current setup that I’m using to make this as easy as possible.

Everyone knows that I’m a sucker for a new tool but this tool has been with me for quite a while and I’m skeptical that anything will be able to replace it. TestDriven.Net is the foundation of a great workflow when it comes to unit testing and it’s truly worth the small amount that Jaime asks for his efforts. He’s a great guy and it’s a great tool – go buy it and install it immediately.
So now that you have it installed, there a couple of settings in Visual Studio that help make that test/code/test cycle even tighter.

Keyboard shortcuts

Once you have TestDriven installed, you’ll notice some extra options in the context menus when you right-click on class files, projects and even in code. These will allow you to run tests in various fashions but I’m a lazy man and I hate moving my fingers off the keyboard so I’ve added a few shortcuts to Visual Studio. In the options menu for “Keyboard”, I bind Control-1 to “TestDriven.NET.RunTests”, Control-2 to “TestDriven.NET.ReRunWithDefault”, and Control-3 to “TestDriven.NET.ReRunWithDebugger”. The way this helps me is that I am able to use Control-1 to execute the test that the cursor currently resides in (if you’re in between tests or on the fixture itself, it will run all in that fixture). If it doesn’t pass, I can hop over to the code that’s being tested, make the changes and then just press Control-2 to see if the test passes. No back and forth between the two. The last shortcut is helpful because it allows me to set a breakpoint where I am (using F9 of course) and rerun the test so that it will hit that breakpoint. Again, no back and forth.

Output window

Every time you execute a test, the tool bar will give you a quick look at the status but the output window will be your friend when things don’t quite execute as planned. All the output gets piped here but you don’t need it in your face so be sure that the “Show Output window when build starts” is unchecked but also be sure that you have it collapsed just below your code file. output window.jpg This way if you do have need to see what is in the output, you can just press Control-Alt-O and it will pop up with focus. (Pressing Escape will cause it to hide again and leave us in our code.)

I still haven’t quite figured out how to bind to the “Run All Tests” so if you have a suggestion, I’d love to hear it. However, I do still find it helpful that a “Run All Tests” will execute again when using the rerun shortcuts and I use that quite a bit right before commits. (If you’re not religious about running ALL tests before a commit, I hereby grant your co-workers permission to knee-cap you.)

Because unit tests only provide benefit when they are actually run, we need to do everything that we can to tighten the code/test loop and make executing the right thing at the rightht time as easy as possible.


David O’Hara is a Principal Consultant with Improving Enterprises in Dallas, Texas.


Using Embedded Resources for Unit Testing…

July 10, 2007

I’ve often had to use XML documents in my unit testing. In the past, I’ve always done a concatenation to string together a document.

Xml document concat

However, I came across a post on Haacked that lead me to a better solution, embedded resources. Basically, you add a document to your project and mark it as an “Embedded Resource” rather than “Content” in the “Build Action” attribute.

Mark resource as embedded instead of content

This will pack it into the unit testing dll and allow you to extract it from the assembly. No more missing documents causing failing tests! In my custom class, I’ve defined a method for unwrapping the resource that allows you to pass in arguments that it will use for customizing the xml nodes. I found this to be simpler than attempting to navigate the document and update the nodes although I’m guessing it may be less performant.

Unwrap Method

One thing to be sure of with this, is that you use a centralized location for the resources so that your lookup doesn’t fail. So now I’m able to write my tests such that their intent is clear and the code is clean.

Resourced Test

Although I haven’t had the need yet, I could see where this could easily grow into handling multiple types of documents but I’ll hold off on that code until I need it. :)


“Zany” About MbUnit…

January 28, 2007

It looks like Sean has been working hard on my FAVORITE unit testing GUI – Zanebug. He’s updated it to the latest version of NUnit (2.2.9) and added support for MbUnit tests (here’s a post with screenies). Now it really is “all that and a bag of chips”…. (did I really just say that?) Regardless, if you’re not using it as your test runner – you’re missing out big time. Guess I don’t have a reason to put off trying out MbUnit anymore.


TDD Experiences and Thoughts…

December 5, 2005

While still only a relative novice to TDD, I’ve found it to be amazingly helpful in building better classes and thus writing better code. With no one to guide me, I stumbled thru several articles and numerous examples before I finally started to “get it?. There has been quite a bit of trial and error that has caused me to alter the way that I code and I wanted to write about a couple of things that I’ve started doing that have been a tremendous help.

Throw out the debugger. Ok, not really, but that’s sort of how I’ve started to feel now. Actually, this has been the biggest shift in my paradigm and thus my actions (aside from the general need to refactor my classes as a whole). I used to write a small console or windows app that would instantiate the class(es), do some sort of setup, and then respond to my input so that I could see how my code was evolving/reacting. Well, this is EXACTLY what unit testing does. It’s simple, I know, but it still took me some time to get used to and to wrap my mind around the fact that I didn’t have to press F5 to see how things were coming, I just ran my tests. As I wrote more tests, I wrote more code to use those tests and vice versa. It was a wonderfully vicious cycle that led to some pretty enormous tests with a ton of pre-condition and post-condition checking.

Refactor your tests and fixtures as much and often as needed. While I had some extensive unit testing being done, it certain didn’t follow DRY and was sort of a mess to maintain. Enter SetUp/TearDown… While there are still some who debate their use, others seem to agree with me that using them will not only make your life easier but makes your code cleaner. Whenever I have a test that needs some setup done, I usually refactor that setup into its own private method first. Once several of the methods use that single private method, I move them all to a separate fixture and make the private method a “SetUp? method. As a side note, good naming convention is VITAL for good tests. I avoid using the suffix “Test? for them and try to make them as descriptive of what they’re testing as possible. This reduces the number of messages that I have to output with my Asserts – oh, and always try to adhere to OAPT for better testing.

Finally, for those of us who use log4net (if you’re not using it, start NOW) I’ve put together a quick little way to leverage it in unit tests (see example below). By setting up and adding a ConsoleAppender in my TestFixtureSetUp, I get all of my messaging within my testing GUI. I’m even able to control the levels and formatting on a per fixture basis. Notice the use of preprocessor directives to keep the logging out of my automated build scripts as well.

[TestFixtureSetUp]
public void FixtureSetUp()
{
#if !AUTOMATED && DEBUG
AttachConsoleAppender();
#endif
}

private void AttachConsoleAppender()
{
LevelRangeFilter rangeFilter = new LevelRangeFilter();
rangeFilter.LevelMin = Level.Debug;
rangeFilter.LevelMax = Level.Info;
ConsoleAppender appender = new ConsoleAppender();
PatternLayout layout = new PatternLayout( “%date %-5level %logger – %message%newline” );
appender.Layout = layout;
appender.AddFilter( rangeFilter );
BasicConfigurator.Configure( appender );
}

Which finally brings us to the testing GUI itself – learn it, live it, love it. While the NUnit GUI is passable, I’ve found Zanebug to be everything it is not. Plus it’s FREE – can’t beat that…


Mocking Me…

November 2, 2005

I’ve been pretty “hot and heavy” with unit testing as of late. I can’t say enough about the benefits and, once you get over the learning curve, the ease with which they can be produced. Actually, I’m afraid that I sometimes border on the side of “overtesting” even but I’m guessing that aspect is something that develops with a little practice and time.

While unit testing is a great thing, sometimes things can’t really be unit tested well. Reliance on “outside” elements (such as external API calls) can make testing difficult at best and even impossible in some cases. But fear not, mock objects are an answer. I personally use DotNetMock but there are any number of solutions out there. At first, they were a bit confusing but after trying a few samples, I was able to understand their general use.

Ok, so all this long winded explanation was to present my current quandry. I’m writing a Visual Studio Add-In and would like to test it’s functionality. I have created my class which acts on a Solution object while iterating it’s Projects for various ProjectItems to utilize. So without insane amounts of setup and tear down code, how do I testing this beast?? For that matter, how would I test it even with all the code??

Shameless plug: If you’re looking for the best Unit Testing GUI out there – Zanebug is it.


Follow

Get every new post delivered to your Inbox.