Of Dictionaries and Tables : Why your Domain Specific Language needs a Dictionary

dictionary

Searching for the right word

Imagine you are a product owner, inspired to write the requirements for a new feature using this new-fangled SpecFlow that your team is keen for you to use.  You start typing ...

new-feature

And then you are seized by doubt.  Is it Order Number or Order No.?  Maybe Order #?

And then, muttering something about how you wish people could just standardise their terminology, it occurs to you that you also don't recall whether orders have a Status or a State.  In fact, do orders have a state, or is that a property of a Shipment?

You resolve to run what you have .... you haven't got to the bit where you describe the new functionality, so this should just work.

exception.PNG

You get an IndexOutOfRangeException....  What the ...????

You reach for the start menu, launch Microsoft Word and start typing requirements the good old-fashioned way.

Searching for the right word (take two)

Imagine you are an author, reaching the end of your magnum opus.  You re-read your final paragraph: it's perfect. But wait a moment, have you used that word in the correct sense?

You reach for ....

A Dictionary

"The greatest masterpiece of literature is only a dictionary out of order"

- Jean Cocteau

Turning the Tables

The table is a wonderful way of forcing some structure and clarity on a requirement.  However, in SpecFlow the table is not checked until run time and there is no easy way of knowing in advance what columns a given step definition supports or requires.

We might offer one of two solutions to our reluctant product owner.

  1. "Go read the code"
  2. Here's a word document (you seem to like those) with all the tables defined

Option 1 at least has the benefit of not involving any up-front investment.  Unfortunately, if you don't meet your product owners and business analysts half-way in making it easy for them to write SpecFlow then they'll be back to Microsoft Word before you can say Badly-Written-Specification-Driven-Development (BWSDD).

Option 2 doesn't even have the benefit of being cheap.  You spent money producing it and it will be out of date within weeks.  Many of us will have had a "My First Dictionary" as a child, but we don't refer to it any more. A dictionary that is missing words (or indeed one with out-of-date definitions) is about as useful as .... IndexOutOfRangeException.

With Annotations

Suppose I wrote my step definition like this...

annotated-step-deg

I've annotated my step definition with the names of the columns in the table (and indicated which are mandatory/optional).

The method CheckTable compares the supplied table against these annotations and if mandatory columns are missing, or a column is supplied that is not recognised, then it prints out a nice friendly message saying which column is incorrect and then tells the user what is supported/required.

You don't need to write any more code to check tables; you just annotate your step definitions.  

You need only implement this table checking code once and then you can re-use it in all your step definitions, in all your projects.

Implementing it is going to require a bit of reflection (in both senses of the word), but should be easy for any competent developer.

And writing a new Dictionary every night

If all of your step definitions are annotated in this way, then why not auto-generate documentation (a dictionary) from the code?  Here's an example from one of our clients...

An HTML report generated (nightly) from the step definitions.  Guaranteed to be up to date. Guaranteed to be book-marked as a favourite by your product owners and business analysts...

In fact, why not go one step further and include a bit of documentation about what each step does and how to use it?  From a different client (with a different colour scheme!)...

Again,  you only need to write this code once.  Our version spits out XML and we use XSLT to transform to HTML, in case we need to make client-specific tweaks (e.g. the desire for nauseating orange).

I like to stress the importance of nouns in designing a DSL (see "those three little words (or how to design a specification language)") so I also annotate my steps with the noun to which they relate.  This then allows me to naturally group step definitions together in my output; alphabetical order might work for a dictionary but your step definitions are probably going to need a bit more structure.

And update your CV

To say "Developer and lexicographer" ...which Samuel Johnson defined as

"A writer of dictionaries; a harmless drudge that busies himself in tracing the original, and detailing the signification of words."

But you did it without the drudgery.