Today, I’ll be diving into alphabet soup of TLA’s. For this I apologize in advance – those TDD guys started it!! First though, a little reminder: Spatial is a software component, rather than an end-user product company. So most of the discussion below is in the context of developing components that will be used by customers in their applications, as opposed to developing applications that will be used by end users to get something done.
For those of you who are unfamiliar with it, TDD stands for "Test Driven Development". It’s a methodology espoused by the agile/extreme community that advocates using unit tests to drive the interface design of your software. A core principle of TDD is that it is a design (as opposed to testing) methodology – the idea is that if you use tests to drive the interface design, then testability is built into the application.
When we started using agile methods in our ACIS product five or six years ago, one of the techniques we adopted was TDD. And over the course of the next few years I began to see a pattern: we would discover while writing the documentation for new functionality that the interface that we’d come up with during TDD often wasn’t quite right. It’s the usual effect of writing things down – only when you’re documenting how a customer is supposed use an interface function do you discover that you only have an 80% understanding of what you want. Writing the documentation down makes you work through the nasty and subtle 20% that’s the hard part, and lets you understand what it was that you didn’t understand when you thought you understood what it was that you wanted. (Understand? :) This led us to the concept of something we called "Documentation Driven Development" (DDD). The idea is that, when putting a new piece of functionality into ACIS, we should write the documentation first. This documentation can then be used to drive the stories, which drive the acceptance tests, which drive the software development (which is where TDD comes in). In retrospect, this is pretty obvious; the alternative of writing the stories before you write the documentation leads to stories that might not be relevant to the actual requirements. Not surprisingly, when I googled for “Documentation Driven Development” yesterday I got a lot of hits – the part in the first one where he talks about writing sample code after the code is written is exactly the same thing we went through.
But wait! There’s more!!!
The same 80/20 argument that I applied to the interface functions above also applies to the documentation itself. The best way to know if your new software component will fulfill the needs of customer applications is to try to write an application against your new software component. This is just the usual "eat your own dog food" principle. In the same way that stories without documentation leads to a tendency to miss the forest (documentation) for the trees (stories), documentation without an application can lead to a set of documented functions which don’t quite fit together when trying to build an app. This led us to generalize DDD to the concept of "Application Driven Development" (AppDD), where a sample application is used to drive development of component software.
Note that nothing above is new. The Wikipedia article on TDD refers to methodologies such as Acceptance Test Driven Development (ATDD) and Behavior Driven Development (BDD); these and a host of others are all pushing the general idea of driving development based on application scenarios. In fact, classic Agile methodology says that the acceptance tests should drive the need for the interfaces that are developed using TDD, and that stories should represent vertical slices. What I think might be new is the following:
When you think in terms of vertical slices (i.e. write a story), the vertical slice needs to extend into your customer’s work environment.
If you’re a developing a software component (such as ACIS), then the story should be "as an application developer, I want to introduce a CreateBlock feature into my application", NOT "as an application developer, I want to be able to call an ACIS function to create a block." If you’re developing a mold-design application named MoldApp, then the story should be "As a user, I want to be able to import a mold I designed with MoldApp into MachineApp, so that the tool paths for cutting the die can be calculated." The best way to do this is to have a sample version of your customers’ environment within your organization, and implement your stories within that environment.
Next time, I’ll talk about how we are applying this principle in our CGM product.