2 Creating a Script Fixture - essenius/FitNesseFitSharpGameManagementDemo GitHub Wiki

We saw on Executing Scripts Using Script Tables how to use Script Tables in FitNesse. On this page, we will show how to create a fixture for it. We'll assume you have set up your own fixture as explained in the readme.

We are going to add a fixture to the class library named GameManagementFixtures. Since the script was called player management driver, we need to call the fixture PlayerManagementDriver. So, we will create a class PlayerManagementDriver with method AddPlayerWithSkill.

using System.Collections.Generic;
using System.Linq;

namespace GameManagementFixtures
{
    public class PlayerManagementDriver
    {
        public static bool AddPlayerWithSkill(string playerName, string skillLevel) => true;
    }
}

This is the simplest implementation that compiles and communicates well with FitNesse. Of course, it doesn’t do anything yet. We’re just making sure that the setup works.

To make sure that FitNesse can find the fixture assembly, create a file config.xml with the following content in project GameManagementFixtures, and make it copy to the output directory on build.

<?xml version="1.0" encoding="utf-8" ?>
<suiteConfig>
  <ApplicationUnderTest>
    <AddAssembly>GameManagementFixtures.dll</AddAssembly>
    <AddNamespace>GameManagementFixtures</AddNamespace>
  </ApplicationUnderTest>
  <Settings>
    <Runner>fitSharp.Slim.Service.Runner</Runner>
  </Settings>
</suiteConfig>

If you have FitNesse running, stop it by pressing Ctrl-C in its command window. Then change the current directory to the build output folder of the C# solution, and restart FitNesse:

cd /D %LOCALAPPDATA%\FitNesse\GameManagement\GameManagementFixtures\bin\release\net5.0
java -jar c:\Apps\FitNesse\fitnesse-standalone.jar -d %LOCALAPPDATA%\FitNesse

Run the test by entering http://localhost:8080/GameManagementTest?test in a browser. If all goes well, you will see the following as the first few lines: First test run

FitNesse warns that the PlayerCount method does not exist. So the next thing is to create that method, again with the simplest implementation that compiles. We also need a method PlayerIfSkill:

        public static int PlayerCount() => 0;

        public static string PlayerIfSkill(string playerName) => "null";

After building, this is what the test result should look like now: Test run without exception

Good – so we have the right fixture structure in place now. Not all assertions are right yet, but that makes sense – we didn’t build the system yet. But at least we know in enough detail what it should be capable of doing.

The Player Management Subsystem

We do a quick design session for the player management subsystem. The player list looks like a collection. However, it would make more sense to take a collection that doesn’t allow duplicates. A HashSet seems a good fit. We will base it on a Player object.

Let’s first make a class that represents a player. In the project GameManagement, we create a class called Player. Besides the obvious Name and Level properties, we also redefine the Equals() method: we define two Player objects as being equal if they have the same name. Further we redefine GetHashCode() to make sure that we create a hash based on the unique property (name).

namespace GameManagement
{
    public class Player
    {
        public Player(string playerName, string skillLevel)
        {
            Name = playerName;
            Level = skillLevel;
        }

        public string Name { get; }
        public string Level { get; set; }
        public override bool Equals(object obj) => 
            obj is Player other && Name.Equals(other.Name);
        public override int GetHashCode() => Name.GetHashCode();
    }
}

Now we can use it in a HashSet. Create a class called PlayerCollection with the following content:

using System.Collections.Generic;

namespace GameManagement
{
    public class PlayerCollection : HashSet<Player>
    {
    }
}

Now we have the basic player management structure in place, let’s update the fixture to start using it. Go to GameManagementFixtures and add a dependency to GameManagement.

Go back to PlayerManagementDriver and change it to look as follows:

using GameManagement;

namespace GameManagementFixtures
{
    public class PlayerManagementDriver
    {
        private static readonly PlayerCollection Players = new PlayerCollection();

        public static bool AddPlayerWithSkill(string playerName, string skillLevel)
        {
            var player = new Player(playerName,skillLevel);
            return Players.Add(player);
        }

        public static int PlayerCount() => Players.Count; 
        public static string PlayerIfSkill(string playerName) => "null";
    }
}

Build the solution and run the FitNesse page again. You will see that more tests are now passing.

Test run with Player if Skill null

The second registration of user John is now rejected (i.e., the test passes), the player count shows the right values, and the second player count now passes as well. The skill checking tests are still failing – as expected, because we didn’t connect that to the subsystem yet. So now let’s work on the skills check. One missing piece is being able to search a player object by name, so we can return the skill level. We will implement that search as a method on PlayerCollection:

using System.Collections.Generic;
using System.Linq;

namespace GameManagement
{
    public class PlayerCollection : HashSet<Player>
    {
       public Player FindOnName(string playerName)
        {
            return (from Player p in this where p.Name == playerName select p)
                   .FirstOrDefault();
        }
    }
}

Now update the PlayerIfSkills method in PlayerManagementDriver as follows:

        public static string PlayerIfSkill(string playerName)
        {
            var player = Players.FindOnName(playerName);
            return player == null ? "null" : player.Level;
        }

Build, and run the test again. It seems we are there! Since all tests pass, you are done with this part of the work and you show the result to the business rep.

Test run all passing

“Cool, good job.” he says. “Now I want to see a list of people who have a certain level. We can then use that list later to see who can play against each other. First, let’s check if the list of intermediate level players consists of Bill and Julie.”

We'll discuss how to do that on the page Dealing with multiple results using Query Tables

⚠️ **GitHub.com Fallback** ⚠️