Defensive coding is your friend

This post is a response to Ayende’s post http://ayende.com/blog/160898/defensive-coding-is-your-friend please read it before continuing.

It took me a while to understand what Ayende is trying to say with this post. First I thought he is faking his test results. The test is expecting that Fiddler is running on the test machine and he was trying to ignore it was not running. So why his test isn’t simply looking like this?

[Fact]
public void Should_get_independent_notification_subscriptions() {
    using (var store = NewRemoteDocumentStore(fiddler: false)) {
        /// Do whatever was intended to be done
    }
}

Then I looked up Fiddler and found that it is used for logging HTTP-Traffic. I realized what he was trying to explain. When executing this test locally on his machine (where Fiddler seems to be installed) he wants to be able to log traffic for development purposes but on the build server no one cares about that.

So Ayende’s solution is to check if fiddler is running and then to decide whether the test should use it or not.

What annoys me is the fact that you make your test system dependent, or at least give it the logic to behave different on different systems.

A possible solution that comes to my mind is to add another test class that provides the same tests, but uses Fiddler instead of the direct Url.

public class LocalDocumentStore : IDocumentStore {
    public LocalDocumentStore() { 
        //Using http://localhost:8079
    }
}

public class FiddlerDocumentStore : IDocumentStore {
    public FiddlerDocumentStore() {
        //Using http://localhost.fiddler:8079 here
    }
}

public abstract class SubscriptionTestBase<T> : IUseFixture<T> where T : IDocumentStore, new() {
    IDocumentStore store;

    [Fact]
    public void Should_get_independent_notification_subscriptions() {
        using (var session = store.OpenSession()) {
            session.Store(new TestDocument { Name = "Name" });
            session.SaveChanges();
        }
    }

    public void SetFixture(T data) {
        store = data;
    }
}

public class LocalSubscriptionTest : SubscriptionTestBase<LocalDocumentStore> { 

}

public class FiddlerSubscriptionTest : SubscriptionTestBase<FiddlerDocumentStore> { 

}

OK, it is a lot of work compared to Ayende’s solution but it is more understandable, in my humble opinion. The class LocalSubscriptionTest is used on build server for automated testing and the FiddlerSubscriptionTest is ignored except I explicitly start this test for debugging purposes.

The missing piece in that puzzle is, that it seems that xUnit.net does not support skipping of classes (like it would be possible in NUnit for example).

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>