Over the past few months, I’ve been doing test-driven development (TDD) using VstsUnit (aka MSTest), which ships with Visual Studio Team System. (A client’s choice to use VstsUnit, not mine.) I’m an avid ReSharper user and quite like their unit test runner, which allows you to run NUnit or csUnit tests directly from within Visual Studio. Unfortunately it doesn’t support VstsUnit. When Albert Weinert released MbUnit support for ReSharper a few months back, I realized that JetBrains had an undocumented plugin model for their unit test runner and I could integrate support for VstsUnit into ReSharper. Without further ado, I present to you the VstsUnit Plugin for ReSharper.

VstsUnit Plugin for ReSharper

Out of the box, JetBrains ReSharper Unit Test Runner supports NUnit and csUnit. This ReSharper plugin adds support for the Unit Testing Framework in Visual Studio Team System (VstsUnit), also known as MSTest.

N.B. The plugin will likely work with JetBrains UnitRun, but I have not taken the time to test it with UnitRun. Unfortunately you cannot have ReSharper and UnitRun installed at the same time, which means I need to set up a virtual machine with Visual Studio 2005 and JetBrains UnitRun. I have not taken the time to do this yet.

Installation

  1. Close Visual Studio 2005.
  2. Extract the contents of archive, including the VstsUnit folder, to:
    %ProgramFiles%\JetBrains\ReSharper\VS2005\Plugins
  3. Launch Visual Studio 2005.
  4. Open a project containing VstsUnit tests.
  5. Open a test file containing a TestClass with TestMethods. Standard ReSharper icons will appear in the left margin and allow you to run the unit tests.

Known Issues

ReSharper Unit Test Runner icons do not appear beside TestClass and TestMethod.
This is typically caused by having an assembly reference to another unit test framework. ReSharper Unit Test Runner (and UnitRun) only support a single unit test framework per test assembly. Remove references to NUnit.Framework, csUnit, and/or MbUnit.Framework from the References in your test project. This is a known limitation in the JetBrains’ current unit test runner implementation. A plugin votes on whether the current assembly contains tests that it can run. If the plugin votes “yes”, the unit test runner stops querying additional plugins. NUnit and csUnit get queried before third-party plugins.
Poor performance when running full test suite.
Unit tests are run by invoking mstest.exe and parsing the resulting XML file (.trx). The Unit Test Runner invokes the plugin once for every TestClass (aka TestFixture in NUnit terms). Unfortunately MSTest has high overhead as it copies all files to a new directory to execute tests. There is no way to turn off this behaviour in MSTest. It may be possible to run the full suite of tests and cache the results, but there are numerous problems with this approach including determining whether the cache is fresh and keeping TestClass or TestMethod runs responsive. Due to the architecture of MSTest, it is not possible (without what would likely be some truly awful System.Reflection work) to run the unit tests in-process as is done for NUnit and csUnit.
Cannot debug or profile VstsUnit tests.
I have not found a way to hook the debugger or profiler to the MSTest process. Hopefully this will be possible in a future version.

NUnit, MbUnit, or VSTSUnit (aka MSTest.exe) have similar syntax, which makes it easy to switch between one framework and another. Switching from NUnit to MbUnit is as simple as replacing:

using NUnit.Framework;

with:

using MbUnit.Framework;

Switching the other way is just as easy as long as you haven’t used any MbUnit-specific features such as RowTest.

Switching to/from VSTSUnit is not as easy because Microsoft decided to rename the test-related attributes. (The Assert class is largely the same fortunately. So switching is largely an attribute renaming exercise.) So here’s a snippet to place at the top of every test file that will allow you to switch between NUnit, MbUnit, and VSTSUnit via a simple #define in a code file, a compiler switch, or project properties. You then define your tests using VSTSUnit attributes. (i.e. TestClass, TestMethod, etc.)

#if NUNIT
using NUnit.Framework;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
using ClassInitialize = NUnit.Framework.TestFixtureSetUpAttribute;
using ClassCleanup = NUnit.Framework.TestFixtureTearDownAttribute;
#elif MBUNIT
using MbUnit.Framework;
using TestClass = MbUnit.Framework.TestFixtureAttribute;
using TestMethod = MbUnit.Framework.TestAttribute;
using TestInitialize = MbUnit.Framework.SetUpAttribute;
using TestCleanup = MbUnit.Framework.TearDownAttribute;
using ClassInitialize = MbUnit.Framework.TestFixtureSetUpAttribute;
using ClassCleanup = MbUnit.Framework.TestFixtureTearDownAttribute;
#else
using Microsoft.VisualStudio.TestTools.UnitTesting;
#endif

Now you’re probably thinking to yourself, “James must really love VSTSUnit because that’s the default.” Not exactly. I use a number of tools including ReSharper’s built-in Unit Test Runner and VSTSUnit’s Test View window. ReSharper works against the compiled code model. So the naming of the attributes is irrelevant. Instead of TestFixture, I could attribute my test-containing class with “MonkeysWritingShakespeare” as long as I had the proper using alias:

using MonkeysWritingShakespeare = NUnit.Framework.TestFixtureAttribute;

ReSharper’s Unit Test Runner figures it out because the whole using syntax is C# syntactic sugar so you don’t have to type fully qualified classes all the time. (The CLR only deals in fully qualified classes.)

How about VSTSUnit’s Test View? Not so good. It is apparently parsing the C# code file, not the code model, looking for tests. If you attribute a test with anything other than TestMethod (or its fully qualified equivalent), the test disappears from the Test View window even if you have the correct using alias to rename the attribute to TestMethodAttribute. Very lame. So that’s why I use VSTSUnit attributes and alias them to NUnit or MbUnit equivalents rather than the other way around.

Now should you use this unit test switching technique on every project? No, it’s not worth it. Pick a unit test framework and stick with it as long as it is not causing you pain. Because of differences between unit test frameworks, you need to run your test suite with all the test frameworks at least every few days. Otherwise you’ll accidentally use a feature specific to one framework and not realize it. (I’m assuming that you are running your test suite frequently throughout the day using your test framework of choice. My point here is that you need to run your test suite with all frameworks at least once in awhile to ensure that everything works.) There are occasions where you want to support multiple test frameworks and the snippet above will hopefully make life easier for you.

I know C# quite well and thought I knew all the language features, both old, new, and forthcoming. Today I was completely surprised when I discovered a feature that has existed since C# 1.0 that I never knew about… String literals in C# can span multiple source lines!

My voyage to discovery started when reading a post by Oren Eini about an unrelated subject. He casually mentioned his annoyance that Microsoft used string concatenation in its examples and why weren’t they using multi-line strings. Oren is a smart guy and generally knows what he’s talking about. So I started poking around. The following code results in a compiler error, as I expected:

string sql = "SELECT foo
              FROM bar
              WHERE baz=42";

So regular strings cannot span multiple lines, which is why you commonly see it written as:

string sql = "SELECT foo " + 
             "FROM bar " +
             "WHERE baz=42";

I can wax poetic all day about the advantages/disadvantages of hard-coded SQL in your code. The reality is that if you’re not using an object-relational mapper (such as NHibernate – and you really should be), you need to stick the SQL somewhere. Code is as good a place as any. The truly awful part is round-tripping the SQL between a query editor and C# for tuning or investigation purposes because you have to strip out all those double-quotes and plus signs. But C# has another type of string — the string literal (@””). As it turns out, string literals can span multiple lines. The following is completely valid C# and even provides decent readability of the SQL in your C# code:

string sql = @"SELECT foo
               FROM bar
               WHERE baz=42";

Maybe LINQ (in .NET 3.5) will do away with the need for SQL in quoted strings, but until that day, my SQL statements became a little bit more wieldy.

I had a great time presenting at the Victoria Code Camp this past Saturday. Over 100 developers attended the event at the scenic University of Victoria with lots of great talks by some awesome speakers, including a few from Alberta – Jean-Paul BoodhooDonald Belcham, and Justice Gray. They even let me of al people give two talks.  Nolan Zak and the rest of the organizing committee did a phenomenal job orchestrating the event and making sure everything ran smoothly. For those of you who attended my talks, you can find the slidedecks and demos here:

Tools of the Trade: Must-Have .NET Utilities (slides)*

ASP.NET Kung-Fu: Advanced Techniques and Idioms (slides & demos)

I would also like to thank JetBrains for sponsoring my talks by generously donating two copies of ReSharper as prizes. (I don’t work for JetBrains. I’m just a very happy customer!) Congratulations to the two winners, Joe and Robert. I hope you enjoy using ReSharper as much as I do. It’s a phenomenal product.

* The Tools of the Trade slides are in PowerPoint 2007 format (pptx). If you don’t have Office 2007, you can download the Microsoft Office Compatibility Pack, which allows you to open/save Word, Excel, and PowerPoint 2007 documents using Office 2003.

You know you’re living life on the bleeding edge when you search the web for an answer to your problem and your own blog appears as one of the most promising results!?! (Currently third from the top on this search.) Reporting Services on Windows Vista just doesn’t work out-of-the-box, even with SQL Server 2005 SP2 installed. (N.B. SP2 is beta/CTP right now.) So I decided to do a bit of digging. As is noted here, local administrators are no longer SQL Server admins by default. (Local administrators used to get this because they were a member of Administrators group and Administrators was added to the SQL Server sysadmin role by default. Because of UAC – which is an excellent security technology no matter what its detractors might say – local administrators do not have the Administrators SID in their security token. (In order to have the administrators token, you must elevate using “right-click, Run as administrator” and consent via the UAC prompt.) So how do you grant your user (administrator or not – and I still encourage not) access to the report server?

  1. Run IE as an administrator. (Right-click IE, Run as administrator.)
  2. Browse to your Report Manager directory, usually http://localhost/reports.
  3. Click on Site Settings (upper right).
  4. Under the Security heading, click “Configure site-wide security”.
  5. “New Role Assignment” and add your user to the System Administrators role.
  6. Click “Home”, “Properties”, and under security “New Role Assignment”, add your user to “Content Manager”.

Now the funny part… Try running a non-elevated IE and browse to http://localhost/Reports. This is the result:

Report Manager - IE Protected Mode

Now let’s try it with FireFox:

Report Manager - Firefox

That looks a lot better. Turns out that IE Protected Mode is getting in the way and preventing Report Manager from rendering properly. (IE7 runs in Protected Mode by default, which is a good thing.) We can disable protected mode just for this site by adding it to our trusted sites list in IE. (Tools… Internet Options… Security tab… Select “Trusted sites”… Click “Sites”… and add http://localhost to the list.) Also make sure that “Enable Protected Mode” is disabled for Trusted Sites. (It should be enabled for Internet/Local intranet/Restricted sites.)

Report Manager - IE Trusted Sites

Note on the bottom bar “Trusted sites | Protected Mode: Off”. That looks a lot better under IE7!  I haven’t investigated why Report Manager doesn’t like Protected Mode, but it should get many of you up and running with Reporting Services on Vista.

Congratulations to Jean-Paul Boodhoo on his well-deserved Microsoft MVP award! Couldn’t have happened to a nicer guy and more awesome dev. Welcome to the club, Jean-Paul.

Well, Bil Simser has tagged me, which means that I’m it. The basic gist of this blog game/chain letter is that I have to tell you five things that you probably wouldn’t know about me. As a reward, I get to pick five other hapless blogging souls who must then do the same.

  1. I am a long-time vegan and avid chef. I taught cooking classes for a number of years while living in Boston. I even got featured on the front page of the Somerville Journal, North America’s oldest newspaper.
  2. I’ve been playing the saxophone for about 20 years and have been in various jazz bands, big and small. I can carry a tune, but I’m not giving up my day job. (I take full responsibility for the “musical interludes” that grace Plumbers @ Work.)
  3. I have a Masters degree in Physical Chemistry from Harvard University. Although my business cards say “M.Sc.”, it’s actually an “A.M.” or Artus Masterus, which is Latin for Master of Arts. It’s easier to write “M.Sc.” than explain to everyone that Harvard gives out an “A.M.”, which is equivalent to every other university’s M.Sc.
  4. I love games. I collect European-style board games. Examples include Puerto Rico, Power Grid, The Princes of Florence, and The Traders of Genoa. (i.e. Not Monopoly.) BoardGameGeek is an awesome site. I spent much of my teenage years playing AD&D, Car Wars, BattleTech, Paranoia, and similar games. I was a popular dungeon master in my high school and was president of the RPG club. (In high school, dates were a fruit that grew on trees.)
  5. Unlike Bil, I have broken a bone in my body. Many years ago, I broke a toe on my left foot in a freak cooking accident when I ducked into my pantry for a potato.

My duty is done. I pass on the gauntlet to…

My MSDN Magazine article entitled Debug Leaky Apps: Identify and Prevent Memory Leaks in Managed Code has been published in the January 2007 issue. Go check it out!

Due to space constraints, the editors at MSDN Magazine left a few acknowledgements on the cutting room floor. I would like to acknowledge Rico Mariani (MS) for coining the term “midlife crisis” as it applies to the garbage collector. His blog is full of excellent perf advice and insight. I would also like to acknowledge Tess Ferrandez (MS) as one of the examples in the article is based on her blog post, “Does Page.Cache leak memory?“.

Finally, a very special thanks to my spouse, Risa Kawchuk, for her patience and excellent editing of the many versions of the manuscript.

There are many paths to software enlightenment, to attaining the state of development nirvana knows as ZenBoo. Masters of the art of ZenBoo can invert dependencies at will, value coding to interface* not implementation, favour composition over inheritance,** and respect the open-closed principle.***

On your journey to becoming a ZenBoodist, you will encounter many revelations and wonders. While meditating on test-driven development (TDD), you will gain deeper understanding of the technique. First you will realize the power of an automated test harness and a suite of regression tests that prevent bugs from finding their way into your code base. Next you will realize that your suite of unit tests allows you to confidently refactor your code base. Finally you will discover the power of mocking and realize that TDD is not a testing technique, but an agile design technique. Other wonders abound including better layered architectures, O/R mapping, IoC containers, and more.

How can I achieve a state of ZenBoo, you might ask? Everyone’s path is different, but I offer you a few humble suggestions. You must first understand object-oriented design. Just understanding object-oriented programming isn’t enough. You have to know how to design object-oriented hierarchies through responsibility assignment. Which object/class is responsible for X? By assigning responsibility for X to this object/class, how does that affect my coupling, cohesion, and a myriad of other factors? A good treatise on the subject is Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd Edition) by Craig Larman.

By understanding responsibility assignment, software patterns suddenly make sense. You have a framework upon which to understand patterns and upon which to build new ones. Everyone should read Head First Design Patterns (Head First) by Eric Freeman and Elizabeth Freeman. This book offers deep insight into the ZenBoodist mind in a playful, approachable way. Although it is written for Java developers, it is equally applicable to and comprehensible by C# developers. It covers the classic “Gang of Four” software patterns, but frames them in within actual problems so that you can see how to apply them. You understand the power of coding to interface not implementation, why we favour composition over inheritance, and how to apply the open-closed principle. If you’re going to read one software book in the next year, this should be it.

Now that you understand the “Gang of Four” patterns and the basic ZenBoodist philosophies, it is time to understand how to design real-world architectures and build real-world applications. For this, we turn to Applying Domain-Driven Design and Patterns: With Examples in C# and .NET by Jimmy Nilsson. He blends together elements of Eric Evans’ Domain-Driven Design and Martin Fowler’s Patterns of Enterprise Application Architecture to take you on a journey of discovery through TDD, mocking, O/R mappers, domain-driven design, and more.

Becoming a ZenBoodist master is a difficult journey, but one well worth it. Once you achieve development nirvana, you will code with elegance, refactor with confidence, and dream in patterns. You will also realize that you are but a humble grasshopper wanting to learn more.

<plug type=”shameless” subject=”http://www.jpboodhoo.com”>

If you want to get a jumpstart on ZenBoodism, check out Jean-Paul Boodhoo‘s Nothin’ but .NET course. You get 5 days of top-notch training from a ZenBoodist master, a ReSharper 2.0 license, Martin Fowler’s Patterns of Enterprise Application Architecture, and free food. The next course is in Edmonton on February 19-23, 2007. Highly recommended.

</plug>

<shelf type=”reference”>

The following reference books are useful to have on your shelf, but you probably don’t want to read them cover-to-cover unless you’re crazy. (Yes, I’ve read all of these cover-to-cover and thoroughly enjoyed them.)

</shelf>

<footnotes>

* Interface in this context can mean abstract base class or interface. The point is not to depend on a specific type, but on a contract definition.

** Favouring composition over inheritance does not mean abandoning inheritance. True ZenBoodists combine the powers of inheritance with composition to make truly powerful object models. While inheritance is over-used, don’t under-use it either.

*** Open-closed principle: Classes should be open for extension, but closed for modification.

</footnotes>

Full Disclosure: The book links above are through the Amazon Affiliates program. If you buy a book through that link, I get more books from Amazon to sate my hunger for knowledge.

This post by S. Somasegar, VP of Microsoft’s Developer Division, stirred up quite a racket back in September about incompatibilities in VS2005 on Windows Vista. Now that I’ve had a chance to use VS2005 on Vista seriously for a few weeks, I can say that it’s much ado about nothing. VS2005 is a complex application. Does it run on Vista? Yes. Does it run as a limited user or a filtered administrator*? Yes. Are there problems? Yes. Are they show-stoppers? Not for the most part. Full details, including broken features, can be found here on MSDN. If you’re depending on one of these features, life sucks. For most developers, it will mean the occasional visual glitch. I’ve had this happen once and a simple refresh of the Visual Studio window resolved it.

In a way, I can understand where the DevDiv is coming from. VS2005 is in the support channel now and they’re actively working on “Orcas” or Visual Studio vNext. Orcas is the development tool designed to target Vista and .NET 3.0. You’ll notice that all the .NET 3.0 designers are CTPs. They’re works in progress and destined for Orcas as their final home. (I don’t know if VS2005-compatible versions will also be available.) The unfortunate part is that the most likely early adopters of Vista are developers and the DevDiv doesn’t have a fully-supported tool for the platform. Now that sucks. Microsoft has built mind-share by creating a fantastic platform for developers. Developers are a bit out in the cold when it comes to Vista and .NET 3.0. Imagine releasing .NET 2.0 without VS2005? On the one hand, Microsoft should have coordinated th release of Orcas with Vista. On the other hand, by the time most developers will be looking at Vista, Orcas will be released. It’s only us early adopters that need to brave the excitement of running an unsupported developer tool on the latest version of Microsoft’s flagship OS. Honestly, it’s not all that exciting. For the most part, VS2005 works as it always has with a few rough edges due to UAC.

* A filtered administrator is an administrator whose admin token has had most of its privileges stripped out and the Administrators’ group SID changed to a deny. The real admin token is kept in waiting, heavily protected, and is activated when the user clicks “Continue” on a UAC prompt. A good review of the details can be found here on Márton Anka’s weblog. He also has some good information on how to declaratively and programmatically request an elevation of privilege. (i.e. Throw up the UAC prompt.)