You’re Not Gonna Fix It

It’s 2am so I’m hacking this together and cutting a few corners, which in this case it good because it puts me in the right frame of mind to talk about kludges.

I’m not going to justify the kludges, or apologise for kludges. I don’t need help figuring out how to avoid them. Generally speaking kludges don’t come about because we don’t know how to avoid them, they usually exist because a judgement call is made that a kludge is not worth avoiding. Dress it up however you like, but ultimately it comes down to a decision.

This post starts from the premise that in all liklihood there will always be kludges. I want to talk specifically about the lie that programmers tell ourselves every time we resort to a kludge.

“I’ll fix that later”.

In some cases we may even include a comment indicating that we’ve done something we’re not proud of, and perhaps even details about how to fix it.

We may go further and adopt a standard that says we should start the comment with a word like HACK, so we can find these gems later.

Let’s knock something on the head right now.

You’re Not Gonna Fix It.

If that rings a bell it has echoes of “You’re not gonna need it”.

While “You’re not gonna need it” serves as a warning against doing too much in the hopes that it will be useful later, “You’re not gonna fix it” warns us against doing too little with the promise that we’ll fix it later.

Let’s assume you’ve hit one of those moments where there’s a 5 minute fix.

Let’s assume that you’re not entirely happy with the solution. There is a better way, for the purposes of this post it doesn’t matter what the better way is.

You make the judgement call to go with the 5 minute fix. Or, perhaps the jugement call is made for you, by a manager, by the QA team drumming their fingers, by your spouse calling to say your two year old has just coughed up something and you need to get home.

You do the fix, release the code, it gets through QA, pushed into production, and it works. Great.

A month later, you’re finished the project, getting into a new project, waiting to meet stakeholders, you find yourself with a spare afternoon. A chance to crack open the code and take a swing at some of those kludges.

Now, depending on your development process this may actually be a really dumb idea. If production changes need to go through QA then you are about to create a chunk of work for the QA team. Have you checked with them that they have capacity?

What if this fails right as you get started on your new project, will you have capacity?

We’re talking about a change that brings no real value to the users, certainly no visible value. Are you going to run it by your manager?

If you were a manager would you ok a production code change just to tidy up some code that was gnawing at a developers conscience?

If you go gung ho proclaiming that it’s a trivial change the first question you’re likely to be asked is why wasn’t this trivial solution implemented in the first place. It’s funny how perception works. A change that you considered non-trivial at 6pm on a Friday evening when you didn’t really want to do it, suddenly becomes trivial when you have a spare afternoon a few months later.

In reality changes only get harder with the passage of time. You are never going to be as familiar with the code as you were when you first created the kludge. No amount of HACK comments can fix that.

Does this mean you should never pay down technical debt?

Of course not, but understand that your ability to pay down technical debt is intrinsically linked to your development process. The more “Waterfallish” your process the less likely it is that you’ll be able to fix issues later. The more people you need to take time from in order the push out a release, the more likely it is that technical debt will remain untouched.

So for some, You’re not gonna fix is is not just a harsh reality, it’s how it should be. There’s a cost associated with being able to fix kludges. So, either create a process that facilitates repaying technical debt, or get used to the fact that a kludge is for life.

Even if you have a process that facilitates tidy ups, it’s still a useful exercise to consider kludges permanent solutions. If the decision to use or a avoid a kludge is a close call, then it’s tempting to let a promise to fix it later sway the balance in favour of the kludge.

Next time you are in that situation, throw in a promise that this kludge is for life and see which way the scales tip. If they still fall in favour of the kludge then go with it.

If the realisation that “You’re not gonna fix it” tips the scales the other way then you’ll have your answer.

Snooker Kata

I’ve been toying with the following TDD Kata. I like it a lot, it provides just enough complexity that it’s interesting, but not so much that the algorithm needs to be complicated.

The idea is to implement a game of Snooker. I’ll assume you either know the rules of snooker, or can find them here.

We need a class that keeps track of a frame of snooker, including which player is at the table, which colour ball they should be targeting, and provides methods that allow us to tell the class what happens with each shot.

The Methods needed are

Hit(colour)
Pot(colour)
Miss(colour)
InOff(colour)
Nominate(colour)

We also need a number of methods that will give us back details about the state of the two players.

int Score(player)
int HighestBreak(player)
int Potted(player, colour)
  1. Implement Hit(Colour)
    Game will keep track of which player is at the table, and whether they should be hitting a red or another color. If the player hits any red when a red is expected, or any colour when a colour is expected, it shall be deemed a valid hit, and play shall switch to the other player.
  2. Wrong Ball Hit
    If a red is expected but a colour is hit, or vice versa, the game shall detect the foul and award the correct number of points to the other player and play shall switch to that player.
  3. Implement Pot(Colour)
    Same logic as above, however the appropriate number of points shall be awarded to the player at the table and play shall remain with that player.
  4. Implement Miss(Colour)
    This method indicates that the player at the table missed the targeted colour. Award the appropriate points to the opponent and switch player.
  5. Implement InOff(Colour)
    This method indicates that the player potted the cue ball while targeting a player of the suggested colour. Award the appropriate points to the opponent and switch player.
  6. Implement Nominate(Colour)
    This method should be used after the player has potted a red, it designates the desired colour that will be targeted. If Nominate is followed by Hit or Pot of a different colour, that is a foul. Award points to opponent and switch player. if Nominate is followed by Hit or Pot of the nominated colour that is valid, award points to the player and he remains at the table.
  7. Change Nominated Ball
    Allow the player to change nominated ball by simply calling Nominate again, the most recent call counts.
  8. Replace Potted Balls
    Colours are replaced on the table after being potted, reds stay off the table when potted.
  9. No Reds Left
    Detect when all reds have been potted, the players must then play for the lowest valued colour. They can not nominate a different colour. When colours are potted at this stage of the game they remain off the table.
  10. End Of Frame
    Play ends when the table is cleared.
  11. Statistics
    The following statistics should be available for each player at any time during or on completion of a frame:
    Score
    Highest Break
    Number of pots for each ball colour

FitNesse Query Tables

This entry is part 5 of 5 in the series FitNesse

Query Tables
In the last post we looked at using Decision Tables with FitNesse. Each row in a decision table can be thought of as a Test Case, with some of the columns representing Inputs and others representing expected Outputs.

Now we move on to something a little more complicated. Query Tables represent a set of results. The Table in its entirety represents a single test (e.g. Get All Employees in IT Department).

The table contains a row for each expected result, and the columns represent the attributes of the objects. Here’s a Query Table in FitNesse that loads a set of Employees.

Query Table

The Markup for this table is about as simple as you’d expect.

|Query:All Employees                             |
|Employee Number|First Name|Last Name|Hire Date  |
|1429           |Bob       |Martin   |10-Oct-1975|
|9924           |Bill      |Mitchell |19-Dec-1966|

The first thing to note is the word Query in the first row. This tells FitNesse that the table should be interpreted as a Query Table.

The name of the table ‘All Employees’ will need to map to a Fixture class called ‘AllEmployees’.

The next row contains the column headers. Our Test Fixture is going to need to mark the returned data with these Column names so that FitNesse knows where it fits in the table.

Query Table Fixtures
Before we look at the specific details of how to pass data to and return data from the Query Table Test Fixture, lets look at the structure of the Test Fixture itself.

At its simplest we need only provide a function called ‘Query’ that returns a list of objects. Since it has no parameters the fixture class doesn’t need any special constructor. The query method will get called and should return the table of data.

We’ll get to the exact details of how the list of objects will represent a table of data. For now you just need to understand that when the Tests are run in FitNesse, the ‘Query’ method will be executed, and it returns a list of something.

public class AllEmployees
{
    public List<Object> query()
    {
        throw new NotImplementedException();
    }
}

We can add a constructor to the class, this will allow our test to feed individual parameters into the Test Fixture. This can be useful if we want to pull back a filtered list of data.

public class SimpleQueryFixture
{
    public SimpleQueryFixture(date HiredBefore)
    {
    }

    public List<Object> query()
    {
        throw new NotImplementedException();
    }
}

Constructor Parameters are specified in the first row of the table.

|Query:All Employees                 |01-Jan-2000|
|Employee Number|First Name|Last Name|Hire Date  |
|1429           |Bob       |Martin   |10-Oct-1975|
|9924           |Bill      |Mitchell |19-Dec-1966|

Of course you can provide multiple parameters to your constructor, just make sure the values in the table match the signature of the Test Fixture constructor.

|Query:Employees By Date City Dept|01-Jan-2000|"IT"|"London" |
|Employee Number             |First Name |Last Name|Hire Date|

We can also optionally implement a ‘Table’ method. If supplied this will be invoked before the ‘Query’ method, and it will receive the existing FitNesse table and it’s contents. This can be useful if we want to provide a table of data, or a partially filled table, and have columns filled in or even overwritten.

public class SimpleQueryFixture
{
    public void table(List<List<String>> table)
    {
        throw new NotImplementedException();
    }

    public List<Object> query()
    {
        throw new NotImplementedException();
    }
}

Table Formats
The eagle eyed among you will notice that the data structure passed to the ‘Table’ method is a List of Lists of Strings, whereas the data structure returned from the ‘Query’ method is a List of Objects.

It’s worth understanding how these tables are represented and the differences between them. We’ll see these data structures used again and again as we look at other types of FitNesse/SLiM tables.

The Output Table – From the ‘Query’ method
We’ll start with the output table since that is by far the most common one you’ll use. It uses a nested List of Lists of Lists type arrangement. Here’s a hard-coded example of how you would return a table of employee details from the query method of your Test Fixture. It illustrates the data structure.

public List<Object> query()
{
    return new
          List<Object>{
            new List<Object>{
              new List<String>{"Employee Number", "1429"},
              new List<String>{"First Name", "Bob"},
              new List<String>{"Last Name", "Martin"},
              new List<String>{"Hire Date", "10-Oct-1974"}
            },
            new List<Object>{
              new List<String>{"Employee Number", "8832"},
              new List<String>{"First Name", "James"},
              new List<String>{"Last Name", "Grenning"},
              new List<String>{"Hire Date", "15-Dec-1979"}
            }
          };
}

From the outside our table looks like a List of Objects. Each item in that list represents a row in the table, and is also represented by a List of Objects. Each cell in the row is represented by a List of Strings. This last bit is where the confusion may lie for the uninitiated.

Instead of representing the Column headers once in a row of their own, the table represents each cell in every row as a Name/Value pair in the form of a List of two strings.

This has it’s advantages, you can pull an individual Row out of the Data structure and have everything you need, the column names and cell values.

It is a little unconventional though, there’s a bit of a mismatch between how you view a table and how it’s actually represented. But, once you know what’s happening it’s fine. This incidentally is where the input and output tables differ. Tables that are sent to the Table method represent the column headers as a row in their own right.

On order to avoid creating boilerplate code from scratch every time we use the Query Table, we can take the tasks of translating from domain objects to this list arrangement and make a generic reusable version. We’ll look at how to do that towards the end of this post.

The Input Table – To the ‘Table’ method
Tables that are sent by FitNesse to the ‘Table’ method are represented by a List>. To put that in english, each row is a list of Strings, and a table is a List of these rows. This is much closer to the way you would imagine a table would be represented.

Using our tables from above as an example, if we have a table that shows Employee Number, First Name, Last Name and Hire Date, we could use code like the following to turn the table into a list of Employee objects.

List<Employee> employees = new List<Employee>();

    foreach(var row in table)
        {
            if(row[0] != "Employee Number")
            {
                employees.Add(
                    new Employee(row[0],
                                 row[1],
                                 row[2],
                                 row[3]));
            }
        }

Pardon the horrible code here, but you get the point. We ignore the first row as it contains the column headers. The four items in each subsequent row represent the cell values from the table, we pass these to the constructor of our domain object.

Translating from Domain Objects To Query Table
It’s unlikely that the data in your application will be represented by a data structure that looks anything like that required by the Query Table.

Assuming we have a list of Employee objects, how are we going to knock it into the shape that will allow our test fixture to pass it pack to FitNesse.

Obviously we could hand code each Test Fixture as the need arises, but that’s a lot of boring repetitive boilerplate code.

Below is an example of using Reflection to convert a list of objects into a list that FitNesse can work with. It makes the assumption that the properties of the object are in CamelCase and by splitting the words in the property name we get the Column name from the table. So, ‘EmployeeNumber’ becomes ‘Employee Number’

class SlimTableAdaptor<T>
{
    public List<Object> FromObjects(List<T> items)
    {
        return CreateTable(items);
    }

    private List<Object> CreateTable(List<T> items)
    {
        return items.Select(CreateRow).Cast<Object>().ToList();
    }

    private List<Object> CreateRow(T item)
    {
        PropertyInfo[] properties = GetProperties();
        return properties.Select(property =>
                         CreateColumn(item, property)).ToList();
    }

    private object CreateColumn(Object item, PropertyInfo property)
    {
        string propertyName = SplitCamelCase(property.Name);
        string value = GetPropertyValue(item, property.Name);
        return new List<string> { propertyName, value };
    }

    private PropertyInfo[] GetProperties()
    {
        return typeof(T).GetProperties();
    }

    private string GetPropertyValue(object source, string property)
    {
        object value = source.GetType()
                             .GetProperty(property)
                             .GetValue(source, null);

        string valueAsString = value.ToString();

        if (value.GetType().Name == "DateTime")
            valueAsString = FixDate(value);

        return valueAsString;
    }

    private string SplitCamelCase(string value)
    {
        return System.Text.RegularExpressions.Regex
            .Replace(value, "([A-Z])", " $1").Trim();
    }

    private string FixDate(Object value)
    {
        DateTime date = (DateTime) value;

        if (date.TimeOfDay.Ticks == 0)
            return date.ToString("dd-MMM-yyyy");

        return value.ToString();
    }
}

With a helper class like this written, it becomes a trivial matter to create a Test Fixture class. Here’s what our Query method might look like.

public List<Object> query()
{
    var employees = EmployeeRepository.GetAll();

    var helper = new SlimTableAdaptor<Employee>();
    return helper.FromObjects(employees);
}

This is a simplified version of the helper class. You might like to add some additional features such as

  • Ability to specifically map property names to column names
  • Ability to return a subset of properties rather than all of them
  • Ability to translate from Input Table to list of Objects
  • Ability to translate other sources of Data (e.g. Data Tables, XML etc.)

Subset Tables
There are two specialised types of Query Table that you can use, Subset Query Tables, and Ordered Query Tables. The names pretty much leave nothing to the imagination here.

When we use a Subset Query Table our tests pass as long as the rows we specify exist in the results returned from the Fixture.

When we use an Ordered Query Table our tests pass as long as the rows we specify match exactly the rows returned from the Fixture, including the ordering of the rows.

Subset and Ordered Query Tables work exactly like regular Query Tables, the data is returned in the same format, we can specify constructor parameters and an input table in exactly the same way.

Here’s a Subset Query Table

|Subset Query:All Employees                      |
|Employee Number|First Name|Last Name|Hire Date  |
|1429           |Bob       |Martin   |10-Oct-1975|

As long as one of the rows returned from the AllEmployees test fixture matches the row in the table, the test will pass.

Here’s an Ordered Query Table

|Ordered Query:All Employees                     |
|Employee Number|First Name|Last Name|Hire Date  |
|1429           |Bob       |Martin   |10-Oct-1975|
|9924           |Bill      |Mitchell |19-Dec-1966|

The rows returned from the AllEmployees test fixture must match those in the table exactly, including matching the order in which the rows are listed.

FitNesse Decision Tables

This entry is part 4 of 5 in the series FitNesse

In the last post, we set up a solution to demonstrate the use of FitNesse. The solution contained a Calculator Project, and a Calculator.Specifications project which contains an instance of FitNesse, and an Acceptance Test fixture for the Calculator project.

To show that everything was up and running we created a simple Decision Table test in FitNesse.
In this post we’ll look more closely and Decision Tables.

Decisions Decisions
A FitNesse Decision Table allows us to supply a number of input parameters and receive back a number of output values. A test passes or fails based on whether the expected outputs match the actual outputs.

In our last post we tested a simple calculation using our Calculator project. Let’s look at the Markup for that Table, line by line.

Line 1 defines the name of the table, and by convention this also tells FitNesse the name of the Class it should try to use when executing the test. In this case FitNesse will search our TestFixtures for a class called DoSimpleMath. Alternatively the Fixture name ‘DoSimpleMatch’ could have been used in the table.

The Exclamation mark at the start of Line one is interesting. If the Table name had been written without spaces as described above, FitNesse would have automatically turned the table header into a link.

The Exclamation mark prevents links being automatically created. Strictly speaking in this instance it’s not needed, since FitNesse does not try to create links where spaces exist. It is however good practice to include the exclamation even when not needed.

Line 2 defines the parameters of the test, but the input values we’ll sent to the test, and the output values we get back. In this case A, B and Op are all input parameters. Result is an output value as indicated by the question mark ‘?’.

Line 3 consists of the values to be used with the Test. We supply 1, 2 and + and we state that we expect the value 3 to be the result of adding 1 and 2.

!|Do Simple Maths  |
|A  |B  |Op|Result?|
|1.0|2.0|+ |3.0    |

Naturally, you can create multiple rows to test various scenarios.

!|Do Simple Maths  |
|A  |B  |Op|Result?|
|1.0|2.0|+ |3.0    |
|5.0|5.0|- |0      |
|2.0|3.0|* |6.0    |
|6.0|3.0|+ |2.0    |

Decision Table Fixtures
As mention above the name of the Table dictates the name of the class that FitNesse will attempt to execute the test.

It may be that a table name and the particular input and output columns are ideal for describing features of the system, but are not good names for objects in our domain model.

This is where Fixtures come in. Generally speaking we don’t want to write FitNesse tests that directly access the domain model. Apart from the fact that good names for tests may not make good interfaces for objects, there is also a brittleness from hooking up directly to a Domain Model that could change.

Test Fixtures provide a level of abstraction between FitNesse and our System Under Test. Fixtures are usually simple pass through objects that invoke the expected behaviour and return apropriate results.

We declare the inputs as public fields. There’s no benefit in declaring properties and private fields in a fixture. We want the simplest possible implementation that allows us to get values in and out.

public class DoSimpleMaths
{
    public decimal A;
    public decimal B;
    public string Op;

    public decimal Result()
    {
        if (Op == "+")
            return Calculator.Add(A, B);

        if (Op == "-")
            return Calculator.Subtract(A, B);

        if (Op == "*")
            return Calculator.Multiply(A, B);

        if (Op == "/")
            return Calculator.Divide(A, B);

        throw new NotImplementedException(string.Format("'{0}' is not an implemented Operator", Op));
    }
}

The following fixture implements the Result output as a function. If your Decision Table includes multiple outputs you can implement each as a separate function for each.

public class DoDivisionWithRemainder
{
    public int A;
    public int B;

    public int Result()
    {
        return A / B;
    }

    public int Remainder()
    {
        return A % B;
    }
}

If the work of the fixture can be implemented in a single method, you could consider the following alternative approach. Use public fields for all inputs and outputs, then use a method called Execute to populate all of the outputs.

FitNesse will run the ‘Execute’ method before evaluating the outputs.

public class DoDivisionWithRemainder
{
    public int A;
    public int B;
    public int Result;
    public int Remainder;

    public void Execute()
    {
        Result = A / B;
        Remainder = A % B;
    }
}

The following FitNesse Decision Table will work with either of the previous two Test Fixtures.

!|Do Division With Remainder|
|A  |B |Result? |Remainder? |
|13 |5 |2       |3          |

Beyond the Basics
We can do some interesting things beyond the basic decision tables shown above. For example if we have inputs that will be the same for each row in the table, we can define it once in the header.

!|AddAFixedPercentage        |10     |
|Principal                   |Result?|
|0                           |0.0    |
|10                          |11.0   |
|100                         |110.0  |

In the above example, the value 10 is passed into the constructor of the fixture. It can then be used for each row, without needing a column for it in the table.

public class AddAFixedPercentage
{
    public decimal principal;
    private decimal _percentage;

    public AddAFixedPercentage(decimal <span class="hiddenGrammarError" pre="">percentage)
    {
        _percentage</span> = percentage;
    }

    public decimal result()
    {
        return Calculator.AddPercentage(principal, _percentage);
    }
}

If you want to pass more than one parameter to the Fixture you can do that. Just add them to the first row in the table. Make sure that the constructor has the correct number of parameters of the correct types to accept the values in the table.

!|FixtureName  |10 |ABC |3.14 |

When testing our expected results against the actual results, we also have options. We don’t need to find an exact match in order to pass a test. Sometimes an approximate match, or a range of values may be sufficient. Let’s remind ourselves of the markup for an exact match.

!|Do Simple Maths  |
|A  |B  |Op|Result?|
|6  |2  |/ |3      |

If we use the ~= operator we can match on approximately equal values.

|22|7|/ |~=3.14      |

22/7 is the famous approximation of PI, but in reality it’s not all that close an approximation. In fact it all goes wrong if you look beyond 2 decimal places. The Test above will pass because at two decimal places, 22/7 matches 3.14.

We can also check that a value is Grater Than another.

|10|1|+ |>10      |

Or that a value falls within a given range.

|5|3|* |14<_<16   |

When Decision Tables Work Best
As mentioned above, Decision Tables are very useful when we have a set of clearly defined Inputs and Outputs. It may seem that most problems can be reduced to this sort of scenario, and that’s probably true, however we’ll see other options in subsequent posts for other types of scenarios.

Aha! Unit Tests – DDDBelfast

Sample Code

On Saturday I spoke at DDDBelfast. My Session was on Unit Testing. After the Test Driven Development session in Bristol, it occured to me that a more fundamental problem was Unit Testing itself. Whether the Tests are Written before or after the code is a non-issue if developers aren’t writing automated Unit Tests at all.

Here are the slides for the session.



The sample Code includes the Wizard project which includes a suite of Unit Tests, you’ll need to install MOQ and NUnit to run all the tests.

Also included are the three examples of injecting mocks, and the example of how traditional NTier code can violate the Single Responsibility Principal, and how to avoid that problem

Any questions about any of this, feel free to get in touch or leave a comment.

Adding FitNesse to your .Net Solution

This entry is part 3 of 5 in the series FitNesse

Sample Code

In the last post I mentioned Jeff Kwak’s blog post on FitNesse, specifically his way of creating a FitNesse wiki within your .Net solution.

The rest of the posts in this series will use a particular arrangement of projects based heavily on Jeff’s approach.

I’m not going to rehash his post, however I did have a few problems getting things to work the way Jeff did, and I also wanted to do some things a little differently. In this post I’ll discuss where my approach differs from his.

I’m providing a very basic Solution with FitNesse included and we’ll walk through creating and passing a first Test. Subsequent posts in this series will build incrementally on this Solution.

A Sample Solution
Download the attached zip file and extract it somewhere on your dev box. Mine is extracted to C:\Projects\FitNesseTutorial.

Open the resulting Solution. It has two Projects, Calculator (our system under test) and Calculator.Specifications (our tests).

Let me apologise right now for going down the well-trodden path of simple calculator examples. My goal with these first few posts is to get you using FitNesse in the simplest possible way. There will be time later to consider more realistic examples of how FitNesse might be used in real projects.

I’m not going to try and find some grand integrated application that illustrates all of the features of FitNesse. I will use simple standalone examples as required to best illustrate what I’m talking about.



Before we start worrying about FitNesse, build the solution. It should build successfully without any changes.

Setting up External Tools
This next step is optional, but I think it’s worth doing. I’d like a way to start and stop the FitNesse server from within Visual Studio, and pop up a browser running the Wiki, also from within the IDE. What I’ve got is not as clean as I’d like, but it’ll do until I find a better way.

Starting FitNesse
The sample Solution includes a batch file that runs FitNesse. The first thing we’re going to do is create an External Tool in Visual Studio to run that batch file.

In the External Tools Dialog, Add a Tool called ‘FitNesseStart’. Set the Command to

$(SolutionDir)Specifications\AcceptanceTests\startfitnesse.bat

set the Initial directory to

$(SolutionDir)Specifications\AcceptanceTests

and check the Use Output window checkbox.

The results should look like this



Opening FitNesse in the Browser
You need only start FitNesse once when you load your project. This starts the FitNesse server running. You seperately navigate to the FitNesse wiki using your browser.

You can start and stop your browser as often as you like, the server will keep running in the background.

We’ll set up another External tool which will load the Wiki on the proper page.

In the External Tools Dialog, Add a Tool called ‘FitNesseBrowser’. Set the Command to

Explorer.exe

set the Arguments to


http://localhost:9092/AcceptanceTests

The results should look like this



Stopping FitNesse
As mentioned above, the FitNesse server will continue happily running away in the background even when you start and stop your browser. Visual Studio External Tools provides a mechanism for shutting down tools, however it doesn’t work for FitNesse.

For now the only solution I’ve found is a separate Tool.

The sample Solution includes another batch file that closes FitNesse.

In the External Tools Dialog, Add a Tool called ‘FitNesseStop’. Set the Command to

$(SolutionDir)Specifications\AcceptanceTests\stopfitnesse.bat

set the Initial directory to

$(SolutionDir)Specifications\AcceptanceTests

The results should look like this



Here’s a curious little thing to note. If you look in the Solution Folder you’ll notice that the Calculator.Specifications project is in a folder called ‘Specifications’, and not ‘Calculator.Specifications’.

This is to make the configuration of the External Tools more generic. It means that when you load a different solution, the external tools will Start and Stop that Solutions own instance of FitNesse, as long as they too are kept in a folder called ‘Specifications’.

The first run
The first time you start FitNesse, the jar file will be extracted to create the Wiki. You saw this in the earlier post. Once everything is extracted the FitNesse server starts running. It all looks like this



First view of the Wiki
With FitNesse running, it’s time to take a look at our Wiki. Select the FitNesseBrowser tool from the Tools menu. What you see should look something like this



Not what you were expecting? Were you thinking you’d see the FitNesse Front Page?

What we’ve done here is make the Tool jump to a specific page in the Wiki, and not going to the regular Front Page. This avoids the need to navigate to our tests every time we start the Wiki.

Since we haven’t created this page yet we’re asked to edit it. So, let’s do that, copy and paste the following code, overwriting the existing contents of the page.

!path bin\Calculator.Specifications.dll

!|import |
|Calculator.Specifications.Fixtures|

This should do simple arithmetic

!|Do Simple Maths |
|A |B |Op|Result?|
|1.0|2.0|+ |3.0 |

Save those changes, but we’re not done with this page yet. Click on the Properties button and change the Page type to ‘Test’. Save the properties and you’ll now see that all important Test Button.



You can click it if you like but it won’t work yet. We have one more piece of setup to do first.

In your Browser, navigate to the URL


http://localhost:9092/root

Edit the ‘root’ page and overwrite the contents with the following

!define TEST_SYSTEM {slim}
!define COMMAND_PATTERN {%m -r fitSharp.Slim.Service.Runner,bin\fitsharp.dll %p}
!define TEST_RUNNER {bin\Runner.exe}

This tells FitNesse to use SLiM which is one of the two protocols that FitNesse can use for linking tests to code. We’re running the implementation of SLiM provided by fitsharp which lets us work with .Net assemblies.

Yes, we could have inserted this bit of configuration at the top of every Test Page, but by putting it in root we can forget about it and stop cluttering up our tests.

Save this page and return to


http://localhost:9092/AcceptanceTests

Now when you click Test, it should work. We have a Test that runs. Admittedly it’s a failing Test, but that’s what we want as a first step.



To get this test to pass we need to look at our code. Our Calculator class throws NotImplementedExceptions rather than implement the actual required logic.

public class Calculator
{
public static decimal Add(decimal a, decimal b)
{
throw new NotImplementedException("Add");
}

public static decimal Subtract(decimal a, decimal b)
{
throw new NotImplementedException("Subtract");
}

public static decimal Multiply(decimal a, decimal b)
{
throw new NotImplementedException("Multiply");
}

public static decimal Divide(decimal a, decimal b)
{
throw new NotImplementedException("Divide");
}
}

Let’s fix that Add method, rebuild and retest.

public static decimal Add(decimal a, decimal b)
{
return a + b;
}



If you’ve made it this far you now have a Solution that has a project under test and a project that has the tests themselves along with all the binaries needed to run FitNesse and use it to test .Net code.

We’ve set up some External Tools in Visual Studio that will make life a little easier.

If you’re a little unsure about how this all hangs together, don’t worry. Over the remaining posts in this series I’ll did a little deeper into the things you can do with FitNesse, and along the way you’ll learn what all the parts of the puzzle are. All posts will use this Solution structure as a basis.

Installing FitNesse

This entry is part 2 of 5 in the series FitNesse

Downloads
FitNesse – The FitNesse application (wiki) with built-in web server.
FitSharp – Library that allows FitNesse to talk to .Net applications.

Options for Setup
There are a number of different ways to set up FitNesse. How you proceed will depend on the nature of your development process and personal preferences. We’ll look at the simplest possible installation in this post. In future posts we’ll look at the other possibilities.

For the purposes of this post we are going to focus on getting a single instance of FitNesse running on your development machine, so that you can learn how to use it. Later we’ll look at how to create a distinct installation of FitNesse for each Solution, and ultimately we’ll look at more advanced topics such as how to give users the ability to edit and create tests, and how to build FitNesse into a Continuous Integration process.

One installation
This approach involves installing FitNesse in a single known location, e.g. C:\DevTools\FitNesse\ and creating all our tests for various projects in subsections within that one Wiki.

Step 1. Install FitNesse
To install a single FitNesse instance, simply download the FitNesse.jar file using the link at the top of this post, and place in a folder of your choice. I keep mine in C:\DevTools\FitNesse. Don’t worry about this too much, once it’s installed you’ll access FitNesse via your browser and you won’t really care too much about where it’s physically located on your hard drive.

FitNesse is distributed as a JAR file, and on first run, the contents of the file are extracted, creating the entire directory structure that makes up the FitNesse Wiki.

Check that it’s working
With your FitNesse jar file in place, you just need to run it. This can be done from the command line.

C:\DevTools\FitNesse>java -jar fitnesse.jar -p 9092

Assuming you have java installed and on your path this should run. On the first run you should see a message confirming that it is unpacking FitNesse.

When FitNesse is running you can view it using your browser, by visiting


http://localhost:9092

Note the port number is set using the -p switch. I’ve used 9092 here. If you don’t specify a port FitNesse will run on port 80, and you won’t have to specify the port in the url.

Personally I like specifying a port for these kinds of apps. It avoids the problem of everything wanting to run on port 80, and I get used to FitNesse being on 9092.

The command to start FitNesse can be placed in a batch file. I use a file called StartFitNesse.bat which I place in the same folder as the FitNesse .jar file.

FitNesse switches

If you want to get a little clever you can try out some of the optional switches that configure FitNesse. We’ll poke into some of these in later posts.

Usage: java -jar fitnesse.jar [-pdrleoa]
        -p <port number> {80} or {9123 if -c}
        -d <working directory> {.}
        -r <page root directory> {FitNesseRoot}
        -l <log directory> {no logging}
        -e <days> {14} Number of days before page versions expire
        -o omit updates
        -a {user:pwd | user-file-name} enable authentication.
        -i Install only, do not run fitnesse after install.
        -c <command> Run the command (same as restful url) and then exit.

Return status is the number of test pages that failed as a result of the command.

Assuming you’ve done everything right, your browser should load the FitNesse Homepage. Congratulations, you have installed FitNesse. It’s a Wiki application running in it’s own little web server. You can play around, follow the links and see where they take you.

With FitNesse running, the next challenge is to write some tests and execute them against some .Net code. Which sounds like a job for Fitsharp.

Step 2. Install FitSharp

To install FitSharp all you need to to is download the zip file from the page linked at the top of this post. Extract the contents of the zip file you downloaded into a folder of your choice. I keep mine in C:\DevTools\FitSharp. Alternatively you could store it as a sub folder of FitNesse e.g. C:\DevTools\FitNesse\Fitsharp.

Once you’ve extracted FitSharp, you’re done. When the time comes to use it, we’ll tell FitNesse where to find it. We won’t write any .Net code yet, we’ll get to that in the next post. This is just about getting everything set up.

One installation per project
This idea of using one FitNesse installation for perhaps multiple projects is all very well, and we could make it work, but there is an alternative. I’ll thank Jeff Kwak for the inspiration here. His suggests including a FitNesse installation in every solution that needs it. This way each Wiki is specific to one project, and more importantly, the Wiki and all the related libraries automatically fall under source control.

I like this approach a lot. I’m going to adopt it for the rest of the tutorial posts. There’s no point in me writing it up and duplicating Jeff’s efforts, head on over to his site and see what he’s done. I’ll meet you back here on our next post, when we actually get down to business and write some C# code.

FitNesse with .Net

This entry is part 1 of 5 in the series FitNesse

Why another tutorial on installing and using FitNesse with .Net? Well, because I had a lot of trouble installing and using FitNesse with .Net. That may be an issue with the existing tutorials, or, it be an issue with me. Hopefully with these posts I can spare you some of the pain I encountered.

First things first. The source for all things FitNesse is here. There you’ll find lots of tutorials, samples and other useful info. In fact, if you stick at it you’ll get up and running using just the information on that site, but if you’re in any way like me you may find you slip off the happy path a few times. That’s where the tutorial you’re reading comes in.

History
Before you wrap your head around FitNesse, it helps to have an understanding of where it came from. The Framework for Integrated Testing (FIT) was developed by Ward Cunningham. The origins of FIT go back to a project where Cunningham discovered that he could allow users to enter test scenarios into a spreadsheet, and with a bit of coding he could make those test scenarios execute against the project code.

FIT is a publicly distributable version of that idea. Requirements can be written in a standard word document. Specific “examples” or “Test Cases” are created as Tables, and FIT enables us to hook that document up to executable code, run the tests and actually insert the results back into the Word Document.

FitNesse takes this notion a step further and provides a self contained Wiki complete with it’s own web server. Requirements can be entered into the Wiki or edited by anyone with access. A number of styles of tables give a means of demonstrating requirements using Sample Data. Like FIT, the FitNesse wiki can be “run” against our code base, and the results of tests inserted back into the Wiki.

Fit and SLiM
Originally FitNesse used Fit as a means of hooking the tests (in the Wiki) up to executable code. Later the developers of FitNesse set about replacing Fit. The result was SLiM.

Either Fit or SLiM can be used and some would argue that they each have benefits. As I progress through this series of posts I will cover both options.

I’ll begin with SLiM, for no other reason than I found it very easy to get started with when I first approached FitNesse. When we’re comfortable using FitNesse with SLiM we’ll cover some of the same ground using Fit and explore where the two approaches differ.

FitNess in Action
So, enough waffle, what does FitNesse look like in practice? The following screenshot shows a Decision Table, just waiting to be run. A Decision Table is one of a number of different types of tables that FitNesse/SLiM provides as a means of capturing, or to be more accurate, illustrating requirements through tests.



The eagle eyed among you will notice that one of those examples looks like it’s expecting the wrong result. When we run our tests that should give us something worthwhile to look at.

Take a look at the left Nav Bar, most of those buttons do interesting things, but for now we’re just interested in the ‘Test’ button. If we click it, our FitNesse tests spring to life, execute themselves against our code base, fill in the results in our table, and highlight the passes and fails in green and read. Or to say it more simply with a picture…this happens…



Notice that one of the tests turns red. Dividing 100 by 4 doesn’t give 26. This isn’t highlighting a bug in the code, it’s highlighting a bug in the test, which can and does also happen from time to time. The point here is that when our expectations aren’t met, we’re told about it.

What just happened?
How did the table know where to find our code and execute it?
How does it communicate with our code, passing parameters to the code, and getting back results? What’s all the text at the top of the screen about?

These and many more questions will be answered during this series of posts. I hope you’ll stay with me. Next up, we install FitNesse and a few more bits and pieces that we need to make it play nice with .Net languages like C#.

Fit Tables and SLiM Tables
Before I close this post let me return to that issue of Fit vs SLiM once more. A big practical difference between the two is the types of tables we can use to define tests. In the example above we used a Decision Table which is a feature of SLiM. The Equivalent Fit table is known as a ColumnFixture.

We’ll start by working through all the tables that SLiM has to offer, then we’ll work through the equivalent Fit tables.

GitHub Collaborative Learning


I’m embarking on something of an experiment in an effort to better understand Git and GitHub.

I’m recruiting a few fellow Git Noobs in the hopes that a little bit of collaborative learning will get us to where we want to be a little quicker. Think of it as a distributed study group.

The distributed and collaborative nature of GitHub means that for me at least, this seems like the most logical approach to understanding and getting comfortable with it.

The plan is simple.

Setup

  1. Sign up a team of GitHub Noobs.
  2. Make sure everyone has a GitHub account
  3. Make sure everyone has Client software
  4. Provide counselling for those traumatised by step 3

Project

  1. Each team member creates a simple project
  2. Each team member creates a repository for their project
  3. Each team member a grabs a clone of each of the other projects.

Play Time

  1. Team members play with the various projects.
  2. Make local changes to the projects.
  3. Issue pull requests to the other team members.
  4. Deal with Pull Requests from other team members
  5. Try to mess things up by stepping on each others toes

At each step in the process we’ll have a number of perspectives of the same activities, ideally members would blog about what they are doing/learning, but that isn’t essential.

The group will obviously be there to answer specific questions for each other, and since everyone is at the same stage in the process we should able to help each other through any problems that arise.

This is an experiment, it should take no more than a few days to a week to get through the exercise. If it turns out to be a useful way of studying a new technology then it can serve as a template for some future study groups.

If you are interested in participating, leave a comment here, or find me on twitter (@richardadalton). The more Noobs in our hive the better.

If you’re not a Noob but would like to get involved in some sort of mentoring capacity, get in touch.

Mind Mapping

I’ve been playing with mind mapping recently as a way of organizing my thinking on sometimes very broad subjects. As an example I’ve uploaded a Software Engineering mind map to Mindmeister.com.

This mindmap is partly a way of remembering the various technologies that I’ve worked with or know about, and partly a todo list of technologies that I’d like to look at.

I was going to create two maps where I would migrate items from one map to the other as I learned about them, but in truth that would be pointless. If you haven’t used a technology in the last few months, it will be as good as new to you should you try to use it again.

With that in mind I would need to constantly review the “things I know” map, to move items back to the “things I’d like to know” map.

Something I would like to do is split this map into 4 or 5 maps, one representing each of the major branches. It’s getting a bit unwieldy at the moment. If I do that I would need simple drill down and up linking between the maps.

The greatest benefit for me right now is that when I hear about a new product or technology, I can access the map from any machine and add a reminder to myself to look into it in the future, and by adding it to the appropriate place on the map, it will be there should I ever need to use something in that space.

For example, at DDD South West I was introduced to NCrunch. So, NCrunch gets added to the map in the Testing area. Now, whenever I glance at the testing area of the Map, NCrunch is there, along with all the other related tools.

Switch to our mobile site