Skip to main content

Sustainable TDD Review - ACCU London February 2010

I always say this and I'll say it again: London is a long way to go from Norwich for the evening. On this occasion it was worth it, as it always is for ACCU London. This dark, cold, late February evening had the added drawback of torrential rain. To make matters worse, while looking for the JP Morgan building at 125 London Wall, we got to the junction of Moorgate to find a sign suggesting we had been walking in the wrong direction. With faith in a printed google map and iPhone GPS we forged on another fifty yards and found 125 London Wall exactly where we expected.

I have been in many offices belonging to a number of financial corporations and JP Morgan is no different to any of them, except for the lifts! Instead of calling the lifts by pressing a button next to them, you have to go to a set of small screens in the middle of the lobby. On one of these screens you select the floor you want and it indicates which lift you have to get in. The assigned lift then opens and takes you to the selected floor. Being a techie I couldn't help thinking how cool this was, but I did find myself wondering what you would do if you changed your mind about which floor you wanted once in the lift. We ascended 17 floors in what didn't feel like not enough time. However the view form the window confirmed just how high we were.

Test Driven Development (TDD) and the benefits it brings are well understood by most software developers and even most companies and managers. Still, every year at the ACCU conference someone does an introductory presentation on TDD. So, I was intrigued when I read about Steve and Nat's presentation on Sustainable TDD as it sounded like the next step.

Steve Freeman and Nat Pryce have a book to sell: Growing Object Orientated Software [1]. Their presentation was based around one section of the book. It was only about 45 minutes long, but there was a fairly long discussion after. During the initial 45 minutes Steve did the majority of the talking and took us through some simple techniques that would improve the readability and maintainability of unit test code.

Steve started off by showing us some lengthy, quite messy unit tests of the sort we have all probably seen or even written at one time or another. Then there were some examples and discussion of how to name test methods effectively. Instead of naming test methods after the method under test we should give them names that describe what is being tested. For example:

holdsItemsInTheOrderTheyWereAdded()
canHoldMultipleReferencesToTheSameItem()
throwsAnExceptionWhenRemovingAnItemItDoesntHold()

The problem with “magic numbers”, literals used directly in code, has been understood for some time, but as Steve explained they still get used in test code, so we should try to use self describing variables instead. For example:

final static Chat UNUSED_CHAT = null;
final static int INVALID_ID = 666;

Often tests require one or more complex objects to be constructed before the test can be carried out. This setup code can often be very verbose:

Order order = new Order(
new Customer("Sherlock Holmes",
new Address("221b Baker Street",
"London",
new PostCode("NW1", "3RX"))));
order.addLine(new OrderLine("Deerstalker Hat", 1));
order.addLine(new OrderLine("Tweed Cape", 1));

The verbosity can be reduced by using a builder, similar to those described in item 2 of Effective Java [2]:

new OrderBuilder()
.fromCustomer(
new CustomerBuilder()
.withAddress(new AddressBuilder().withNoPostcode().build())
.build())
.build();

Steve described quite a few examples of how you might use builders to repeatedly build test objects with different properties. Although this technique could be useful, it would only be where you have a large number of objects to construct or a number of different permeations of a single object that takes a large number of parameters.

Steve then went on to describe a technique that I consider a little controversial. He suggested that the message parameter of JUnit's asserts should be used to help diagnose the problem when a test fails. For example:

assertEquals("balance", 16301, customer.getBalance());

This to me is tantamount to using comments. Here, someone could change the test to test something else and not bother to update the message. However, in simple assertions like this with one word descriptions this is unlikely and the message is is likely to be very useful.

Then Steve explained something that appealed to my colleagues and I as pure genius in its simplicity and potential usefulness:

Date startDate = namedDate(1000, "startDate");
Date endDate = namedDate(2000, "endDate");

Date namedDate(long timeValue, final String name) {
return new Date(timeValue) {
public String toString() { return name; }
};
}

Here if an assertion involving startDate or endDate fails, instead of the actual date being reported:

java.lang.AssertionError: payment date
Expected: [Thu Jan 01 01:00:01 GMT 1970]
got: [Thu Jan 01 01:00:02 GMT 1970]

you get a description of the date:

java.lang.AssertionError: payment date
Expected: [startDate]
got: [endDate]

I think the potential usefulness of this technique speaks for itself.

Discussion continued and Alan Stokes pointed out that only code with unit tests should be refactored and asked how you therefore refactor test code, as it has no tests. The answer was that you first break your production code so that the tests fail, refactor the test code making sure it still fails and then fix the production code and make sure the tests still pass.

Those were the highlights of the presentation for me, although Steve and Nat did cover some other techniques and examples. It was certainly enough for me to buy their book.

References

[1] Growing Object Orientated Software by Steve Freeman and Nat Pryce, ISBN-13: 978-0321503626

[2] Effective Java by Joshua Bloch, ISBN-13: 978-0321356680

Comments

Popular posts from this blog

Write Your Own Load Balancer: A worked Example

I was out walking with a techie friend of mine I’d not seen for a while and he asked me if I’d written anything recently. I hadn’t, other than an article on data sharing a few months before and I realised I was missing it. Well, not the writing itself, but the end result. In the last few weeks, another friend of mine, John Cricket , has been setting weekly code challenges via linkedin and his new website, https://codingchallenges.fyi/ . They were all quite interesting, but one in particular on writing load balancers appealed, so I thought I’d kill two birds with one stone and write up a worked example. You’ll find my worked example below. The challenge itself is italics and voice is that of John Crickets. The Coding Challenge https://codingchallenges.fyi/challenges/challenge-load-balancer/ Write Your Own Load Balancer This challenge is to build your own application layer load balancer. A load balancer sits in front of a group of servers and routes client requests across all of the serv

Bloodstock 2009

This year was one of the best Bloodstock s ever, which surprised me as the line up didn't look too strong. I haven't come away with a list of bands I want to buy all the albums of, but I did enjoy a lot of the performances. Insomnium[6] sound a lot like Swallow the Sun and Paradise Lost. They put on a very good show. I find a lot of old thrash bands quite boring, but Sodom[5] were quite good. They could have done with a second guitarist and the bass broke in the first song and it seemed to take ages to get it fixed. Saxon[8] gave us some some classic traditional heavy metal. Solid, as expected. The best bit was, following the guitarist standing on a monitor, Biff Bifford ripped off the sign saying "DO NOT STAND" and showed it to the audience. Once their sound was sorted, Arch Enemy[10] stole the show. They turned out not only to be the best band of the day, but of the festival, but then that's what you'd expect from Arch Enemy. Carcass[4] were very disappoin

Catalina-Ant for Tomcat 7

I recently upgraded from Tomcat 6 to Tomcat 7 and all of my Ant deployment scripts stopped working. I eventually worked out why and made the necessary changes, but there doesn’t seem to be a complete description of how to use Catalina-Ant for Tomcat 7 on the web so I thought I'd write one. To start with, make sure Tomcat manager is configured for use by Catalina-Ant. Make sure that manager-script is included in the roles for one of the users in TOMCAT_HOME/conf/tomcat-users.xml . For example: <tomcat-users> <user name="admin" password="s3cr£t" roles="manager-gui, manager-script "/> </tomcat-users> Catalina-Ant for Tomcat 6 was encapsulated within a single JAR file. Catalina-Ant for Tomcat 7 requires four JAR files. One from TOMCAT_HOME/bin : tomcat-juli.jar and three from TOMCAT_HOME/lib: catalina-ant.jar tomcat-coyote.jar tomcat-util.jar There are at least three ways of making the JARs available to Ant: Copy the JARs into th