Phillip Trelford's Array

POKE 36879,255

TickSpec: Production Ready

The TickSpec F# Behavioural Driven Development (BDD) project started on CodePlex just over a month ago, and is now in use in production for at least one commercial application. TickSpec executes plain text specifications written in the Gherkin business language against a .Net implementation using reflection and regular expressions (like Cucumber does for Ruby). All English language Gherkin keywords are supported including Background and Examples, along with Bullet Points which are TickSpec specific.

The project now includes support and samples for 3 popular .Net Unit Testing Frameworks:

Screen shot of the MbUnit’s Icarus GUI Test Runner:

TickSpecMbUnit

TickSpec gives the ability to step through plain text feature files in Visual Studio and see the current value of template placeholders of the executing Example:

WinningPositions

Debug support is achieved using Reflection.Emit which executes an IL code representation of the source files at runtime. This allows it to be used from any .Net language, and avoids the need to install a Visual Studio plug-in. Plain text specification files can easily be added to a project as an Embedded Resource.

See TickSpec in action in the following video (includes sound):

 

Yet despite all these features, the TickSpec distribution is still lightweight (<100K) comprising a single standalone assembly (TickSpec.dll). And inside there is support for both C# and F# step definitions using either instance or static methods. So that given the following specification:

Given a bullet list of:

  • 1
  • 2
  • 3

Then the following F# step definition will be passed an array of integer values:

let [<Given>] ``a bullet list of`` (xs:int[]) = ()

 

And also for C# given the regular expression is specified as an argument of the attribute:

[Given(@"a bullet list of")]
public void GivenABulletListOfNumbers(int[] xs)
{
}

 

Get started with the binary, source and examples at: http://tickspec.com and for more information on BDD check out the following free fun e-book: http://www.cuke4ninja.com/

TickSpec: An F# BDD Framework

TickSpec is a lightweight Behaviour Driven Development (BDD) framework on CodePlex:

  • “Tick” because it supports F# ``Tick`` methods (*) (as well as C# annotated methods)
  • “Spec” because it parses plain text Specifications
  • “Lightweight” as it is currently implemented in a single F# file with <200 LOC
  • “BDD” as you can describe the software’s behaviour using a subset of the Gherkin language
  • “Framework” as it is simply a library
  • “CodePlex” so that it can be used by the community

(*) ``F# methods`` delimited with double backtick characters

Why BDD?

 

BDD, originally named by Dan North, is an Agile technique that can help deliver real customer value for LOB applications.

Lest we forget, the Agile Manifesto recommends valuing:

Customer collaboration over contract negotiation

By defining executable scenarios with natural language, BDD encourages collaboration between Developers, QA and Business Participants. This differs from TDD, where unit tests are limited to being readable only by developers. More info:

Agile software development also favours:

Working software over comprehensive documentation

By focusing on writing executable scenarios in a natural language, BDD helps build good enough living documentation.

 

Why F#?

 

For the framework, F# features such as pattern matching, particularly active patterns, combined with regular expression support make writing a text parser and state machine pretty easy.

Consumers of the framework use step definitions as methods that are mapped to lines in the specification text file. In C# typically methods are annotated with attributes describing a regular expression to match the line, with the method name repeating the annotation. By escaping methods in F# with double ticks, spaces and regular expression characters can be used directly, avoiding the duplication.

In his F# Fundamentals article for MSDN Magazine, Luke Hoban claims:

F# is in many ways a higher-level language than C#

it means F# developers can often solve problems and think about their programs at a higher level, closer to the domain of the problem at hand.

A higher level language may be more appropriate for writing acceptance tests. Ben Hall writes in his article Automate Acceptance Tests with IronRuby again for MSDN magazine:

I think you can justify the context switching (between IronRuby and C#) in order to take advantage of the readability and the more natural way of writing the verifications and scenarios

In the end, integrating acceptance testing into the development process can be a hugely positive step for a development organization.

I would assert that F# is similar to IronRuby in its expressiveness, but has an advantage in being a first class language within Visual Studio 2010. I would recommend looking at acceptance tests in F# as a way to introduce the language inside an organization. See Zach Bray’s talk on Automating Acceptance Testing with F# at Skills Matter to learn more.

 

Gherkin feature example

 
Feature: Refunded or replaced items should be returned to stock

Scenario 1: Refunded items should be returned to stock
	Given a customer buys a black jumper
	And I have 3 black jumpers left in stock 
	When he returns the jumper for a refund 
	Then I should have 4 black jumpers in stock 

 

F# Step Definitions

 

let [<Given>] ``a customer buys a black jumper`` () = ()
      
let [<Given>] ``I have (.*) black jumpers left in stock`` (n:int) =  
    stockItem <- { stockItem with Count = n }
      
let [<When>] ``he returns the jumper for a refund`` () =  
    stockItem <- { stockItem with Count = stockItem.Count + 1 }
      
let [<Then>] ``I should have (.*) black jumpers in stock`` (n:int) =     
    let passed = (stockItem.Count = n)
    Debug.Assert(passed)

 

Why TickSpec?

 

Right now TickSpec is intended as a lightweight framework to get you started with BDD using F#. It is standards based, supporting a subset of the Gherkin language, so should be easy to change to another Gherkin based framework like Cucumber, SpecFlow or StorEvil.

 

Finally

 

The Agile Manifesto values:

Individuals and interactions over processes and tools

A BDD framework helps automate the execution of scenarios. But don’t forget, the real value in BDD comes from greater customer collaboration.

Declarative Naming

Like sentence construction, declarative programming requires careful selection of words. Nouns for class and property names, verbs for method and event names.

Ignoring the arbitrary ‘I’ at the start of interface names, nouns or adjectives can describe their capabilities, e.g. comparable, equatable and observable.

Declarative names should describe the “what” without the “how”. Short names typically indicate good abstraction. Long or schizophrenic names are a code smell suggesting poor separation of concerns and that refactoring may be required.

Luke“ Luke. Let the force words guide you.”

A Brief History of Naming

In the beginning, Microsoft operating systems such as MS-DOS or Windows 3.x did not support long file names like other operating systems such as Unix, OS/2, and the Apple Macintosh MAC OS. The earlier versions of Microsoft's operating systems had a limitation of an eight character file name or directory, and a three character extension. [Information about long file names]

Going back a bit further to the 8-bit era of computing, I remember my first Z80 assembler for the Amstrad CPC, HiSoft’s DevPac which only treated the first 6 characters of a label as significant. Meaning coding schemes for labels were required for larger programs, a bit like postal codes for addresses, .

Later with newer assemblers, CPUs and C, restrictions relaxed, but naming conventions like Hungarian notation remained to indicate things like the types of variables. Thankfully with the advent of modern compilers and IDEs, bringing type checking and type information on tooltips, the need for these notations has been removed. Nowadays we should be free to focus on good declarative naming.

Declarative Naming Resources

When following a variant of Domain-driven design (DDD), a ubiquitous language helps define names for core business concepts. This just leaves naming for technical abstractions, and there are plenty of resources out there to help.

Online:

Books:

And now for some examples…

Managers

Like a manager typically has no specific role, so a manager class is probably a poor abstraction. More often than not you’d be better starting with a collection.

INotifyPropertyChanged

In an MSDN article by Josh Smith on MVVM, a ViewModelBase class is suggested that implements the INotifyPropertyChanged interface. To me this seems a poor abstraction as a class need not be a View Model in order to implement this interface, and the name gives no obvious indication to its behaviour, instead suggesting a set of base behaviours. A better abstraction would be ObservableObject, like the framework’s ObservableCollection class which implements the not too dissimilar INotifyCollectionChanged interface.

IDictionary

An improvement on the naming of the pre-generics un-typed equivalent Hashtable class, the Dictionary class better specifies the “what” over the “how”. However the new underlying generic IDictionary interface could be improved by separating the concerns of reading and writing items across 2 interfaces.

GetOrAdd

The new ConcurrentDictionary class in .Net 4.0 contains a method GetOrAdd. Again in terms of naming, this seems to be a poor abstraction, and again by emphasizing the “how” rather than the “what”. A better name would be Obtain, a suggestion in a Martin Fowler tweet.

ToString

A good example of declarative naming, also promoting the idea of functional transformation and idempotence.

Pluralisation

I like pluralisation for collections, e.g. Items, its both short and descriptive. The new IObservable<T> interface as used by the Reactive Extensions (Rx) also seems to lend itself well to pluralisation, e.g. Notifications.

Last word?

For variable names the last word of the object may suffice, e.g.

let connection = new SqlConnection()

Finally

KentBeck: if you can’t find a really good name for something, pick a really terrible name (i like "fred"). then you are motivated to fix it.

Disclaimer:

For legacy code consistency may be as important as declarative naming, so abandoning coding schemes like Hungarian notation on a large codebase may be counter-productive.