Sunday, August 31, 2008

Test Driving the "Money" example

The other day, I demo'ed Kent Beck's "Money" example in a Lunch and Learn session.

Even though participation was very thin (for a variety of scheduling challenges), the people who did attend found the session useful. This was heartening.

I test-drove the "Money" example equivalent to the first 11 chapters of Kent Beck's book [1]. There were some variations: I added a test-for-instanceof-based-equality, asserting that a ClassCastException was thrown when Dollars were compared to Euros. Later, when the instanceof operator in the equals() method was replaced with the domain concept of "currency", I test-drove this change by modifying the test-for-instanceof-based-equality to a test-for-currency-based-equality. This new test asserted that no exceptions were thrown when Dollars were compared to Euros.

The other variations dealt with the natural ebb and flow of the demands of an eager (though small) audience: I took detours -- even to dead-ends -- to answer questions and demonstrate principles. I allowed the audience to direct some of the refactorings: we replaced the calls to Dollar() and Euro() constructors with calls to factory methods in Money class much earlier than in the book, based on their familiarity with the principle of separating creation of objects from their usage. And, of course, I made the example more contemporary: I replaced Francs with Euros. This latter change had the effect of inverting the exchange rate from 1 Dollar = 2 Francs (in the book) to 2 Dollars = 1 Euro; which is a fairly close approximation of current reality.

The feedback from the small audience was generous: it was mostly 4's and 5's (on a 5-point scale, 5 being highest). I would have liked to do it differently (and hopefully better) in the following ways:

1. Test Driving all the way to the end of the Money example. This corresponds to chapter 16 (chapter 17 is the retrospective). I believe I'd have needed about 20 more minutes to do these five remaining chapters.
2. Demonstrating code coverage more often. I switched to the Eclemma coverage window not often enough.
3. Being more deliberate and thoughtful (rather than speedy and mechanical) in test-driving some of the changes.

I do realize that even the items on this short wish-list have built-in conflicts. But then, crafting software is all about finding serene compromises amongst conflicts.

[1] Test-Driven Development By Example, by Kent Beck

No Integration Without Representation

This article is not about the European Union.

Much has been written about the dangers of integrating software components late in a project. "Late" could mean "not at the first opportunity", "not after every working change to every module" or "closer to the product's deployment date than the project's commencement date". Any definition suffices for the purpose of this article.

One reason that exacerbates late integration is that not all the software systems that need to be integrated with the system-under-development (SUD) are known in advance. This problem is (in software terms) ancient, and apparently bit the first XP project -- "end to end is farther than you think". [1]

It is always going to be difficult to a priori enumerate the complete list of software systems with which a given SUD is going to integrate. And such a list would be an evolving artifact, anyway. So how do we continually determine with which systems our SUD is expected to integrate?

One way is to make this apparent by representation. Most iterative teams regularly present their evolving product to the customers and stakeholders -- usually at the end of each iteration. This is a natural junction where integration points with other systems can be demonstrated.

How do we know if we're missing some key integration point(s)? Expand the membership of the "iteration showcase" meeting to representatives of external system who might have an integration point. It may seem chaotic to invite too many people to an iteration showcase, but in practice this works out well. Quite often, such "chickens" either quickly transmogrify into "pigs" or leave the roost.

The foil to this wishy-washy "come if you're interested, don't if you aren't" is the statement "you probably are interested if you use an application that consumes data from or provides data to this SUD". I like to condense this to the pithy "no integration without representation".

Explicitly proclaiming that the SUD will integrate with all (and only) the applications whose stakeholders are represented has a self-correcting effect on guiding the integration points. Of course, encouraging, enabling attendance, and welcoming the representatives who might have an integration point are all necessary to the correct usage of this pith.

[1] See the "Creation Story" in Extreme Programming Explained by Kent Beck.