Part of my Agile Requirements series.
I've written about A Vision for Fit in the past. What I haven't talked about is how to use Fit on a day-to-day basis. In this essay, I'll fill in the gap.
What I'm about to describe isn't the only way to use Fit. We're all still learning too much about the best ways to use Fit to have any final answers. Rather than calling it a "best practice," I'll call it my "favorite practice."
My Old Way
When I first started using Fit, I used it in the same way I use test-driven development. I would write some examples in a Word document, get one to pass, refactor, move on to the next example, etc.
I encountered a big problem with this approach, though: I stopped doing good TDD. "Storytest-driven development" blurred the line between Fit and unit tests. The "STDD" cycle largely replaced the TDD cycle and, as a result, I had far fewer unit tests than normal.
That was a problem because Fit examples are not unit tests. Fit examples are just that: examples of a business rule in action, from a business perspective. In TDD, I write tests for every line of code that can possibly break. In my Fit examples, I try to talk about every possible business case. That's a bigger net than TDD, and without TDD, my code wasn't well tested.
As I refactored my code and changed my Fit documents, the holes in my tests became increasingly obvious. I lost confidence that my code was being tested. Also, today's refactoring tools aren't aware of Fit documents. Changes started to become painful.
Since then, I've switched to another approach. Now I draw a very sharp distinction between Fit and TDD. I use Fit at a higher level than TDD. If TDD is "red-green-refactor," then my use of Fit ("Example-Driven Requirements?") is "describe-demonstrate-develop." The "develop" step includes all of TDD.
Describe. In the Fit document, use a short paragraph to describe part of the functionality that the software supports. (This should be done by business experts.)
Demonstrate. Provide some examples of the functionality, preferably examples that show the differences in possibilities. Sometimes only one or two examples is enough. (This should be done by business experts, too, possibly with help from testers and programmers.)
Develop. Develop the functionality using TDD. Use the structure and terms of the examples to provide direction for the domain model, per Eric Evans' Ubiquitous Language. Turn each kind of concept in the examples (such as "Currency") to drive the creation of new types, per Ward Cunningham's Whole Value. (This should be done by programmers.)
Don't run Fit during this stage until the small increment of functionality is done. When it is, create the Fit fixture and hook it up. Use your Whole Value classes rather than primitive types. When you run Fit, the examples should pass.
Repeat. Continue with the next section of the document. Often, the business experts can go faster than the developers and finish several more Describe/Demonstrate sections before the programmers finish Developing the first section. That's okay and I encourage that they do so. There's no need for the business experts to wait for the programmers to finish Developing a section before the business experts Describe and Demonstrate the next one.
As you expand the Fit document, you should see opportunities to reorganize, change, and improve sections. Please do. You'll end up with a much better result.
What's the difference between a "best practice" and a "favorite practice?" Favorite practices aren't always appropriate. (That's why I detest the term "best practice." Nothing is always "best" in software development.)
In the case of describe-demonstrate-develop, I'm assuming a bunch of things. I'm assuming that you're using Fit to drive discussion about your domain, as I discuss in A Vision for Fit and Fit Workflow. I'm assuming that your business experts, not your testers or programmers, are providing the majority of the Fit direction and examples. I'm assuming the presence, and primacy, of a domain model. (See Evans' Domain-Driven Design book for an expert description of domain modeling.) I'm assuming that Fit is being used primarily as an aid for discussion and design of domain logic rather than for user interface or database code.
Under these conditions, I've found describe-demonstrate-develop to work very well. Sam Gentile agrees: "In this iteration, it was the FIT tests that sort of forced business and development into long, fruitful discussions that fleshed out what it is we are really wanting as well as designing. And it was so much more than anyone thought. There were tremendous amounts of details in there that no one knew about until we tried to write the FIT tests." (But Sam, call them "examples," not "tests!" We need to spread the word that Example-Driven Analysis is about communication, not testing! ;-) )
Describe-demonstrate-develop may be appropriate outside of these assumptions, too, but I haven't tried it.
Elaborating on a Theme
The above approach also assumes a particular way of structuring a Fit document that I seem to have invented (or re-discovered, or something). I guess you could call it "elaborating on a theme." In this approach, you start with a concept and describe the most basic case (with a few examples). Then you describe one special case or additional detail (with a few more examples). Then another. Then another. In the end, you have a large section of a document with perhaps five paragraphs (depending on how much detail you need to provide), each with its own small set of examples. Each paragraph is built during the Describe step and the paragraph's small set of examples is in the Demonstrate step.
You can see this approach in action in the Fit Specification which is part of the Fit download. Check out parse.html for the best example. (In the Java and C# versions, you can find it in the 'spec' directory.) Here's exactly what it says, with the examples trimmed so you can see the flow:
HTML Document Parsing
Fit parses the tables from HTML documents into a data structure. For example, in the following table, raw HTML is shown on the left and Fit's view of the HTML is shown on the right. (Table cells are in brackets, rows are per line, and tables are separated by dashes.)
Everything but table structure and cell contents are ignored. The ignored portions are preserved so they can be output again later, exactly as they were read in.
Even whitespace is preserved.
The colspan and rowspan attributes of table cells are also ignored, but jagged tables (tables with a varying number of cells in each row) are okay:
Tables that are missing "table," "tr," or "td" tags generate an error.
Tables containing unclosed "table," "tr," and "td" tags also generate an error.
However, excess closing tags don't generate an error.
HTML mistakes that aren't related to tables are ignored.
You can see above how I'm taking a theme and elaborating on it: "Fit parses HTML tables. (example) Here's what we do about everything else (example). We deal with rowspan and colspan attributes (example). We deal with malformed HTML (further detail, example, detail, example, detail, example, detail, example)." I describe overall feature of HTML parsing by starting with the most basic case and expanding, detail by tiny detail, until the complete picture is visible.
With the describe-demonstrate-develop approach to developing with Fit and the "elaborating on a theme" approach to structuring Fit documents, it's very natural to take a single section, use TDD to develop it independently of Fit, then return to Fit to see the examples turn green. Fit operates one level higher than TDD, steering overall development and using TDD to drive the detailed design, coding, and testing.
As I look back, I realize that I've now closed the circle on a pretty substantial cycle of essays on agile requirements. I now cover everything from planning months of releases down to how to write a single section of Fit document, the work of an hour. Pretty cool. (Hey, wait! Shouldn't I demand big bucks for this stuff?)
- Beyond Story Cards describes how I prefer to handle requirements over the course of developing an entire software product.
- Fit Workflow describes how I use Fit to facilitate collaboration on requirements during a single iteration.
- A Vision for Fit gives a concrete example of using Fit to facilite collaboration.
- Describe-Demonstrate-Develop describes how I prefer to develop the Fit document, fixtures, and how actual software development comes into play.
- "Elaborating on a Theme" describes how I structure Fit documents and their examples.
It's working well for me and the teams I work with. Try it yourself and let me know what you think. My email is at the bottom of the page.