Archive for unit testing

Practical .NET Unit Testing – Free paper released

I’ve been working on a unit testing paper that sums up my experience in unit testing, and discusses some of the core information that I feel is important about the subject. It’s very much a work in progress, but I wanted to get it out sooner rather than later. I’ll be continuously updating it as time goes on.

Update: I updated the PDF location to one that doesn’t require registration.

Practical .NET Unit Testing

There are some really great books out there about unit testing, but I think some of them are trying too hard to be long enough to be considered a “book”. I set out to create a document that fills the gap between the various snippets of information from blog posts, and the comprehensive books on the subject. If you’re interested in something a bit more in-depth, here are some great books on the subject:

The paper currently consists of 5 main sections:

  • Why Write Unit Tests?
  • Unit Test Mechanics
  • Common Unit Testing Strategies
  • Designing for Testability
  • Advanced Techniques

Here is a more complete snapshot of the current outline:

  • Introduction
  • Unit Testing & Managers
  • What Unit Tests Really Do
  • Types of Testing
  • Testing Framework
  • Test Runner
  • Unit Test Structure
  • Other Test Attributes
  • What is Refactoring?
  • Test Driven Development
  • Evolving Code
  • When Should You Write Unit Tests?
  • Test is for Functionality, Not Code!
  • The Constraints of Reality
  • Interfaces – Quick Overview
  • Using a Mocking Framework
  • Stubs
  • The Test Driven Design Paradox
  • Testing Under Pressure
  • Extracting Duplicate Logic
  • Modular Design Benefits

So what are you waiting for? Go check it out online instantly, you can even download it as a PDF if you like. Is anything missing? Is anything just plain wrong? I’d love to hear your feedback.

Remember, if you want to hear more about unit testing, I’ll be speaking in Northeast Wisconsin Saturday, May 9th.

Speaking at Day of .NET at Fox Valley Tech

If you’re interested in hearing about writing practical unit tests in .NET, I’ll be speaking at the Fox Valley .NET user group “Day of .NET” event May 9th! Here is the synopsis for your reading pleasure:

Want to learn how to write good automated unit tests that are beneficial both to the product/customer and to you as a developer? See an overview of the mechanics of unit testing including the tools and frameworks available. You’ll see examples of how to test existing code, but you’ll also see practical examples of how seemingly un-testable code can be designed so that it can be tested with ease. Learn how test driven development and refactoring will improve the readability of your code, minimize debugging, and speed up development.

image

If you’re anywhere near the Northeast Wisconsin area, stop in. It’s free!

I’ll be publishing both the presentation and a supporting 25+ page paper shortly, so make sure you’re subscribed to my feed.

Fox Valley Tech is located at:
1825 N. Bluemound
Appleton, WI 54912

Unit Testing a LINQ to SQL or EF Query

I was writing a slightly non-trivial method to query a database to find a record matching a certain time range. It quickly became clear that it would be nice to write some automated unit tests against it. Integration tests would be less than ideal because of the execution time and complexity. I ended up with a way to test the code without jumping through too many hoops.

IEnumerable vs IQueryable

First, you need to understand the purpose of IEnumerable and IQueryable. IEnumerable defines a stream of objects that can be retrieved sequentially. It’s implemented for nearly every type of list, and it’s an integral part of LINQ. There are now methods included such as “Where” and “Select” that let us filter, sort, and manipulate lists of data in interesting yet simple ways. This can also be referred to as LINQ to objects.

IQueryable inherits from IEnumerable, and is designed to be translatable into a query. IQueryable is typically used to build an expression tree that represents the requested operations. The operations are not actually executed until the expression tree is evaluated and used.

As an example, let’s say I have a database with a table and entities called DateRange. Suppose I cast the DateRange entityset (which implements IQueryable<DateRange>) as IEnumerable<DateRange>. When I call LINQ expressions on that IEnumerable, the underlying query is run immediately, which effectively causes all of the data from that table to be retrieved. If I use IQueryable without casting, my operations get turned into SQL that gets executed when I actually try to iterate through the data (probably using ToList() or foreach). It’s obviously preferable to have the query run in SQL since it can more efficiently filter the data.

The Problem

As I mentioned earlier, I recently starting writing a data access method that started to contain some non-trivial logic. Whenever I see logic, I want to be able to unit test it! I ended up pulling out the logic into its own static method. This method takes in IEnumerable<DateRange>, which can also accept IQueryable<DateRange> (because of the inheritance, you’ll recall). Then, I simply use the AsQueryable method in IEnumerable. This ends up building the needed expression tree that can be translated into a SQL query, but it also lets me test against an in memory collection.

public static DateRange FindRelativeToDate(IEnumerable<DateRange> enumerable, DateTime reference, int periodOffset)
{
	//Build as an expression tree, if possible, otherwise enumerate
	var queryable = enumerable.AsQueryable();

	//Now put in all the logic

	var reference2 = reference.AddDays(-1);

	var initialRange = from bp in queryable
		 where reference >= bp.Start && reference2 < bp.End
		 select bp;

	var currentDateRange = initialRange.First();

	if(periodOffset == 0)
		return currentDateRange;

	var newRange = from bp in queryable
		select bp;

	if (periodOffset > 0)
	{
		newRange = newRange.Where(x => x.Start >= currentDateRange.Start);
		newRange = newRange.OrderBy(x => x.Start);
	}
	else
	{
		newRange = newRange.Where(x => x.End <= currentDateRange.End);
		newRange = newRange.OrderByDescending(x => x.Start);
	}

	return newRange.Skip(Math.Abs(periodOffset)).Take(1).FirstOrDefault();
}

In my unit test class, I can define a list of sample data. I took real data from the database to make the tests as close to reality as possible:

private static readonly List<DateRange> _DateRanges = new List<DateRange>
{
	new DateRange {Start = new DateTime(2009, 1, 1), End = new DateTime(2009, 1, 30)},
					new DateRange {Start = new DateTime(2009, 1, 31), End = new DateTime(2009, 3, 01)},
					new DateRange {Start = new DateTime(2009, 3, 2), End = new DateTime(2009, 3, 31)},
					new DateRange {Start = new DateTime(2009, 4, 1), End = new DateTime(2009, 4, 30)},
};

Now, I can easily test the static class I wrote (this is 1 of 9+ real tests):

[TestMethod]
public void FindRelativeToDate_MiddleOfDateRange_ContainingDateRange()
{
	var result = DateRangeRepository.FindRelativeToDate(_DateRanges, new DateTime(2009, 3, 15), 0);
	Assert.AreEqual(_DateRanges[2], result);
}

The only thing that is left to do is wire up the repository method so that it calls my static method. This is a thin wrapper layer that will actually get used in production. If you run profiler, you’ll see that the query expression is being evaluated and converted into an efficient SQL expression.

public DateRange FindRelativeToDate(DateTime reference, int periodOffset)
{
	var ctx = dbEntities;
	return FindRelativeToDate(ctx.DateRangeSet, reference, periodOffset);
}

Limitations/Conclusion

Unfortunately, this method of testing a repository doesn’t scale easily. If you start working with multiple entity sets that are combined with join operations, this technique is next to impossible to use. You’ll see the most benefit when working with a single entity type, and need to test logic in your repository method.

One thing you need to be aware of, is that LINQ to SQL and Entity Framework don’t implement every IQueryable/IEnumerable method. This means that you could potentially make calls on the in-memory collection that will then fail when you use the actual database. Fortunately, these problems can usually be detected fairly quickly.

Screencast – Unit testing with real DataSets

As I’ve mentioned before, I wrote a small utility for running a SQL query, and returning the results as an XML serilialized DataSet.

I created a quick screencast to demonstrate how you go about using this utility. I’m new to screencasts, so don’t expect a high production value!

image

You can check out the screencast here!

Let me know what you think in the comments!

Design your classes for their consumer

I’m going to describe a methodology that will help you save time by writing better classes, and will help simplify your life by allowing you to solve problems with a top-down approach.

Developers such as myself often have a tendency to just focus on the class we’re currently working on. Of course I believe this is a good thing, because we all know the importance of focus. However, you should never forget the reason you’re actually writing that class. It is because other code will be consuming it.

Consumer-Approach

There have been far too many instances where I would figure out which pieces I needed to build, and then build each one, from the bottom up. The problem is that I would write the class in the most short-sighted and easiest way possible, which is usually not the best way to use it.

Now, when there is a question of what a class interface should look like, I ask myself what it should look like to make the life of the consumer as easy as possible.

Sometimes we can even take code usability to an extreme. For example, Fluent interfaces, which allow you to chain together multiple calls. In many instances, this makes the code much easier to call, potentially at the expense of making the called code more complicated.

I’ve come up with a simple example to help illustrate. Suppose I need to process a list of x,y coordinates. Here are a couple of potential signatures:

  • ProcessData(double[] xData, double[] yData);
  • ProcessData(PointF[] points);
  • ProcessData(IDictionary<double, double> points);

For now, just ignore the performance implications (they’re going to be linear in this case, or close to it anyway). To choose the correct signature, we need to know who the caller is.

Of course there is a good chance that we’ll have a slight intentional leaky abstraction. In the previous example, we may have been able to use the IEnumerable generic to be more flexible. That’s a topic for another day.

Thankfully, this problem is minimized, although not always eliminated when you follow the single responsibility principle. The better you can follow that principle, the simpler each piece will be. That tends to minimize the potential for the consumer to need the interface to look different than it would naturally be.

Another way to look at your classes from the consumers point of view is to practice test-driven development. In fact, I see this as one of the strongest arguments for test driven design. For each layer in your code, you’re creating code by consuming it before writing it. Every layer acts as an API to the layer above it.

In conclusion, I’m simply recommending that you don’t lose sight of why you’re writing that piece of code. You’re not just writing code for the sake of writing code, you’re writing it to be used!