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);
            process.WaitForExit();
        }
    }
}
Then our test looks like:
|myStuff.CommandLine|
|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|type|System.Diagnostics.Process|
|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:
|define|run|@program|with|@arguments|
|with|type|System.Diagnostics.Process|
|with|start|@program||@arguments|
|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 http://fitnesse.org and put it in C:\apps\fitnesse. I got the latest fitSharp release from http://github.com/jediwhale/fitsharp 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
pause
I created a configuration file storytest.config.xml:
<suiteConfig>
    <Settings>
        <Runner>fitnesse.fitserver.FitServer</Runner>
    </Settings>

    <ApplicationUnderTest>
        <addNamespace>Fixtures</addNamespace>
        <addAssembly>c:\projects\fitsharpsample\build\debug\Fixtures.dll</addAssembly>
    </ApplicationUnderTest>
</suiteConfig>
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|
|check|greeting|hi|
I ran the test and all green!

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