Productivity suggestion: put your unit tests in the same project as your production code
I’ve been doing a bit of work with Django again over the weekend. One of the things I like about Django is that you put your unit tests in the same directory as your models and views in a file called tests.py. Because this sits just next to your production code, it makes writing unit tests a very natural and easy way of working.
This is in complete contrast to the way things are done in .NET, where most developers put their unit tests in a separate project, preferring instead to provide a separation of concerns and keep the size of their build output down.
The problem with that is it’s a complete faff. Because your unit tests end up in a totally different part of your solution to the code they are testing, you have to navigate all over the place through the solution explorer to get between two files that you should really be working with together all the time. It’s like trying to cook a meal when your fridge freezer is in the garage, the oven is in the attic, and the kitchen sink is in the basement.
I personally find this makes me write fewer unit tests than I otherwise would. That is bad.
The other problem is that it’s much more difficult to unit test your assembly’s internal classes. You can of course use the [InternalsVisibleTo] attribute to expose them to your test assembly though, but even so it’s a little bit awkward. Additionally, since you have an extra project in your solution, it takes longer to load into Visual Studio, and longer to build. On a large solution with a lot of projects, it can get very sluggish indeed.
The argument against putting test code in the same assembly as production code is of course that you don’t want to bloat your release build. However, it’s perfectly possible to get round this by wrapping your test classes in conditional (#if) compiler directives. It is even possible — in fact, it’s surprisingly easy — to knock out the references to test framework assemblies such as Gallio, MbUnit, Moq, and so on from release builds. You can’t do it directly from the Visual Studio IDE, but if you open up your .csproj file itself in a text editor you can add a Condition attribute to the references you want to omit. For example, this code would omit the MbUnit assembly from your Release configuration, while including it in your Debug configuration (and any other configurations you may have):
<Reference
Include="MbUnit, Version=3.1.0.0,
Culture=neutral, PublicKeyToken=eb9cfa67ee6ab36e,
processorArchitecture=MSIL"
Condition="'$(Configuration)' != 'Release'" />
What do you think, readers? Are there any other good reasons why you shouldn’t do this? Personally, I can’t think of any.
Comment on this » 
RSS feed
Posted at 08:00 on 14 June 2010.
If you’re wrestling with problems such as these, Roy Osherove’s book,

