mumble test business rules mumble

03 Aug, 2005

The following is lightly-edited copy of an email I sent to the Fit-devl mailing list.

At the Fit Summit last Friday, I kept beating the same drum over and over: I said that declarative tests using ColumnFixture were a more effective use of Fit than imperative tests using flow-style fixtures like ActionFixture and DoFixture. My call to "test business rules!" at the summit may have been a little strident. :-) Now that I can take some extra time to phrase my thoughts, I'll explain further.

As I said at the summit, I think Fit's unique value is its ability to enhance collaboration between business experts and programmers. The automated testing--or, as I prefer to think of it, the automated feedback--is an important part of that value.

As I've worked with business experts, I've noticed--as I'm sure everyone has--that their default mode of thinking is a flow style. When I ask for an example of their thinking, they tend to answer with, "we do this, then the machine does that, then this happens, etc." In other words, a flow-style example.

So why don't I just go with the flow? (heh.) If Fit's unique value is to enhance collaboration, and if business users think in a flow style, what's my problem with flow-style examples?

I have several reasons.

Problems with Flow

First, I think flow-style examples tend to sidle around the essence of the problem. In many cases, they show the effect of some underlying business rule. I would rather have examples that illustrate the business rule directly.

Second, I've found flow-style examples to be verbose and difficult to understand. They take up a lot of space, but much of it is boilerplate. It takes extra time to understand what's being demonstrated. One single row of a ColumnFixture can turn into a complete table with multiple rows in an ActionFixture or DoFixture.

Finally, flow-style examples tend to lead to duplication. Each example often has similar set-up and tear-down requirements. There can be repeated checking logic as well.

Domain-Specific Imperative Languages

I'm going to change the subject for a moment. Every time I've worked with a domain-specific imperative language--that is, your average "little language"--I've cursed the developers for their shortsightedness. Why didn't they put in proper loops? Or variables? Or subroutines? How come recursion isn't possible? Why do I have to jump through these awkward hoops to have one variable reference another? Etc.

Okay, back on topic. With flow-style fixtures, we have made a domain-specific imperative language. As we discover the limitations of that language, we are adding more and more features. FitLibrary and FitNesse added setup-specific subroutines. FitNesse added variables. There was an experience report at Agile 2005 in which they added general-purpose subroutines. Each of these features comes with its own subtly weird idiosyncracies. A pointed example of this was at the summit when "Uncle Bob" Martin was talking about variables in FitNesse. "Which side does the equal sign go on?" he asked. "I can never remember."

I have no doubt that we can overcome these problems. But the result probably won't be any fun for programmers, and I'd bet that it will be absolutely incomprehensible to business experts. A table-based imperative programming language? Signs point to "ick."

We already have fantastic tools for flow-style testing. They have great support for abstractions, variables, and a full programming language environment. I'm referring, of course, to xUnit.

The Future of Fit

Despite my misgivings with flow-style examples, I don't think we should remove them from Fit. In fact, I'm in favor of enhancing what we have. I think we still have a lot to learn about the best way to use Fit to collaborate with customers. Fit can be used for more than demonstrating business rules. I have no doubt that flow-style fixtures will be part of that.

I'm writing this because I'm concerned that the path of least resistance is to use flow-style examples even when other approaches work better. I'm concerned that the default reaction to flow's limitations is to add programming features to flow-style fixtures like subroutines and variables. And I'm concerned that, if we do that, we will turn Fit into a bad programming language.

While I value flow-style fixtures and think they have a central place in the future of Fit, I am concerned about the direction they may take us. I excited about the experimentation people are performing with Fit fixtures and I think we've just barely touched on the possibilities. As we consider things to incorporate into core Fit, I hope we will choose to value approaches that provide new ways of collaborating with business users over approaches that replicate an imperative programming language.