Thursday, September 24, 2009

TestMethod Code Snippet

If you’ve ever written more than one test method for any of the test frameworks out there that uses attributes, you know how quickly you start hoping for a code snippet to create the body of the method for you. Actually, you start hoping for one if you are aware that code snippets do exist. What? Everyone knows about snippets, no? Well, I’m sorry, but no. Think what you will, most people I have worked with didn’t know about code snippets until I told them that they existed. But if you do know about code snippets, here’s how you would go about creating a test method snippet for MSTest.

First, you absolutely need to download Snippet Editor on CodePlex. It makes creating snippets a breeze. So just download it, extract the files and run the executable.

Press the New button and you can start creating your snippet. The first fields are pretty self-explanatory. Just name and describe the snippet and name yourself as the other. Pay attention to the shortcut field, this is what you will need to type in the code editor to activate your snippet. I used tm. You then need to select the language for your snippet (C# in this case) and the kind of code your snippet produces.  Member Declaration is the type needed in our case.

Next up is the code itself. Just type the code you wish to appear once the snippet is activated. This is the code I wrote for my test method snippet:

[TestMethod]
public void TestThat()
{
    // Arrange

    // Act

    // Assert
}

Almost done, just click the save button and place the snippet in your snippet folder (document\Visual Studio 2008\Code Snippets\Visual C#\My Code Snippets by default). You are now ready to test your brand new code snippet.

Fire up Visual Studio, create a new class (test class or not, it doesn’t matter), move the cursor inside the class definition and press tm followed by tab. You should see the code above appear in the code editor. This easy shortcut will save you tons of typing, but you can make it even more useful!

You can have the snippet turn the name of the method into an editable field when the code is inserted. This is very easy to achieve again using the Snippet Editor. Simply return to Snippet Editor, select the name of the method in the code field and click the plus button in the lower frame. You could give the field another id, default value or specify a tooltip, but none of this is necessary. Just save the snippet and try it again in the Visual Studio code editor. When the code appears, you will notice that TestThat is now an editable green field. Just type tm then tab, type the name of the method, press enter and there you have it, a brand new test method for a fraction of the keystroke cost!

Monday, September 21, 2009

On why I choose to invest in clean code

Lately there is a lot of talk about "Clean Code". This is in part due to Robert Martin's recent book by the same name. I've heard people come up with idealistic reasons to embrace clean code practices. That all well and good, but when you're face with a team who does not share your conviction, this can be difficult.

Why should I invest in clean up code if I cannot keep the whole of the code pristine?

Well I continue to write clean code and to re-pass the broom over the same floors I have previously swept because if I dont it will deteriorate into a real bordello.

I continue to clean up because every effort I make to figure some tangled mess out is an effort I do not want to repeat later. The two hours I spend trying to figure out the purpose of a dozen poorly-named classes are hours I do not want to re-live. The next time I pass through this code I want my previous insights to jump out at me, not hide behind the same mess I dug through last time.

I continue to clean up along my path because I hope that the next person (however clean-conscience they may or may not be) does not get slowed down by the previous mess. This person is my team-mate, and the success of my current commitments is dependent on them. Anything I can do to save them wasted time benefits me.

I continue to write clean code and clean up the problems that cross my path because that same team-mate may waste my precious time asking me questions that I could otherwise have answered directly in the code.

This seemingly futile exercise in clean up is all geared at saving me wasted time on a daily basis.

Why do I chose to invest in clean code? Because I'm lazy.

Thursday, September 3, 2009

On abstracting out static contexts

Any test favoring developer will tell you singletons are the bane of testability. Static contexts make testing difficult. When dealing with legacy code, we are often faced with the problem of testing around such problematic coupling. I've had enough opportunity to dable in such code to have developed some strategies in dealing with coupling. In this post I'll present a strategy I refer to as abstracting out singletons.

For the purpose of discussion I present the following code fragment:

public class TightlyCoupled {
 public void quickPurchase(String customerReferenceNumber, 
    int productCode, int quantity) {
  CustomerCatalog customers = CustomerCatalog.getInstance();
  Customer purchaser = customers.find(customerReferenceNumber);
  if (purchaser == null)
   throw new UnknownCustomerException(customerReferenceNumber);
  OrderItem requestedItems = Inventory.getInstance().take(productCode, quantity);
  Order quickOrder = new Order(purchaser);
  quickOrder.add(requestedItems);
  // ...
 }
}

This code is displays the symptoms of coupling that clearly make testing difficult. Can the inventory and customer catalog be easly programmed to behave in a predictable and testable manner? Your answer will be contextual, but often they cannot. In most enterprise application such singletons will bootstrap the initialization of other singletons as well as database connections. Can these services be easily mocked? Doubtful.

I have seen cases where programmers will allow themselves to override the singleton before the test scenario. This works, but does not help to move away from the current programming model.

What we want is to be able to provide an alternate implementation of these services to a constructed instance of the class under test (CUT). The problem with using a dependency injection approach to testing is that most applications developed with singleton spread are rarely blessed with an IoC container to facilitate object construction. Consequently we can rarely allow ourselves to remove the default constructor of the CUT.

So the first thing that I propose is that we consider using a DI approach, and in order to support this we provide two constructors for our CUT: one that allows for the injection of the dependencies, an a default constructor that wires the class with the default dependencies. This quickly leads us to something like this:

public class LessCoupledThroughConstructor {
 private CustomerCatalog customers;
 private Inventory inventory;

 public LessCoupledThroughConstructor(
   CustomerCatalog customers,
   Inventory inventory) {
  this.customers = customers;
  this.inventory = inventory;
 }

 public LessCoupledThroughConstructor() {
  this(CustomerCatalog.getInstance(), Inventory.getInstance());
 }

 public void quickPurchase(
  String customerReferenceNumber, 
  int productCode, int quantity) {
  Customer purchaser = customers.find(customerReferenceNumber);
  if (purchaser == null)
   throw new UnknownCustomerException(customerReferenceNumber);
  OrderItem requestedItems = inventory.take(productCode, quantity);
  Order quickOrder = new Order(purchaser);
  quickOrder.add(requestedItems);
  // ...
 }
}

So now our CUT can be passed a test friendly set of dependencies with a minimal impact on existing code. What's more, if the CUT is normally treated as a singleton also, its default constructor can become private, and its instance accessor would not take any dependencies. The test friendly constructor would remain public.

This approach has one drawback. When working on a legacy system that relied heavily on singleton accessors to initialize its services, I quickly discovered that many of these services had developed a kind of magical initialization order. No one knew for certain what that order was, but many bugs in the system were to it. This minor adjustment I proposed broke the initialization order: the dependency services where initialized in the constructor, and not on first use in the using method. Ka-boom!

No problem. The solution is to introduce a minimal amount of abstraction. I decided to creation some wrapper services. These services delegated operations to the static context on a per-call basis, but where not singletons or static instances themselves. This produces the code bellow:

public class LessCoupledThroughWraping {
 private CustomerCatalog customers;
 private Inventory inventory;
 
 public LessCoupledThroughWraping(
   CustomerCatalogService customers,
   InventoryService inventory) {
  this.customers = customers;
  this.inventory = inventory;
 }

 public LessCoupledThroughWraping() {
  this(new GlobalCustomerCatalogService(), new GlobalInventoryService());
 }

 public void quickPurchase(
   String customerReferenceNumber, 
   int productCode, int quantity) {
  // as previous example
 }
}

To give you an idea of what the wraper services look like:

public class GlobalInventoryService implements InventoryService {
 public OrderItem take(int productCode, int quantity) {
  return Inventory.getInstance().take(productCode, quantity);
 }
}

This approached allows the CUT to define a default set of dependencies, but still provides the possibility to inject dependencies.

These approaches are clearly not good examples of applied TDD, but on large systems that have a great deal of code coupling it is often necessary to introduce such test seams. Gradually a large system becomes split into an IoC container friendly design with well tested components.

Other areas where such a strategies work include all static data, static third party APIs, as well as static platform functinality.

An example that I used recently involves the .NET runtime's “DateTime.Now” which can make testing time dependent behavior unpredictable. My goal was to test that after 10 minutes some condition expired. Obviously I didn't want a test that ran for ten minutes. I abstract out a date and time service and at test time I substitute a date time service on which I can set the desired date and time. This makes testing cleaner and more reliable, and in this last case I only needed to redefine the date/time service's time to jump ahead ten minutes.

What do you think? Have you encountered similar problems? What did you do to work around them?