Browsing Posts published in February, 2007

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.