Sunday, July 24, 2011

Command line execution in storytests with fitSharp

A recent question on Stack Overflow asked if there is a command line execution fixture available for fitSharp. Something like:
|command line fixture|
|mypath\myprogram.exe|my arguments|
I answered that I didn't know of any but it would be easy to write one. (I put aside any thoughts of why this would be necessary. People use fitSharp for all kinds of things that I've never imagined.)

When I started to think more carefully, I realized that fitSharp provides the capability to do this without writing any fixtures at all. In classic Fit, the first cell in a table is the name of a fixture class to be invoked. In fitSharp, if this cell does not contain the name of a fixture class, a DoFixture is created which lets us execute methods on a class without writing a fixture. So we can write a command line class:
using System.Diagnostics;
namespace myStuff {
    public class CommandLine {
        public void Run(string program, string arguments) {
            var process = Process.Start(program, arguments);
Then our test looks like:
|run|mypath\myprogram.exe||my arguments|
This is a common pattern: we write a 'domain adapter' class to make it easier to invoke methods on our system under test from standard fixtures like DoFixture. These classes tend to be more flexible and reusable than if we write custom fixtures for each of our test scenarios.

But we can go further than this. We can execute methods on the System.Diagnostics classes directly. The 'with' keyword tells DoFixture which object to execute methods on. So our test can be:
|with|start|mypath\myprogram.exe||my arguments|
|wait for exit|
Of course, it would be nice to not duplicate this throughout our tests, so we can define a procedure:
|wait for exit|
Then we can use this whenever we need to run a program:
|run|mypath\myprogram.exe|with|my arguments|
This is a simple example of how we can start building a testing DSL that suits the kind of test scenarios we need to execute.

Saturday, July 9, 2011

Starting a FitNesse project with fitSharp

FitNesse and fitSharp offer so much flexibility that there's many different ways to configure a project, but for the beginner, a common question is: OK, but where do I start? So here's how I set up a sample project.

I got fitnesse.jar from and put it in C:\apps\fitnesse. I got the latest fitSharp release from and unzipped it into c:\apps\fitnesse\dotnet.

I created a Visual Studio solution in c:\projects\fitsharpsample.  I added a class library  project called Fixtures.  I added references to fit.dll and fitsharp.dll from c:\apps\fitnesse\dotnet.  I added a class called SampleDo:
using fitlibrary;

namespace Fixtures {
    public class SampleDo: DoFixture {
        public string Greeting { get { return "hi"; } }
In my solution folder, I created a fitnesseRoot folder. I created a file fitnesse.cmd to run FitNesse:
java -jar \apps\fitnesse\fitnesse.jar -p 8080 -d "c:\projects\fitsharpsample" -r fitNesseRoot
I created a configuration file storytest.config.xml:

In my browser, I went to http://localhost:8080 and clicked the root link and edited the root page to contain:
!define TEST_RUNNER {c:\apps\fitnesse\dotnet\Runner.exe}
!define COMMAND_PATTERN {%m -c c:\projects\fitsharpsample\storytest.config.xml %p}
 I added a SampleTest page in FitNesse:
|sample do|
I ran the test and all green!

Assertions: 1 right, 0 wrong, 0 ignored, 0 exceptions (0.000 seconds)
sample do
check greeting hi

Wednesday, June 1, 2011

Working remotely: a success story

I just finished a great project where the entire team was geographically distributed.  I'm going to jot down some retrospective thoughts about what made this project a success, while it's fresh in my mind.
  • Being all distributed probably worked better than having a centralized core team with remote members.  There were no second class citizens and we were all more aware of keeping everyone else connected to what we were doing.
  • The technology is there - just make sure you use it.  We did a daily group video stand-up and iteration planning and retrospectives with Skype and Mikogo, a screen-sharing tool.
  • Video is important. Occasionally, a team member would not have access to video and you could feel the collaboration start to slip almost immediately.
  • Distributed source control, like git or mercurial, is a must.
  • We had a small, highly competent team with diverse and complementary skills. The old rule about each new team member adding 'n' communication paths is amplified when those paths are remote.
  • There was a strong team culture of collaboration.  We had 3 developers, a product owner and an analyst/tester, but everyone pitched in wherever they were needed.
  • We used pair-programming from time to time to share knowledge and developers worked on tasks in different areas of the code base from iteration to iteration.  There was a team culture of learning that reinforced collective code ownership.
  • Automated unit tests and executable specifications are a must. (We used NUnit and FitNesse.)
Your mileage may vary, but I see the distributed team as an effective way to get the very best people assembled for your next project.

Tuesday, January 4, 2011

Customizing the new FitNesse parser

FitNesse began its life using the 'simplest thing that works' to parse wiki markup and render it as HTML: a set of regular expressions. Over the years, FitNesse functionality has grown, and the regex-based parser has had to support more and more complex tasks.  More and more hacks have been added to work around regex limitations and performance has suffered as bigger and more complex wiki pages have been thrown at it. So last spring, I started on a project to re-write the entire FitNesse parser, using classic grammar theory approaches.

Although the realities of earning a living slowed progress at times, and the challenges of replicating all the quirks of the original parser tested my resolve, we have finally merged the new parser into the main code base.  Thanks to a number of beta users, it has been tested on some major FitNesse test suites and the next FitNesse release, coming soon, will use the new parser.

One of the features of the original parser was the ability to extend the wiki syntax by plugging in your own custom wiki 'widgets'. This is described here: you write a class that extends WikiWidget and you add a line to a file.


James Carr wrote a nice post describing a detailed example of this.

The new parser also has this feature, but the plug-in class that you write is different. I'm going to show a very simple example here. Let's imagine we want to write !pi in our wiki pages and have it rendered with the value of pi in the HTML.

The plug-in class must extend SymbolType. A plug-in class can specify up to four pieces of information for the parser. Our simple example only needs to supply three of these.

The first is a name, specified in the super constructor. The name is just used for error reporting and debugging and so it can be any descriptive string.

The second is the wikiMatcher. This is an object that knows how to identify the symbol type in the source string. The Matcher class provides a lot of common matching behavior, so we can just tell it that our symbol type is recognized by the string "!pi". You can look at the Matcher source to find other matching behavior.

The third is the wikiRule, which our symbol type doesn't require. This is an object that implements a grammar production rule if our symbol type is composed of other symbol types (a non-terminal, in grammar-speak). Our symbol type is a terminal so we don't need a production rule. Look at the fitnesse.wikitext.parser package to see examples of how production rule classes are written.

The fourth is the htmlTranslation. This is an object that renders the symbol type as a string in the HTML output. We can implement the Translation interface and specify this as our translation object. The toTarget method renders our output, a string containing the value of pi.

We add a line to the file.


That's it!