Archive for unit testing

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!

A Dependency Injection example with Spring.NET

As requested, here is a real world example of how I used dependency injection to simplify a project, increase modularity, and subsequently increase testability.

Here’s the project. I have a successful website called SimpleTracking.com which allows you to track packages using a simple, common user interface. It also allows you to track pages using RSS.

Here is a list of features:

Supports multiple shippers, including FedEx, DHL, and USPS. The tracking number is resolved to one of them, and if a tracking number could belong to more than one, they are called simultaneously, and the one that returns the results is used. Results are cached to avoid overusing the shippers servers Errors are handled appropriately

I boiled the design into a tree of classes:

 image

To greatly simply the design, I decided that each module would implement a common interface. After all, they all take in a tracking number, and return tracking data. Here is the ITracker interface:

public interface ITracker
{
        TrackingData GetTrackingData(string trackingNumber);
}

Simple enough? Every class in the diagram above implements the same interface. If I want to add additional functionality, such as logging for example, I can simply add a class to the chain, and implement the same interface.

Now I can wire it up with Spring.NET:

<object name="postUtility" type="YTech.ShipperInterface.Tracking.Http.PostUtility, YTech.ShipperInterface" />

<!-- The trackers that actually do the work -->
<object name="uspsTracker" type="YTech.ShipperInterface.Usps.Tracking.UspsTracker, YTech.ShipperInterface">
        <constructor-arg ref="postUtility" />
        <!-- Code removed for readability... -->
</object>
<object name="fedexTracker" type="YTech.ShipperInterface.FedEx.Tracking.FedexTracker, YTech.ShipperInterface">
        <constructor-arg ref="postUtility" />
        <!-- Code removed for readability... -->
</object>
<object name="dhlTracker" type="YTech.ShipperInterface.Dhl.Tracking.DhlScreenScrapeTracker, YTech.ShipperInterface">
        <constructor-arg ref="postUtility" />
</object>
<object name="simulationTracker" type="YTech.ShipperInterface.Tracking.Simulation.SimulationTracker, YTech.ShipperInterface" />

<!-- Combine all of the other trackers into one stream -->
<object name="multiTracker" type="YTech.ShipperInterface.Tracking.MultiTracker, YTech.ShipperInterface">
        <constructor-arg>
                <list element-type="YTech.ShipperInterface.Tracking.ITracker, YTech.ShipperInterface">
                        <ref object="simulationTracker" />
                        <!-- Order these by popularity -->
                        <ref object="fedexTracker" />
                        <ref object="uspsTracker" />
                        <ref object="dhlTracker" />
                </list>
        </constructor-arg>
</object>

<!-- Cache the upstream tracking data -->
<object name="cacheTracker" type="YTech.ShipperInterface.Tracking.CacheTracker, YTech.ShipperInterface">
        <constructor-arg ref="multiTracker" />
</object>

<!-- Handle errors by logging them, and returning a special ErrorTrackingData object -->
<object name="MainTracker" type="YTech.ShipperInterface.Tracking.ErrorHandlerTracker, YTech.ShipperInterface">
        <constructor-arg ref="cacheTracker" />
</object>

Now in my code, this is all I have to do:

var ctx = ContextRegistry.GetContext();
var tracker = (ITracker)ctx.GetObject("MainTracker");
var td = tracker.GetTrackingData("my tracking number");

Every piece I’ve written is fully testable. I even created a class that posts data to a remote web server, and returns the response. This allows me to completely test the tracker classes. They don’t care if they’re hitting against a real server, or an in memory request/response mock class.

I have nearly 100% test coverage, and making changes to the site is a breeze.

The next step is to convert the actual web project to an MVC project so that I can unit test the actual page functionality.

Hopefully I’ve given a good example of how inversion of control can be a really good thing. Have any more questions about the architecture? Feel free to leave a comment.

Note: I haven’t replaced the code on the live SimpleTracking.com site yet, but I plan on upgrading in the next couple of weeks.

Unit tests are for functionality, not code!

Shawn has an interesting post where he talks about why 100% unit test coverage should be one of your goals. I agree 100%. I’m not sure why anyone would say that you shouldn’t be testing your properties. Don’t you want to make sure they work?

Unit-Testing

The prevailing philosophy in regards to unit testing is writing your tests before your code. In practice, this happens a lot less than it should. Why should we write our unit tests first?

Writing your unit tests first makes you design pieces of your software from the clients perspective. After all, you’re writing your code to be consumed. The code itself is not important, it’s what it does for other code. Unit tests are meant to test functionality, NOT code! That means if you write your unit tests after the fact, you’re probably not focusing on the functionality. You might be trying to come up with edge cases that might not even matter to the client. It’s harder to come up with good unit tests after the code is written, because you’re not necessarily looking at it from the clients perspective, or from the perspective of the required functionality.

There are two valid ways to increase code coverage:

Write additional tests - This only makes sense if you forgot to write the test initially. Since you’re tests are verifying functionality, why don’t you already have a test for this particular piece of functionality? Remove the untested code - In a perfect world, this is what you would always do. After all, your tests verify that your code has a certain set of functionality. If you have untested code, that code isn’t needed. Why keep code you don’t need?

Here is the basic process I recommend:

Come up with a rough design in your head Write unit tests to test a required piece of functionality Write the code to provide that functionality Verify that the unit tests pass, fix the code as necessary Refactor as necessary Run a code coverage tool, and get as close to 100% as possible using one of the methods I mentioned previously. Go to #2 and repeat as necessary

Do you really need a data access layer with LINQ?

Lately I’ve been giving a lot of thought to using LINQ to access my database instead of using NHibernate. I’ve been a little confused as to how LINQ would work in a data access layer, but I’m starting to think it makes sense as a replacement to the data access layer.

This article was inspired by the Google App Engine. Using the Django framework for database access is stupidly simple. They’re able to focus on getting something done, which is good enough in a lot of cases. Not every project has to be an N-Tier enterprise application.

Primarily, I write eCommerce websites. Consider the following diagram, which gives you a rough idea of how I’ve traditionally structured my applications:

Traditional Architecture

Notice that a lot of code is being tested. The sweet side of me likes unit tests, but the wheat part of me is telling me to simplify code when possible to minimize the need for unit tests. I’ve traditionally wanted a lot of unit tests at the data access layer because it tends to be a source of a lot of issues due to it’s complexity. It’s complexity is a result of impedance mismatch.

Code that is a good candidate for unit testing:

Logic/utility/static functions Code that will be used in a lot of places, and has a well defined contract Code that needs the highest levels of reliability

Now consider what happens when we use LINQ and the ADO.NET Entity Framework. The impendence mismatch has been minimized because the entity framework has automatically written our model code to match the database. It has also been my experience that the queries that are not trivial are usually not re-used. In other words, query complexity is inversely proportional to the frequency of re-use.

The end result is that our code has been greatly simplified. Now our unit tests can focus on the business logic. We’ll actually have more time for unit testing, which should lead to more stable code where it is needed most.

Sure, our UI will contain what are basically database queries. The fact is that many pages simply need a specific set of data that will populate a drop down list for example. I know that it might give people a bad feeling (as it does to myself), but I think it’s something we need to get over. If you want to test the page, in most cases you can just run it, and see that it’s working. In conjunction with a good web testing tool, it would be easy to have high levels of reliability.

Linq Architecture

Obviously there are a lot of places where this is a bad idea. I’m certainly not condoning a complete lack of a data access layer for every application. I’m applying the 80/20 rule. Places it might not make sense, or where it’s gray:

A logic class that needs to make frequent, repeated database calls.
An application that requires a certain level of testability.
An application that contains some extremely common queries that may or may not be trivial.


You are viewing a mobilized version of this site...
View original page here

Mobilized by Mowser Mowser