David Leal shares some thoughts on the documentation process.
Update: Part 2 of the Series: How to Write Living Documentation
If you are a software developer, I hope by now you have realized that you're much more than a "code monkey". If that weren't the case, you'd be translating between a detailed description of a given process, written in natural language, and some programming language that the computer could understand. You'd be a language translator. But you're not. Consider the following:
Often, you begin with a very vague specification (i.e., a story) of a feature you need to implement. You'll probably need to talk to a few people (and first you must determine who you should be talking to) in order to understand exactly what the feature is about, why it's needed, and how it will be used. Sometimes, you'll be given a problem in the form of a solution ("we need to add a field to widget XYZ"). When this happens, you will find that you need to work backwards from the solution in order to understand what the real problem is. In this way, you gain the ability to evaluate the solution that was originally proposed.
Once you have the required information, and you have determined you’re the one who should be building this feature (since it’s possible that another teammate is in a better position to build it) you must consider each possible solution (including the original solution-problem, if you were given one). You need to ask some questions:
- What are the inputs? What needs to happen? Are there any corner cases?
- How does the new feature integrate into the existing application?
- How does it affect existing functionality? How complex is it?
- How big is it?
- Does performance matter here?
- And finally, which of these questions are even important for this problem?
Sound familiar? Here's another thing that will be familiar as well:
None of this involves writing code.
This process involves thought and communication--essential ingredients of problem solving--but not code. We are not just software developers, we are, first of all, problem solvers. In fact, we solve some of our problems by deciding not to write code at all (and I'd argue those are the best solutions).
Of course, you can decide you don't need to do any of the above, and you can jump straight into coding.
Weeks of programming can save you hours of planning!
I can vouch for that.
To document, or not to document
Let's say you're one of those people who haven't yet seen the light, so you actually go through the trouble of thinking things through. How do you do it? Maybe you think a little, sketch a little, write a little, repeat, until you reach an acceptable solution. What happens to that output? Do you simply discard it, or leave it buried in whatever project planning tool you use, and start implementing? Maybe you believe code is the design, and therefore, that it is the only thing that's really necessary?
Is code design? Well, yes and no. First, code may be design and, in theory, code is all that's needed for an application to work, and for you to understand how it works. But code only tells you how things work. It doesn't tell you why they should work the way they do, or how they are actually supposed to work. So, even if code is design, that design alone is insufficient.
Second, think about people that are new to the application (or you, coming back to a certain area of the code after a long time away from it). It's very hard to get an overall idea of what a feature does (much less an application!) by simply looking at the code. It's like trying to understand how a machine works by looking at each part separately. You can do it--in theory--but it will take you a long time.
So, I hope we agree that some documentation, at least, would be useful. But we all know what happens to documentation. Documentation starts losing its value the minute it's added, just like a new car loses value the moment it's bought. It decays if you don't keep it current. Worse, given its potential to mislead innocent developers, it may be more harmful to have documentation that is out of date than having no documentation at all.
Wouldn't it be great to have documentation which you know you can rely on, because it actively encourages you to keep it up to date?
Living documentation is documentation that is backed by tests. For that reason, it’s much harder for it to become outdated, as regular documentation does. Here's an example meant to be executed by Cucumber, a popular living documentation tool:
Feature: Photo displayA photography site is all about photos, and the biggerthey are, the better. If we limit the text content, wecan use the entire background area to show a single photo.Due to time constraints, we're not building a dedicatedphoto gallery yet, but we must give people a chanceto see more photos, using a very simple navigation systemthat uses "back" and "forward" links, like a manuallyactivated slideshow.Scenario: photo shown on the homepageWhen a visitor visits the homepage multiple timesThen they should see a different photo each timeScenario: photo navigationWhen a visitor is looking at a photoThen they can choose to see the photo that follows itAnd they can choose to see the photo that precedes itScenario: photo navigation beyond last photoWhen a visitor tries to see the photo that comes afterthe last photoThen they should be shown the first photo in theslideshow instead...
These are the basic components of a living document:
- The feature name
- A quick overview--why the feature exists, what problem it solves, what alternatives you explored, etc. Whatever you believe to be relevant for people reading the feature documentation.
- Some people use the known story format, "As a ... I want to ... so that ...", others prefer a free-flowing format.
- A series of scenarios, describing several aspects of the feature. They are written in a slightly constrained format--each line must start with one of .Given, When, Then, And and But
Did you notice that there's no code in sight? We have a perfectly readable document, written in a natural language (albeit with a slightly more constrained format), which we can show to stakeholders (if they are willing to read it), but above all, to fellow team members. This and other documents like it, properly organized, will form the basis for understanding what the application does, and why. Use it to define the team's shared vocabulary. Use it to recall functionality that you had previously forgotten. Export the whole suite to PDF and give it to a new team member to read.
Why not use a lightweight spec framework to write the documentation?
You can use a spec framework (like, RSpec, or Capybara's feature DSL) to practice a kind of limited literate testing, but that approach comes with a few drawbacks. Compare the Gherkin version:
Feature: Background picture displayScenario: show random background pictureWhen a visitor visits the page multiple timesThen they see a different background picture each time
And the RSpec version:
describe "Background picture display" docontext "When a visitor visits the page multiple times"it "They see a different background picture each time" doendendend
There are a few important differences from the first case to the second:
First, the Gherkin version has much less noise than the RSpec version. There are
Second, this is not the time to be thinking about code! You should be focusing on the business rules. You'll probably want to clarify your thoughts by rewording things a bit, move some steps around, tweak the terms used to better fit the domain. The more rigid structure of the RSpec example makes that harder to do. Text is easier to manipulate than code.
Third, it's harder to read. It mixes code and business rule descriptions. If you export just the business rule parts, you are still unable (as far as I know) to export comments supplementing the business rule descriptions.
In this article, I tried to convince you to step away from the code a bit, and give some consideration to higher level issues. In future articles, I plan to explore in more depth what living documentation is about, show some complete examples, and some suggestions for an effective workflow.
It's time we start giving code the relative importance it has. Code is the way to talk to very stupid machines. It is less ambiguous, but also less flexible and less expressive.
Nothing compares to the power of human language. Put it to good use!
They Write the Right Stuff: There are many gold nuggets in "They Write the Right Stuff", but the one that initially impressed me the most was seeing the impact that a properly specified system had on the quality of the code
Hammock-Driven Development: Rich Hickey has been an inspiration for me ever since I first saw Simple Made Easy. This talk is about the process that underlies coming up with robust solutions to the problems we face as software developers.
Solving Cucumber's Problems: Jonas Nicklas briefly discusses some of the problems of the code-all-the-things approach.
If you feel this strongly about documentation we probably want to hire you.