Welcome to MSDN Blogs Sign in | Join | Help

ploeh blog Is Moving

After three years on MSDN blogs, I'll be moving my blog to http://blog.ploeh.dk. Why? Read the answer here.

This is most likely the last post on this blog, so if you'd like to stay tuned, please go and subscribe to the new blog.

Posted by ploeh | 0 Comments
Filed under:

Faking The Windows Azure Table Service

When presented with a new technology, one of my primary evaluation criteria is its testability, so it should come as no surprise to the regular reader of this blog that this was also foremost in my mind when Windows Azure was presented at PDC. Much of the Azure Services Platform is just .NET, so testability is really up to you, just like with all other .NET code.

However, when it comes to the Windows Azure storage, the developer story is different. The Windows Azure Table Service is essentially a REST-based service, and to use it, you'll need to install the Azure Visual Studio SDK.

That's not a problem in itself, but it seems to be implemented as a REST service on top of SQL Server Express. While that may be good enough for casual development, that's quite heavyweight for unit testing. Imagine having to somehow deal with populating and cleaning this database between each test case. That will likely involve a fair amount of complex and undocumented Back Door Manipulation. As the service is out of process in relation to the test, this is brittle and slow, so a better approach is warranted.

Fortunately, I've already demonstrated how to Fake a REST-based Data Service, so faking the Windows Azure Table Service turns out to be fairly easy, and generally follows the same steps as previously outlined.

In the following example, I'm working with a simple service that echoes messages back to the caller. The Delay method saves the input message in table storage and returns the previous message from storage. This test verifies that the input message is being correctly saved:

[TestMethod]
public void DelayWillSaveMessage()
{
    // Fixture setup
    string expectedMessage = "Anonymous text";
 
    Uri address = new Uri("http://localhost/EchoService");
    FakeDataService<MessageContainer> service = 
        new FakeDataService<MessageContainer>(
            new MessageContainer());
    using (WebServiceHost host = 
        new WebServiceHost(service, new[] { address }))
    {
        host.Open();
 
        StorageAccountInfo account = 
            EchoFacadeTest.GetAccount();
        EchoFacade sut = new EchoFacade(() => account);
        // Exercise system
        sut.Delay(expectedMessage);
        // Verify outcome
        Assert.AreEqual<string>(expectedMessage,
            service.Container.GetStore<FakeMessage>().
            First().Message, "Delay");
        // Teardown
    }
}

In the EchoFacade service, I've used the SDK sample StorageClient library that extents the ADO.NET Data Services Client API to deal with the particulars of Windows Azure Table Storage. One difference from regular ADO.NET Data Services lies in how StorageClient deals with the base URIs of the REST interface. This is a challenge, because a URI like http://localhost/EchoService is interpreted as a service at the address localhost belonging to the account EchoService.

This has the implication that I can't just pass the complete address directly to the client API (i.e. EchoFacade), since it would need to decompose it before it can make proper use of it. Fortunately, such a decomposition already exists in the form of the StorageAccountInfo class, so I just need to pass a properly configured instance to my SUT to make it work.

The test accomplishes this task like this:

private static StorageAccountInfo GetAccount()
{
    Uri address = new Uri("http://localhost/");
    return new StorageAccountInfo(address, true,
        "EchoService", EchoFacadeTest.TableKey);
}

When the service is hosted in the full system (whether in the Development Fabric or on Azure proper), the StorageAccountInfo instance is instead initialized using the static StorageAccountInfo.GetDefaultTableStorageAccountFromConfiguration method.

If you are using the StorageClient library for your data access code, you might as well also take advantage of it when defining the fake service. First of all, you can derive the entities exposed from the Fake service from TableStorageEntity, as this gives you the key properties for free.

public class FakeMessage : TableStorageEntity
{
    public FakeMessage()
    {
        this.CreationTime = DateTime.Now;
    }
 
    public DateTime CreationTime { get; set; }
 
    public string Message { get; set; }
}

The DataContainer then becomes equally simple:

public class MessageContainer : DataContainer
{
    public IQueryable<FakeMessage> Messages
    {
        get
        { 
            return this.GetStore<FakeMessage>().
                AsQueryable(); 
        }
    }
}

Using a Fake ADO.NET Data Service enables you unit test clients of the Windows Azure Table Service in a light-weight manner.

In this Fake, I have chosen not to deal with the Windows Azure Table Service's particular way of partitioning and sorting data according to PartitionKey and RowKey. Instead, I just rely on the Fixture of each test to insert the data entities in the expected order.

Posted by ploeh | 1 Comments
Filed under: ,

A General-Purpose Fake ADO.NET Data Service

In my previous post, I discussed how to implement a Fake ADO.NET Data Service for use with unit testing, showing how you can develop a one-off service that addresses specific needs, such as querying parents and children in the example.

As I hinted in that post, it's possible to create a reusable Fake ADO.NET Data Service that takes care of implementing IUpdatable based on in-memory data storage. To save you the trouble of doing that, I've created one that you can use, if you should so desire.

Following the standard ADO.NET Data Service coding idiom, the Fake ADO.NET Data Service consists of two classes:

  • FakeDataService<T>, which derives from DataService<T>. This is simply the counterpart of MyDataService from the previous example. You can use this class as is.
  • DataContainer, which implements IUpdatable. Although I haven't made this class abstract, it only becomes useful when you derive from it and define your own queries.

Let's say that I want to use these two classes to unit test the same service client as in the previous example. Instead of MyService (where I manually had to implement IUpdatable), I can now define my data container as simply as this:

public partial class ParentChildContainer : DataContainer
{
    public IQueryable<Child> Children
    {
        get 
        {
            return this.GetStore<Child>().AsQueryable(); 
        }
    }
 
    public IQueryable<Parent> Parents
    {
        get
        {
            return this.GetStore<Parent>().AsQueryable(); 
        }
    }
}

The only thing you have to do is just derive from DataContainer and specify your queries.

Although you don't have to use FakeDataService<T> to host your Fake DataContainer, it makes it easy to set up the Fake service in a unit test:

[TestMethod]
public void TestCanSetupFakeService()
{
    // Fixture setup
    Uri address = new Uri("http://localhost/MyDataService");
    FakeDataService<ParentChildContainer> service = 
        new FakeDataService<ParentChildContainer>(
            new ParentChildContainer());
    using (WebServiceHost host =
        new WebServiceHost(service, new[] { address }))
    {
        host.Open();
        // Exercise system
        // ...
        // Verify outcome
        // ...
        // Teardown
    }
}

How does this work? DataContainer stores each 'table' in a List<T>, and each list is again stored in a dictionary that maps the list to the type. Here's the part of DataContainer that doesn't contain the IUpdatable implementation:

public partial class DataContainer
{
    private readonly Dictionary<Type, IList> stores;
 
    public DataContainer()
    {
        this.stores = new Dictionary<Type, IList>();
    }
 
    public IList<T> GetStore<T>()
    {
        if (!this.stores.ContainsKey(typeof(T)))
        {
            this.AddStore<T>();
        }
        return (IList<T>)this.stores[typeof(T)];
    }
 
    private void AddStore<T>()
    {
        this.stores.Add(typeof(T), new List<T>());
    }
}

When you call GetStore<T>, DataContainer implicitly creates the list for the give type if it doesn't already exist.

The rest of DataContainer deals with implementing IUpdatable:

#region IUpdatable Members
 
public void AddReferenceToCollection(object targetResource,
    string propertyName, object resourceToBeAdded)
{
    IList list = (IList)targetResource.GetType().
        GetProperty(propertyName).
        GetValue(targetResource, null);
    list.Add(resourceToBeAdded);
}
 
public void ClearChanges()
{
}
 
public object CreateResource(string containerName,
    string fullTypeName)
{
    Type t = this.ResolveType(fullTypeName);
    object resource = Activator.CreateInstance(t);
    this.stores[t].Add(resource);
    return resource;
}
 
public void DeleteResource(object targetResource)
{
    foreach (IList list in this.stores.Values)
    {
        list.Remove(targetResource);
    }
}
 
public object GetResource(IQueryable query,
    string fullTypeName)
{
    return query.Cast<object>().AsEnumerable().
        FirstOrDefault();
}
 
public object GetValue(object targetResource,
    string propertyName)
{
    return targetResource.GetType().
        GetProperty(propertyName).
        GetValue(targetResource, null);
}
 
public void RemoveReferenceFromCollection(
    object targetResource,
    string propertyName,
    object resourceToBeRemoved)
{
    IList list = (IList)targetResource.GetType().
        GetProperty(propertyName).
        GetValue(targetResource, null);
    list.Remove(resourceToBeRemoved);
}
 
public object ResetResource(object resource)
{
    return resource;
}
 
public object ResolveResource(object resource)
{
    return resource;
}
 
public void SaveChanges()
{
}
 
public void SetReference(object targetResource,
    string propertyName, object propertyValue)
{
    targetResource.GetType().GetProperty(propertyName).
        SetValue(targetResource, propertyValue, null);
}
 
public void SetValue(object targetResource, 
    string propertyName, object propertyValue)
{
    targetResource.GetType().GetProperty(propertyName).
        SetValue(targetResource, propertyValue, null);
}
 
#endregion
 
private Type ResolveType(string fullTypeName)
{
    return (from t in this.stores.Keys
            where t.FullName == fullTypeName
            select t).First();
}

If you find this useful, I've attached the code to this post for your downloading pleasure. As always, the standard disclaimers apply.

Posted by ploeh | 2 Comments
Filed under: ,

Attachment(s): DataServicesQualityTools.zip

Creating A Fake ADO.NET Data Service

Previously, I discussed unit testing ADO.NET Data Service clients using a Fake ADO.NET Data Service, and I promised to demonstrate how to create such a service. In this article I will continue the previous example and implement the Fake MyService class.

The basics of MyService is pretty simple:

public partial class MyService
{
    public MyService()
    {
        this.ParentStore = new List<Parent>();
        this.ChildStore = new List<Child>();
    }
 
    public IQueryable<Child> Children
    {
        get { return this.ChildStore.AsQueryable(); }
    }
 
    public IQueryable<Parent> Parents
    {
        get { return this.ParentStore.AsQueryable(); }
    }
 
    public IList<Child> ChildStore { get; private set; }
 
    public IList<Parent> ParentStore { get; private set; }
}

This service supports two 'tables': Parents and Children (Parents can have Children). Since this is a Fake, it only needs to store its data in memory, so I use two List<T> instances for that. To provide direct access to the service's data, MyService exposes both lists as public properties (you can make those properties internal if your Fake service is defined in the same assembly as your tests).

This is all you need if you only need to support read-only scenarios. If the client you want to test only queries its service, you don't need to do anything else. On the other hand, if you also need to test Create, Update and Delete (CUD) operations, you will need to implement IUpdatable:

public partial class MyService : IUpdatable

Implementing this interface enables you to support CUD operations. Since it contains twelve members, I'm not going to walk you through each and every one of them, but rather present some highlights. If you are interested in more details on the methods of this interface, I'll recommend this post on the Project Astoria Team Blog.

To support each of the simple CUD operations, multiple methods must be implemented, although there's an overlap.

To create a new item, the first method to implement is CreateResource.

public object CreateResource(string containerName, 
    string fullTypeName)
{
    switch (containerName)
    {
        case "Parents":
            Parent p = new Parent();
            this.ParentStore.Add(p);
            return p;
        case "Children":
            Child c = new Child();
            this.ChildStore.Add(c);
            return c;
        default:
            throw new ArgumentException(
                "Unknown container name.");
    }
}

This implementation simply creates a new instance of the requested item type and adds it to the in-memory list. Here, I was just being a bit lazy and simply switched on the containerName, but it's perfectly possible to create a more generic implementation using a bit of Reflection, since the fullTypeName parameter specifies which type of object to create.

The CreateResource method's responsibility is to create a default instance of the requested type and add it to the underlying data store (in this case just an in-memory list). However, it doesn't assign values to the item's properties, since this is the duty of the SetValue method.

public void SetValue(object targetResource, 
    string propertyName, object propertyValue)
{
    Type t = targetResource.GetType();
    t.GetProperty(propertyName).SetValue(
        targetResource, propertyValue, null);
}

At this point, I found it easier to implement the method using Reflection than explicitly switching on both the targetResource and propertyName parameters.

The last method that must be implemented to support the Create scenario is ResolveResource.

public object ResolveResource(object resource)
{
    return resource;
}

Since the Fake service is already working with in-memory objects, it can just return the object itself.

With these methods implemented, updating an item is not quite as involved, since it reuses the SetValue and ResolveResource methods, so I only need to implement the GetResource method.

public object GetResource(IQueryable query,
    string fullTypeName)
{
    return query.Cast<object>().AsEnumerable().
        FirstOrDefault();
}

This implementation requires a bit of explanation. The query argument that the method receives is actually an expression over the service's exposed queries (i.e. Parents and Children). Since the service operates on in-memory objects, it doesn't need to transform the expression, but can simply evaluate it directly, which is what the AsEnumerable extension method does. However, IQueryable doesn't have an AsEnumerable extension method, whereas IQueryable<T> does - hence the cast to object.

Deleting an item reuses GetResource and ResolveResource, so to support this scenario, the DeleteResource method is the only extra method that must be implemented.

public void DeleteResource(object targetResource)
{
    ((IList)this.ParentStore).Remove(targetResource);
    ((IList)this.ChildStore).Remove(targetResource);
}

Once again, I decided to keep things simple and simply hard-code knowledge of ParentStore and ChildStore into the method, but it would be easy to generalize this approach.

The rest of the methods of IUpdatable address more advanced scenarios concerning references between items, and I'm not going to cover them in this post, since it's already becoming quite long. If you are interested, I've provided the entire sample code as an attachment to this post, so download and peruse it at your leisure (obviously, the usual disclaimers apply).

Update: I've now posted a general-purpose Fake ADO.NET Data Service that should hopefully address most of your needs.

Posted by ploeh | 1 Comments
Filed under: ,

Attachment(s): DataServiceTesting.zip

Unit Testing ADO.NET Data Service Clients

In my previous post, I discussed unit testing ADO.NET Data Services and how you can host and test the service itself. In this post, I'll take a look at the opposite scenario: You have a client of an ADO.NET Data Service, and you want to unit test the client without relying on the real, production service.

In other words, you want to test the real client against a Test Double service. Presently, I'll show you how to create and host a Fake ADO.NET Data Service that the client code can invoke. Obviously, the client in this example uses the ADO.NET Data Services Client API, so I'll demonstrate how you can use that to invoke the fake service from within the same test.

Before we dive into the specifics of the implementation, here's a simple test that verifies that the client can retrieve all Parent instances from the service:

image

As you can see from the figure, the test combines two logical tiers into one test: The service and the client.

The service tier is simply part of the test's Fixture, and while I'm not concerned with testing it in this context, I still need to set it up. This part uses the ADO.NET Data Services API to define and host the service.

The client part uses the ADO.NET Data Services Client API to query the service via its REST interface and verify the result.

Notice that I use an instance of MyDataService to configure the host. While not strictly necessary in this test, when hosting a Fake service, it's desirable to have a reference to the fake instance itself, since that allows you to configure and query it through its Back Door. Here's a test that uses the MyDataService instance to verify that a Parent instance was deleted from the service:

[TestMethod]
public void ClientCanDeleteInstance()
{
    // Fixture setup
    Uri address = new Uri("http://localhost/MyDataService");
    MyDataService service = new MyDataService();
    using (WebServiceHost host = 
        new WebServiceHost(service, new[] { address }))
    {
        host.Open();
 
        MyDataServiceContext ctx =
            new MyDataServiceContext(address);
        var victim = (from p in ctx.Parents
                      where p.Id == 3
                      select p).Single();
        // Exercise system
        ctx.DeleteObject(victim);
        ctx.SaveChanges();
        // Verify outcome
        Assert.IsFalse(service.Data.Parents.Any(
            p => p.Id == victim.Id), "Deleted");
        // Teardown
    }
}

As in the previous example, all Fixture Setup before the declaration of the MyDataServiceContext instance is part of the logical service tier, while the remaining Fixture Setup code, as well as the execution of the SUT is part of the logical client tier. However, notice that the verification now takes place on the logical service tier, since I'm using the fake service instance as a Back Door, instead of relying on the REST interface to query the service.

Since DataServiceHost doesn't include a constructor that takes a single instance as a parameter, I use its base class WebServiceHost instead. Reflector shows that DataServiceHost really adds no behavior to its base class, so using WebServiceHost as a host should be safe - for now (let's hope it stays that way, or even better, that it gets a constructor overload that accepts a service instance).

In normal cases, I consider it best practice to explicitly load data into the fake service as part of the Fixture Setup phase, but to keep these examples simple, I decided to implicitly load some test data as part of creating the MyDataService instance. That is why, in the above example, I can successfully retrieve a Parent instance with an Id of 3. Please be aware that this is not a strategy I endorse - I only did it to keep the example a bit less complex.

Here's the MyDataService class in its entirety:

[ServiceBehavior(IncludeExceptionDetailInFaults = true, 
    InstanceContextMode = InstanceContextMode.Single)]
public class MyDataService : DataService<MyService>
{
    private readonly MyService service_;
 
    public MyDataService()
    {
        this.service_ = new MyService();
 
        IList<Parent> ps = this.service_.ParentStore;
        ps.Add(new Parent() { Id = 1, Text = "Ploeh" });
        ps.Add(new Parent() { Id = 2, Text = "Fnaah" });
        ps.Add(new Parent() { Id = 3, Text = "Ndøh" });
        ps.Add(new Parent() { Id = 4, Text = "Foo" });
        ps.Add(new Parent() { Id = 5, Text = "Bar" });
 
        IList<Child> cs = this.service_.ChildStore;
        cs.Add(new Child() { Id = 1, Text = "Child 1" });
        cs.Add(new Child() { Id = 2, Text = "Child 2" });
        cs.Add(new Child() { Id = 3, Text = "Child 3" });
    }
 
    public MyService Data
    {
        get { return this.service_; }
    }
 
    public static void InitializeService(
        IDataServiceConfiguration config)
    {
        config.SetEntitySetAccessRule("*",
            EntitySetRights.All);
        config.UseVerboseErrors = true;
    }
 
    protected override MyService CreateDataSource()
    {
        return this.service_;
    }
}

As I described, I use the constructor to set up some implicit test data. While I want to reiterate that this is not something I would recommend, I chose to include this code to make it clear what I was talking about.

The service is decorated with the ServiceBehavior attribute, which sets its InstanceContextMode to Single to allow it to be hosted as a Singleton service by WebServiceHost. This, again, is what allows me to query the fake service's data via its Back Door.

Since MyService simply stores data in memory, MyDataService needs to keep the same instance around for each request, so it overrides CreateDataSource to ensure that the same data container instance is always being referenced for the lifetime of the instance.

In a later post, I will describe how to create the fake data service, MyService.

Posted by ploeh | 2 Comments
Filed under: ,

Unit Testing ADO.NET Data Services

ADO.NET Data Services enables you to expose data (including, but not limited to, relational data) as REST services. Since it's built on top of WCF, it can be tested utilizing similar techniques, but allow me to elaborate a bit on the subject.

As with WCF, you might be interested in testing one or both tiers:

  • The service
  • The client

Testing the service is the simplest undertaking, so I'll start with that and return to testing the client in a later post.

Why would you want to unit test an ADO.NET Data Service?

The mainstream scenario for ADO.NET Data Services is to expose a relational database using an ADO.NET Entity Model. Is it relevant to unit test such a service? Perhaps not. It depends on the amount of code you inject into the generated (partial) classes. If the amount of custom code is minimal, it may not make much sense to test simple CRUD operations.

Conversely, if you have a greater degree of custom code, or if you implement an ADO.NET Data Service using non-relational data, it makes a lot of sense.

My loyal readers will probably (correctly) suspect that I would tend to expose a Façade over a Domain Model as a data service, which implies going the non-relational route (even if the underlying data store is, in fact, relational). That is also the context for the rest of this post.

First of all, you should keep in mind that the data service is just a normal class, so you can test much of its functionality by just creating it and start using it:

[TestMethod]
public void ServiceCanReturnRequestedItem()
{
    // Fixture setup
    int anonymousId = 3;
    string expectedText = "Ploeh";
 
    Parent anonymousParent = new Parent();
    anonymousParent.Id = anonymousId;
    anonymousParent.Text = expectedText;
 
    MyService sut = new MyService();
    sut.ParentStore.Add(anonymousParent);
    // Exercise system
    Parent result = (from p in sut.Parents
                    where p.Id == anonymousId
                    select p).Single();
    // Verify outcome
    Assert.AreEqual<string>(expectedText, result.Text,
        "Text");
    // Teardown
}

Notice how most of the test just contains code setting up the Fixture by adding the relevant data to the service's underlying data store, while execution and verification is quickly accomplished.

At some point, however, you will probably want to test the service through its REST interface. To do this, you must host the service within the test and then invoke it.

Hosting the service in a test is easy:

[TestMethod]
public void TestCanHostService()
{
    // Fixture setup
    Uri address = new Uri("http://localhost/MyDataService");
    using (DataServiceHost host = 
        new DataServiceHost(typeof(MyDataService),
            new[] { address }))
    {
        host.Open();
        // Exercise system
        // ...
        // Verify outcome
        // ...
        // Teardown
    }
}

Since the service is exposed through a REST interface, you can use more than one technology to invoke it. The ADO.NET Data Services client API is a natural fit, and I'll cover this in a later post. For now, just imagine that the test above contains client code that invokes the service and verifies the result.

As it turns out, unit testing an ADO.NET Data Service isn't particularly difficult. Unit testing ADO.NET Data Service Clients is a bit more involved, so I'll cover that topic in a separate post. Update: This post is now available here.

Posted by ploeh | 1 Comments
Filed under: ,

Test-Driven Properties

Zero-Friction TDD post #10:

In principle, defining properties (or fields, for that matter) while TDD'ing should be no different than defining methods. Again, the important part is to stay focused on the test at hand, and not become bogged down by implementation details.

Unfortunately, neither Visual Studio 2005 nor 2008 has a Generate property stub smart tag, so until the day arrives when we get support for such in our IDE of choice (and for the record: I have no idea about when this is going to happen), we'll have to resort to more primitive means:

Just reference the non-existing property and move on:

UndefinedProperty

As you can see from the picture, my test code gets squiggly lines under the MyProperty property because this property doesn't exist (yet).

Once more, the important point is to move on and resist the urge to fix this immediately. Don't even waste memory (your own, that is) on the fact that you need to implement this soon; just forget about it right away. The compiler will remind you in due time.

This technique is a essentially what Michael Feathers calls leaning on the compiler, although the context is different.

Posted by ploeh | 1 Comments

Use The Generate Method Stub Smart Tag To Stay In The Zone

Yet Another Zero-Friction TDD Article (YAZFTA):

When writing unit tests in the TDD fashion, it's important to stay in the zone and not get side-tracked by irrelevant issues. You need to avoid what I call mental context switching. Focus on writing the test and postpone all else to later, but make sure that you do it in such a way that you don't have to waste brainpower on remembering what you postponed.

One easy way to do this is by using the Generate method stub smart tag in Visual Studio:

GenerateMethodStubSmartTag

As we all know, this will generate the following implementation in MyClass:

public void MyMethod()
{
    throw new NotImplementedException();
}

but since you already know that, you don't have to go look at it, and you don't even need to commit to memory that you will have to implement the method. When you run the test, it's going to throw a NotImplementedException, and that's all the reminder you need.

So just use the smart tag and move on. Right away, forget about the method you just created. Resist the temptation to go implement it immediately, no matter how simple it might be. Stay focused on writing the test.

You can use the same technique when it comes to evolving SUT API Encapsulation: Sometimes, I know that I'd really like a test helper method that can do something for me, but I have only a vague idea about how to implement it. In such cases, I just write the name of the method, use the smart tag and move on. This helps me stay focused on writing the test, and I can always come back later and implement the helper method at a more convenient time.

Posted by ploeh | 4 Comments

Assert Messages Are Not Optional

...and now, in this week's episode of Zero-Friction TDD: Optional Assert messages that aren't optional anyway!

Actually, this piece of advice comes almost directly from the xUnit Test Patterns book, so I was in doubt whether I should post it all, but it bears repeating, and I guess I still have a few things to add.

The various Assert methods all have an overload that takes a message string that is basically just echoed to the Test Results list if the test fails, appended to the assertion's more generic message.

For example, this assertion

Assert.AreEqual<string>(expectedResult, result, "DoStuff");

will produce this output:

Assert.AreEqual failed. Expected:<ploeh>. Actual:<>. DoStuff 

As there are also overloads available that does not take such a message string, it is tempting to treat it as optional. As far as the compiler is concerned, I might as well have written this:

Assert.AreEqual<string>(expectedResult, result);

which would have yielded this output:

Assert.AreEqual failed. Expected:<ploeh>. Actual:<>.

Not much of a difference, so it may seem quite redundant to supply this extra message.

Well, not only will I argue that it provides value, I will even go so far as to insist that you should treat it as mandatory. Here's the reason:

When one or more test failures appear in the Test Results window, my eyes naturally seek out the Error Message text, so it's very nice to have all the information I need present in the same context. All I really need is just a small hint that will jog my memory enough so that I know what I did wrong.

Please note that I'm not really talking about using the message in the initial Red/Green/Refactor development cycle. In this phase, I rarely read the test failure text at all - I only register that there was a failure, which was expected, since the code isn't implemented yet.

I'm talking about what happens when you refactor a code base with hundreds of tests. In such cases, I often inadvertently break existing tests, and my eyes immediately seek out the Error Message.

Imagine that this is the error message:

Assert.AreEqual failed. Expected:<ploeh>. Actual:<>.

All this really tells me is that in one of my tests (and I don't know which one yet), something was expected to have the value ploeh, but ended up having no value. That's not a lot to go after, so I will probably have to open the test and read it through to get enough context to know what I broke.

On the other hand, I've experienced that just a little extra message often provides just enough context that I immediately realize what I broke:

Assert.AreEqual failed. Expected:<ploeh>. Actual:<>. DoStuff 

In this case, DoStuff is the name of the method being tested. It may seem hard to believe, but in most cases, this is context enough to help my brain figuring out what went wrong. Keep in mind that the test failure was a result of a code change that I just implemented, so my mind has a lot of context already, and it needs almost no help to make the final connection.

When I first encountered this guidance, I was sceptic, but after having worked with it for some time, I'm not going back. It has increased my productivity while refactoring, because I don't need to investigate failure causes quite as often as I did before.

Most developers dislike having to write this optional message because they feel that they ought to write a long piece of fluent prose. That's not the case: Just write a single cue that can trigger your brain at a later date. Normally, I just write the name of the method or property I'm testing - I find that I can easily do that and still stay in the zone when I'm writing my tests.

You are probably still skeptical, but try it out for a couple of months and see what you think!

Posted by ploeh | 3 Comments

First Dynamics Mobile Post

Yesterday, I posted my first post over on the Microsoft Dynamics Mobile Team blog. More are likely to follow.

In case you are wondering what this means for this blog, the answer is: Nothing. I plan to continue blogging in more or less the same vein as I've done for the last three years now.

Posted by ploeh | 0 Comments
Filed under:

Why Use AreEqual<T>?

This is a post in my Zero-Friction TDD series.

One of my colleagues recently asked my why I prefer Assert.AreEqual<T> over one of the non-generic Assert.AreEqual overloads for primitive types.

In most cases, I'm very happy with the C# compiler's ability to infer generic type arguments from the method call parameters, but this case is a little different.

Let's say you want to compare two strings. I always do it like this:

Assert.AreEqual<string>(expectedResult, result, "DoStuff");

This statement explicitly tells the compiler to use AreEqual<string>. However, if I omit the type parameter, type inferencing is not going to happen:

Assert.AreEqual(expectedResult, result, "DoStuff");

Instead of inferring the type parameter from the parameters, the compiler (correctly) selects the best matching overload, in this case, AreEqual(object, object, string).

When both the expectedResult and result variables are strings, this will still compile and work, but you just lost static type checking.

There are 18 overloads of AreEqual, but that still leaves many combinations where type inferencing will occur. Consider comparing two integers:

Assert.AreEqual<int>(expectedNumber, result, "Explicit typing");

Since there's no non-generic overload that takes Int32 instances, you could omit the type parameter and still arrive at the AreEqual<int> overload:

Assert.AreEqual(expectedNumber, result, "Implicit typing");

However, what happens if you change the type of result to a string? In the first case, you will get a compilation error, but in the latter case, the compiler instead selects the AreEqual(object, object, string) overload!

When you perform refactorings that change the type of one of the assertion variables, the tests will still compile if you rely on type inferencing, but may fail at run-time. With the refactoring support in Visual Studio, you may be changing the type of a property somewhere else in your code base without thinking about the test code at all. If you test directly against such a property in your AreEqual assertion, static type checking could protect you, but the non-generic overloads may introduce subtle errors in your tests.

Since test suites should be executed often, you might argue that you'll discover errors like that soon enough, but I'm a strong believer in fail fast, so I still rather prefer getting a compiler error than a run-time error in my test suite.

The easiest strategy is to not think about this at all, and just always explicitly define the type, so that's what I do: I always use AreEqual<T> and AreNotEqual<T> (except in special cases, but more about that later).

Posted by ploeh | 1 Comments

3 Is Many

This is an installment in my Zero-Friction TDD series.

When I was a kid, my parents taught me that many is any number above three two*; they used the simple counting sequence one, two, many. This little story may make me seem like I was an incredibly dim-witted kid, but the point was obviously not that I couldn't count to more than three, but rather that, in many cases, unary and binary systems may be special, but as soon as you cross the threshold to three, you are dealing with a number that doesn't exhibit any particular characteristics.

Note: I'm not talking about number theory here. I'm sure someone will be able to tell me about all sorts of special characteristics of the number 3. Incidentally, three also seems to be a magic number in many cults and religions. That's not what I'm talking about either.

If you will allow me to further digress, studies have shown that some animals can count to both three and also higher numbers. This goes for humans as well: If I place a number of marbles/dice/glass beads/whatever in front of you, and you have to give me the number as fast as possible, you can probably do that without counting up to perhaps five or six. For higher numbers, you will have to count the items. Three is an instantly recognizable number by the human mind, but I'm not talking about cognition either.

As a colleague once told me: The hardest scale-out you can perform is going from one to two. Nonetheless, if you look at concepts such as active/passive failover clustering, it would seem as though going from two to three is also non-trivial.

However, once you have managed to deal with three of whatever it is you deal with, you are probably ready to deal with four, five, or even twenty-seven. To bring the topic back to code, at that point you are probably working with a list of some sort.

When testing against lists, 3 is a good Equivalence Class for many. If you have a list of three elements, you have distinct elements for the head, interior and tail of the list. You can perform meaningful sorts and filtering on such a list.

In fact, I usually find that I can reproduce most scenarios (as well as most bugs) with lists of three elements.

When writing unit tests, for maintainability the number 3 shouldn't just appear as a magic number in the test, so it makes more sense to define it as a constant somewhere, as in this, otherwise inane, example:

private const int Many = 3;
 
[TestMethod]
public void SumOfManyNumbersWillBeCorrect()
{
    // Fixture setup
    IEnumerable<int> anonymousNumbers = 
        Enumerable.Range(0, MyClassTest.Many);
    int expectedSum = anonymousNumbers.Sum();
    MyClass sut = new MyClass();
    // Exercise system
    int result = sut.Sum(anonymousNumbers);
    // Verify outcome
    Assert.AreEqual<int>(expectedSum, result, "Sum");
    // Teardown
}

The only noticeable part of this piece of code is the Many constant, which is used in the test code itself. This is a good hint to the Test Reader that this test deals with many integers, without particularly caring about how many there are.

* Edit 2009.01.20

Posted by ploeh | 1 Comments

Creating Azure Tables From Script

When working with the Windows Azure Storage service, you must create the tables before you can use them; in essence, defining the 'schema' of your Azure storage service.

On his blog, Steve Marx writes:

"Probably the best solution is to have separate initialization code that creates your tables.  This is analogous to the pattern of having CREATE TABLE commands scripted in T-SQL which you run once to set up the database."

I can only agree, but if you are relying on the CreateTablesFromModel method from the StorageClient data access API (from the Azure SDK), how can you do that?

The first thing to realize is that since you can connect to your Azure Storage Service from anywhere, the script does not need to execute in the cloud. You can just as well run this script from your local development machine, as long as you can connect to your storage account.

You could obviously write a little utility that references StorageClient and your custom TableStorageDataServiceContext.

Another, in my opinion, better option for such a one-off script is a PowerShell script. Here's my first take on such a script:

$address = "http://table.core.windows.net"
$account = <accountName>
$accessKey = <accessKey>
 
$storageClientPath = <storageClientPath>
$contextPath = <contextPath>
 
[System.Reflection.Assembly]::LoadFrom($storageClientPath)
[System.Reflection.Assembly]::LoadFrom($contextPath)
 
$ai = New-Object Microsoft.Samples.ServiceHosting.StorageClient.StorageAccountInfo($address, $null, $account, $accessKey)
 
$dataContext = New-Object <customContext>($ai)
$t = $dataContext.GetType()
 
$ts = [Microsoft.Samples.ServiceHosting.StorageClient.TableStorage]::Create($ai)
$ts.ListTables() | % { $ts.DeleteTable($_) }
 
[Microsoft.Samples.ServiceHosting.StorageClient.TableStorage]::CreateTablesFromModel($t, $ai)

First of all, you will need to fill in the values that I've enclosed in angle brackets (remember quotes):

  • accountName is the name of your Windows Azure Storage account
  • accessKey is your Windows Azure Storage access key
  • storageClientPath is the full path to the StorageClient assembly, e.g. "C:\Program Files\Windows Azure SDK\v1.0\Samples\StorageClient\Lib\bin\Debug\StorageClient.dll"
  • contextPath is the full path to the assembly that contains your custom TableStorageDataServiceContext
  • customContext is the fully qualified type name of your custom context (see the update comment below)

This script does the following:

  1. It loads the StorageClient and your custom assembly into memory so types from those assemblies can be consumed by the script.
  2. It loops through all the tables currently in storage and deletes them (delete the penultimate line if you don't want it to do this)!
  3. It creates the tables from your data model.

Currently, the script has one limitation: Deleting a table using the StorageClient API only marks the table for deletion, so the operation returns much to soon. This means that if you are trying to recreate a table by the same name, a conflict will occur, and the table will not be created. You can work around this limitation by waiting a little while and then run the script again.

Update: In the original version of this post, I accidentally forgot to remove the specific type name of the custom context class that I'd used to create the script. Since you will not have access to that class, it doesn't make sense, so I replaced it with the customContext placeholder.

In case you were wondering, the original line of code was:

$dataContext = New-Object Microsoft.Dynamics.Mobile.Server.AzureDataAccess.MobileServerDataServiceContext($ai)

Posted by ploeh | 3 Comments
Filed under:

testmethod Code Snippet

This is an installment in my Zero-Friction TDD series.

If you are a regular reader of this blog, you may have noticed a certain pattern in my unit test examples (like this one). This is because I always follow the Four-Phase Test pattern (which is a superset of the more well-know Triple-A (Arrange Act Assert) pattern), with a few code comments to denote the different phases (incidentally, in this case, I don't regard these code comments as Apologies).

Writing the skeleton of such a test (the TestMethod attribute, the method declaration, the four comments) is very repetitious work, and I got tired of it around the third or fourth time I had to do it. Therefore, I wrote a code snippet that, in essence, just generates this template:

[TestMethod]
public void Test()
{
    // Fixture setup
    // Exercise system
    // Verify outcome
    Assert.Inconclusive();
    // Teardown
}

From there, you are ready to go ahead and fill in the blanks. It saves me a bit of typing for every test I write and allows me to get started faster with formulating the actual value-adding code, while the structure reminds me to write good and maintainable tests.

I've been using this code snippet for more than a year now, and although I've considered many enhancements to it, I've always felt comfortable with the versatility that this simple implementation provides.

For your convenience, I've attached the code snippet to this post: Just download it and put it in your <Documents>\Visual Studio 2008\Code Snippets\Visual C#\My Code Snippets folder. Now you can just type testmethod and expand the snippet, and you have a structured Four-Phase Test ready to be implemented.

Once more, it saves you a bit of mental context switching, and you can focus on writing the test code that really matters.

Posted by ploeh | 1 Comments
Attachment(s): testmethod.snippet

Ignore Irrelevant Return Values

This is an installment in my Zero-Friction TDD series.

Sometimes, you don't care about the return value from a particular operation. The simplest example is if you want to check that creating a new instance of a specific type will throw an exception if supplied with wrong parameter values:

[ExpectedException(typeof(ArgumentNullException))]
[TestMethod]
public void CreateWithNullTextWillThrow()
{
    // Fixture setup
    int anonymousNumber = 8;
    string nullText = null;
    // Exercise system
    new Plop(anonymousNumber, nullText);
    // Verify outcome (expected exception)
    // Teardown
}

In this example, even though the new operation is supposed to return a value, we don't care about it, since we only want to test that the correct exception type is being thrown. To save myself from having to stop and think about a variable name (even though in this case, I'd just have used sut), I prefer to not declare and assign the variable at all.

In general, I believe that APIs should follow the principle of Command-Query Separation, but sometimes it makes sense to break this rule. When you have an operation that both return a value and have side-effects, testing the side-effect via state-based testing doesn't require the return value.

Imaging that you have a method with this signature:

public object CommandQuery(int number)

Testing the side-effect may look like this:

[TestMethod]
public void CommandQueryWillUpdateNumberProperty()
{
    // Fixture setup
    int expectedNumber = 89;
    int anonymousNumber = 11;
    string anonymousText = "Anonymous text";
    Plop sut = new Plop(anonymousNumber, anonymousText);
    // Exercise system
    sut.CommandQuery(expectedNumber);
    // Verify outcome
    Assert.AreEqual<int>(expectedNumber, sut.Number, "CommandQuery");
    // Teardown
}

Notice that I've ignored the return value of the CommandQuery method.

Save yourself the time and effort it takes to declare and assign variables if you don't use them anyway.

Posted by ploeh | 1 Comments
More Posts Next page »
 
Page view tracker