Friday, February 10, 2006

RowEntryFixture for .Net FitNesse

Many acceptance tests need test data to work with, and RowEntryFixture is a simple fixture made for just that. You create a class that inherits from RowEntryFixture and override its EnterRow method to add an item of data from the corresponding table in your acceptance test.

When I started using FitNesse for my .Net projects, however, I discovered that the FitNesse developers didn't add RowEntryFixture to the .Net part of FitNesse. So I ported the Java version to .Net, and I built it into my .Net FitNesse replacement bundle. Here's the code for anyone wanting to build FitNesse with it:

using System;
using System.IO;

using fit;

namespace fitnesse.fixtures
{
    public abstract class RowEntryFixture : ColumnFixture
    {
        public abstract void EnterRow();

        public const String ERROR_INDICATOR = "Unable to enter last row: ";
        public const String RIGHT_STYLE = "pass";
        public const String WRONG_STYLE = "fail";

        public override void DoRow(Parse row)
        {
            if(row.Parts.Body.IndexOf(ERROR_INDICATOR) != -1)
                return;

            base.DoRow(row);
            try
            {
                EnterRow();
                Right(AppendCell(row, "entered"));
            }
            catch(Exception e)
            {
                Wrong(AppendCell(row, "skipped"));
                ReportError(row, e);
            }
        }

        protected Parse AppendCell(Parse row, String text)
        {
            Parse lastCell = new Parse("td", text, null, null);
            row.Parts.Last.More = lastCell;
            return lastCell;
        }

        public void ReportError(Parse row, Exception e)
        {
            Parse errorCell = MakeMessageCell(e);
            InsertRowAfter(row, new Parse("tr", null, errorCell, null));
        }

        public Parse MakeMessageCell(Exception e)
        {
            Parse errorCell = new Parse("td", "", null, null);
            StringWriter buffer = new StringWriter();

            buffer.Write(e.StackTrace);
            errorCell.AddToTag(" colspan=\"" + (ColumnBindings.Length + 1) + "\"");
            errorCell.AddToBody("<i>" + ERROR_INDICATOR + e.Message + "</i>");
            errorCell.AddToBody("<pre>" + (buffer.ToString()) + "</pre>");
            Wrong(errorCell);

            return errorCell;
        }

        public void InsertRowAfter(Parse currentRow, Parse rowToAdd)
        {
            Parse nextRow = currentRow.More;
            currentRow.More = rowToAdd;
            rowToAdd.More = nextRow;
        }

    }
}

Building FitNesse and FitLibrary for .Net 2.0

Here's how I built both FitNesse and FitLibrary for .Net 2.0. (If you don't have fifteen minutes for this, help yourself to my .Net FitNesse replacement bundle.)

UPDATE 25OCT2006: These instructions for building FitNesse may not work. Around May 2006, the developers of FitNesse merged their .Net FitServer with FitLibrary.NET into a new SourceForge project. (See the .Net page at FitNesse for more information.) I will try to investigate this, but I make no promise of updating these instructions.

First, let's tackle FitNesse:

  1. Download the latest source bundle for FitNesse. As of today, the latest version is 20060209.
  2. Create a directory in your "Visual Studio 2005\Projects" directory called "FitNesse".
  3. From the FitNesse source bundle, extract the contents of the "dotnet" directory (but not the directory itself) into the folder you just created.
  4. Open the "fitnesse.sln" solution file. This will start VS 2005 and invoke the Conversion Wizard.
  5. Click the "Finish" button, and the wizard converts the solution into one compatible with VS 2005.
  6. Click the "Close" button. If VS displays the conversion summary, then it encountered errors. Scan for the errors and resolve them. If the conversion had no errors, then VS will not display this summary.
  7. If you're using the same FitNesse version as I did, then you will see two errors in the summary regarding "TableFixture.cs" and "TableFixtureTest.cs". The errors occurred because, for some reason, the two files did not make it into the source bundle. Grab them from the latest release source bundle, and put them into the "fitnesse" folder in the "fit" project.
  8. In each of those files, add a using fit; line and change the namespace from fit to fitnesse.fixtures.
  9. For each project:
    1. Right click the project, and choose "Properties" from the context menu.
    2. In the properties page that appears, click the "Build Events" tab.
    3. Delete the pre-build event command line.
    4. Change the post-build event command line to
      copy "$(TargetPath)" "$(SolutionDir)"
      copy "$(TargetPath)" "full path to FitNesse 'dotnet' directory"
      including the double quotes.
  10. Build the solution. (Press F6.) You should see no errors, but you may get warnings. I addressed one of the two that appeared for me. I changed a method call from GetByHostName to GetHostEntry.

And now for FitLibrary:

  1. Download the latest bundle of the .Net version of FitLibrary. As of today, the latest version is 20060117.
  2. Extract the contents of the bundle to your "Visual Studio 2005\Projects" directory. This will add a "FitLibrary.NET" project folder.
  3. Open the "fitlibrary.sln" solution file, and VS 2005 will start its Conversion Wizard.
  4. Click "Finish", and click "Close" when the wizard finishes. If you get errors, address them now. (I did not get any errors.)
  5. For the "FitLibrary" project:
    1. Right click the project, and choose "Properties" from the context menu.
    2. In the properties page that appears, click the "Build Events" tab.
    3. Delete the pre-build event command line. No longer necessary (25OCT2006)
    4. Change the post-build event command line to
      copy "$(TargetPath)" "full path to FitNesse 'dotnet' directory"
      including the double quotes. (Updated 25OCT2006)
  6. In the "FitLibrary" project, remove the reference to "fit", and add a reference to the "fit.dll" in your FitNesse installation's "dotnet" directory.
  7. Build the solution. (Press F6.) It should succeed.

Now you have a .Net 2.0 compatible version of FitNesse and FitLibrary ready for you in your FitNesse installation. Happy Testing!