Sequential .NET Unit Tests

So we’re on: .NET 3.5, NHibernate 2.0, MSTest, Linq, SQL Server 2005.

I wasn’t able to find a decent bootstrap-able database for integration testing of our data access layer, so we chose the next best thing—SQL Server must run on localhost when the tests run. The rest is easy. Each test case asks for a fresh database from a global service, which always drops and recreates the OurSoftwareProduct_Test database. We’re using .NET’s unit testing framework, hence tests run in parallel, and this results in tests creating a database already in use by other tests. This in turn means random test failures.

I tried to find a way to force tests to run sequentially, but it’s not on the web. You can configure tests with a data source via a DataSource attribute, which takes Sequential as a parameter. Whether this would work or not, I don’t want to create this artificial dependency to a data source that I don’t even use. Besides, I may need to actually access the data source to cause he serialization. And must the data source already exist at the beginning of the test? Too many moving parts.

So I came up with two alternate solutions to this problem.

The first solution—create a unique database for each test case. It’s not as bad as it sounds, since each unit test already creates the database from scratch, the only problem being that the name of that database is fixed.

using System.Diagnostics;
static class Database {
static void Create() {
// The next three lines retrieve the name
// of the calling method. Alternately, iterate
// all the frames backwards until you find
// a method that has a [TestMethod] attribute.
var trace = new StackTrace(true);
var frame = trace.GetFrame(1);
var testName = frame.GetMethod().Name;
var databaseName = string.Format(
"OurSoftwareProduct_Test_{0}", testName);

ForceCreate(databaseName);
RunUpdates();
}
}

The second solution—since all test cases recreate the database through a single point of access, I can serialize the execution at this global point of access:

[TestClass] public class ATest {
[TestMethod] public void Test1() {
Database.Create();
// More code.
}
[TestMethod] public void Test2() {
Database.Create();
// More code.
}
}
static class Database {
private static readonly Object lockObject
= new Object();

static void Create() {
lock (lockObject) {
ForceCreate();
RunUpdates();
// More code.
}
}
}

I prefer the first solution, because I get all the data produced/consumed by all of the tests. Solution number two overwrites the database each time, and leaves you with one database at the end of the run.

Trackbacks & Pingbacks 1

  1. From c readonly serialization on 03 May 2008 at 12:08 pm

    [...] Server 2005. I wasn??t able to find a decent bootstrap-able database for integration testing of ouhttp://www.viridium.ro/2008/sequential-net-unit-tests/MBR IT/.NET 247 : CodeDom Serialization on microsoft.public.dotnet …make sure it&39s not readonly [...]

Post a Comment

You must be logged in to post a comment.