Summary
I just read a good introduction to what is arguably the most important part of the agile development process, when it comes to quality. It does a good job of explaining that the real goal is not to “test” your code after you write it, but rather to create a “runnable specification” before you write it.

Advertisement

Designing Programs with RSpec and Cucumber gives a good introduction to what is arguably the most important part of the agile development process, when it comes to quality. It does a good job of explaining that the real goal is not to “test” your code after you write it, but rather to create a “runnable specification” before you write it.

Note:
Ruby’s RSpec just happens to be my favorite tool for that. And while the “R” in RSpec is generally taken to mean “Ruby”, I like to think of it as a Readable, Runnable, Reviewable Specification. So I’ll use the term “RSpec”, regardless of which tool is used to create one.

Like any specification, an RSpec is something you create before coding. Because it is a specification, it is readable. You can skim down the page to see how the API works. It doesn’t give the “big picture” that good API documentation can provide, but it does a better job of describing the details, particularly in corner cases that API docs generally leave out. For example: What happens if you pass zero, -1, or null? Does the program crash? Do you get an exception? Do you get a return value? If so, what is it?

But because an RSpec is also runnable, it is in effect a unit test, ensuring that the implementation matches the specification, and that it continues to match the specification in future iterations, thereby preventing regressions.

In addition, as Martin Fowler pointed out so well in his seminal work on Refactoring, a comprehensive test suite lets you refactor with impunity, secure in the knowledge that the new version will work exactly the same as it did before. The highly desirable result is that you can engineer elegance into the product, instead of watching bug-fix entropy reduce the original beautiful design into a wad of ugly patches.

Of course, you only get that kind of confidence when your test suite is comprehensive--and you only get that kind of comprehensive coverage when you write them first, as part of the specification process.

But here is the key point, that needs to be written in flaming letters, ten feet tall:

Because an RSpec is readable, it can be reviewed--before the code meets the road.

That is a key thought, because early specification review is liable to turn out to be a key component of product quality.

It has long been known the early design reviews are the single most significant predictor of project success. It makes sense. If the basic design is good, then fixes will be limited to correcting oversights and making minor tweaks. But if the design is flawed, any bug could be the one that sends the developers back to the drawing board for the kind of costly redesign that imperils a project.

Ongoing specification reviews, on the other hand, are likely to be an even more significant indicator of project quality. For example, when writing a routine to convert a path to a URL, it was pretty easy to come with a couple of dozen variations that the API could possibly handle, where the input could contain forward or back slashes, absolute or relative paths, paths with "up" (..) or "here" (.), as well as paths with URL prefixes like http:// or ftp://.

It didn't make sense to code for all of those cases, of course. That's where the "engineering" part of software engineering came into play: Deciding which cases were important enough to handle. But the fact that the cases were enumerated at all was a significant determinant of quality.

For one thing, it was possible to document which cases were covered and which weren't. That documentation made it possible for reviewers to see exactly how the implementation worked, identify corner cases that might have been overlooked, and lobby for implemenation of cases they might otherwise have been deferred indefinitely. And, of course, the fact that the specifcation was runnable ensured that the specification was 100% accurate, and that it remained so as the implementation evolved.

It was a small case, but it illustrated the potential benefit of "specification review"--as long as those specifications are (a) easy to write, (b) easy to read, and (c) runnable. If every significant API in an application is subject to such peer review, there is no doubt that reliability will improve significantly.

RSS Feed

About the Blogger

Eric Armstrong has been programming and writing professionally since
before there were personal computers. His production experience includes artificial intelligence (AI) programs, system libraries, real-time
programs, and business applications in a variety of languages. He works as a writer and software consultant in
the San Francisco Bay Area. He wrote The JBuilder2 Bible and authored the Java/XML programming tutorial available at http://java.sun.com. Eric is also involved in efforts to design knowledge-based collaboration systems.