writing the first acceptance test for robocode

In previous posts I've set up an acceptance testing framework that enables me to run a battle and I'm now ready to write my first acceptance test.

To recap, my acceptance test that I want is:

In a one round battle, fighting against a single robot that does not move, the slayer robot should win.

So here's how I want to write that:

    public class in_a_one_round_battle_fighting_against_a_single_robot_that_does_not_move
    {
        Establish context = () =>
        {
            battle = new Battle("in_a_one_round_battle_fighting_against_
a_single_robot_that_does_not_move"
); battleRunner = new BattleRunner(new ProcessRunner(),
new BattleResultParser(new BattleResultsFileReader())); }; Because of = () => returnedResults = battleRunner.Run(battle); It should_result_in_the_slayer_robot_winning = () => returnedResults.Where(r => r.RobotName.Contains("SlayerRobot")) .Single() .Position.ShouldEqual(1); static Battle battle; static BattleRunner battleRunner; static IEnumerable<BattleResult> returnedResults; }

Now, I manually create a battle file in the battle directory with the same name and set up the battle:

oneroundbattle

I'm ready to go with the first acceptance test and when I run it, the battle runner runs the process, the results are parsed and the test fails with the following:

firstacceptancefails

My acceptance test fails because my robot is in second place - the acceptance testing framework works!

I now recognise some areas that I can abstract some of the set up so here's the first process of streamlining as I write a base acceptance specification:

    public class acceptance_test
    {
        Establish context = () => battleRunner = new BattleRunner(new ProcessRunner(), 
                                       new BattleResultParser(new BattleResultsFileReader()));

        Because of = () =>
                         {
                             battleName.ShouldNotEqual(string.Empty);  //battleName must be set 
                             battle = new Battle(battleName);
                             returnedResults = battleRunner.Run(battle);
                         };

        protected static string battleName = string.Empty;
        protected static IEnumerable<BattleResult> returnedResults;
        static Battle battle;
        static BattleRunner battleRunner;
    }

This base acceptance class now enables me to have a very small amount of code to write for an acceptance test:

    public class in_a_one_round_battle_fighting_against_a_single_robot_that_does_not_move : 
acceptance_test { Establish context = () => battleName =
"in_a_one_round_battle_fighting_against_a_single_robot_that_does_not_move"; It should_result_in_the_slayer_robot_winning = () => returnedResults.Where(r => r.RobotName.Contains("SlayerRobot")) .Single() .Position.ShouldEqual(1); }

I can make this even shorter now by adding in an extension method:

    public static class BattleResultCollectionExtensions
    {
      public static BattleResult SlayerRobotResult(this IEnumerable<BattleResult> battleResults)
      {
          return battleResults.Where(r => r.RobotName.Contains("SlayerRobot")).Single();
      }
    }

Now my acceptance test looks great:

    public class in_a_one_round_battle_fighting_against_a_single_robot_that_does_not_move : 
acceptance_test { Establish context = () => battleName =
"in_a_one_round_battle_fighting_against_a_single_robot_that_does_not_move"; It should_result_in_the_slayer_robot_winning = () => returnedResults.SlayerRobotResult().Position.ShouldEqual(1); }

I could go further and make the SlayerRobotResult part of the base acceptance, but I'll leave this for now as I'm happy with how the test looks.

I now have a quick acceptance testing framework where I can ensure that I do not regress the overall outcome of certain battle situations and this series of posts illustrated how you can think out of the box a little and make white box acceptance testing possible up front before you develop the main parts of your application.

At a future date we may want to look at doing this in-process as opposed to launching an external process - Pavel and Jason have comments about using a jni4net bridge to perhaps accomplish this and it would be great if an acceptance testing mechanism could be included as part of the robocode distribution.

Posted at at 7:27 AM on Tuesday, July 27, 2010 by Posted by Justin Davies | 1 comments Links to this post   | Filed under: , ,

wrapping up the battle runner for robocode

In my last post I had written the parsing of the results file and I have a few things left to do to wrap this piece of development.

The first thing is a concrete version of the IBattleResultsFileReader where I abstracted the reading of the file and producing a string array.
This is a very simple implementation and I can drive this without testing as it is a trivial implementation using the BCL. Historically I may have been zealous in my test driven process and written an integration test, but from experience I find that if you have abstracted out to this level where the implementation is very trivial there is little to be gained from running integration tests on that code - it can be seen to work through observation. If I care about very high code coverage I may have to then exclude that class though.
The resulting code is straightforward:

namespace TeamSlayer.Battles
{
    public class BattleResultsFileReader : IBattleResultFileReader
    {
        public string[] ReadResultFrom(Uri file)
        {
            return File.ReadAllLines(file.LocalPath);
        }
    }
}

Finally I need to integrate the parsing and reading of the file into the BattleRunner, so I revisit the specification for that class (only the relevant code is shown below):

    public class when_the_battle_runner_runs_a_battle
    {
        Establish context = () =>
        {
            ...
            theExpectedResults = new List<BattleResult>();
            battleResultParser = MockRepository.GenerateStub<IBattleResultParser>();
            battleResultParser.Stub(p => p.ReadResultsFrom(null)).IgnoreArguments()
                              .Return(theExpectedResults);

            battleRunner = new BattleRunner(processRunner, battleResultParser);
            ...
        };

        Because of = () => results = battleRunner.Run(battle);

        It should_tell_the_battle_parser_to_parse_the_results_for_the_battle = () =>
            battleResultParser.AssertWasCalled(p => p.ReadResultsFrom(battle));

        It should_return_the_results_from_the_parser = () =>
            results.ShouldEqual(theExpectedResults);

        static IBattleResultParser battleResultParser;
        static IEnumerable<BattleResult> theExpectedResults;
    }

I've replaced the original observation that it should return non null results with one that expects the results from the battle result parser to be returned. I also ensure that the battle result parser is called.

Here's an interesting one though - when pairing with a colleague recently we had the above situation where I was asserting that the call is made and that the value returned from the stub is the one returned from the class under test. The discussion then centred around whether the first was implied by the second observation - the fact that the result returned is the same as the one from the stub, you surely don't need the first observation right?

In this case that is perfectly true, you could get away with just having the second, however I prefer to be explicit as they are two different observations, it just happens for the moment to be a straight pass through.

What happens if I choose to only have the second observation and at a later date I manipulate the specification and the BattleRunner so that it no longer returns the battle results but does something else with them instead? Do I then at that stage re-evaluate the specification, realise that I had this missing observation that checks for the the call to the parser and put it in at that later date?

This is too risky for me, I'd rather have both observations in from the start leaving it abundantly clear for future revision what is happening in the interaction between the two classes.

Here is the final implementation of the BattleRunner:

namespace TeamSlayer.Battles
{
    public class BattleRunner
    {
        readonly IProcessRunner processRunner;
        readonly IBattleResultParser battleResultParser;

        public BattleRunner(IProcessRunner processRunner, IBattleResultParser battleResultParser)
        {
            this.processRunner = processRunner;
            this.battleResultParser = battleResultParser;
        }

        public IEnumerable<BattleResult> Run(Battle battle)
        {
            var startInformation = new ProcessStartInfo();
            startInformation.FileName = BattleConstants.BattleFilesLocation + "run_battle.bat";
            startInformation.WorkingDirectory = BattleConstants.RobocodeWorkingDirectory;
            startInformation.Arguments = string.Format("-battle {0} -results {1}",
                                                       battle.BattleFile,
                                                       battle.BattleResultFile);

            processRunner.RunProcess(startInformation, 60);

            return battleResultParser.ReadResultsFrom(battle);
        }
    }
}

Posted at at 7:22 AM on Friday, July 23, 2010 by Posted by Justin Davies | 1 comments Links to this post   | Filed under: , ,

parsing robocode results

In previous posts I've been exploring acceptance testing my robocode robot and I'm at a stage where I can run a robocode battle and produce a results file. I therefore need to begin parsing the robocode results file.
Here's what that file looks like:

battle_results

This text file has a line per robot and many fields that span to the right which I'll explore as I develop the parser.
Most of the file is tab delimited so I should be able to do much of my parsing easily.

So in thinking about my first specification for a BattleResultParser I would like to work against a static string rather than repeatedly read a text file so I'm going to abstract the reading of the file from the BattleResultsParser. I also know that I need to integrate it into the BattleRunner so I'll need an interface seam on the BattleResultsParser itself:

    public class when_parsing_a_battle_result
    {
        Establish context = () =>
        {
            battle = new Battle("kjbasd8908");

            battleResultFileReader = MockRepository.GenerateStub<IBattleResultFileReader>();
            battleResultParser = new BattleResultParser(battleResultFileReader);
        };

        Because of = () => battleResultParser.ReadResultsFrom(battle);

        It should_ask_the_battle_result_file_reader_to_read_the_results_file = () =>
            battleResultFileReader.AssertWasCalled(r =>
                 r.ReadResultFrom(battle.BattleResultFile));

        static IBattleResultParser battleResultParser;
        static Battle battle;
        static IBattleResultFileReader battleResultFileReader;
    }

I'm creating a stub of this new file reader and have declared the BattleResultParser as an interface type in the specification so I can ensure the BattleRunner can use it at an abstract level. Here is the first part of the implementation:

    public interface IBattleResultParser
    {
        IEnumerable<BattleResult> ReadResultsFrom(Battle battle);
    }

    public class BattleResultParser : IBattleResultParser
    {
        IBattleResultFileReader battleResultFileReader;

        public BattleResultParser(IBattleResultFileReader battleResultFileReader)
        {
            this.battleResultFileReader = battleResultFileReader;
        }

        public IEnumerable<BattleResult> ReadResultsFrom(Battle battle)
        {
            var resultLines = battleResultFileReader.ReadResultFrom(battle.BattleResultFile);
            return null;
        }
    }

    public interface IBattleResultFileReader
    {
        string[] ReadResultFrom(Uri file);
    }

I can now stub the content returned by the file reader:

    public class when_parsing_a_battle_result
    {
        Establish context = () =>
        {
            var resultLines = new string[4]
            {
                "Results for 10 rounds",
                "Robot Name\t    Total Score    \tSurvival\tSurv Bonus\tBullet Dmg\tBullet",
                "1st: sample.SittingDuck\t600 (100%)\t500\t100\t0\t0\t0\t0\t10\t0\t0\t",
                "2nd: TeamSlayer.Adapter.SlayerRobot\t0 (0%)\t0\t0\t0\t0\t0\t0\t0\t10\t0\t"
            };

            battle = new Battle("kjbasd8908");

            battleResultFileReader = MockRepository.GenerateStub<IBattleResultFileReader>();
            battleResultFileReader.Stub(r => r.ReadResultFrom(null)).IgnoreArguments()
.Return(resultLines); battleResultParser = new BattleResultParser(battleResultFileReader); }; Because of = () => results = battleResultParser.ReadResultsFrom(battle); It should_ask_the_battle_result_file_reader_to_read_the_results_file = () => battleResultFileReader.AssertWasCalled(r =>
r.ReadResultFrom(battle.BattleResultFile)); It should_ignore_the_first_two_lines_and_bring_back_only_two_results = () => results.Count().ShouldEqual(2); static IBattleResultParser battleResultParser; static Battle battle; static IBattleResultFileReader battleResultFileReader; static IEnumerable<BattleResult> results; }

I can make this pass easily by creating a list of two battle results, so now I need a new specification to force the reading of the number of robots in the file. I therefore create a similar specification with results for five robots in the string array and I'll skip showing that here.
I now have the following implementation:

    public class BattleResultParser : IBattleResultParser
    {
        IBattleResultFileReader battleResultFileReader;

        public BattleResultParser(IBattleResultFileReader battleResultFileReader)
        {
            this.battleResultFileReader = battleResultFileReader;
        }

        public IEnumerable<BattleResult> ReadResultsFrom(Battle battle)
        {
            var resultLines = battleResultFileReader.ReadResultFrom(battle.BattleResultFile);

            var battleResults = resultLines.Where(x => !x.StartsWith("Results for") 
&& !x.StartsWith("Robot Name")); return battleResults.Select(x => new BattleResult()); } }

I'm now ready to parse each individual line, but it occurs to me that rather than treat the BattleResult as a simple value object I could pass it one line from the robot file and it would be responsible for hydrating itself.
So I move over to specifying the BattleResult class:

    public class when_creating_a_battle_result_from_a_result_line
    {
        Establish context = () => 
        {
              robotName = "asdknoij08asd";
              battleResultLine = string.Format(
                  "3rd: {0}\t600 (100%)\t500\t100\t2\t0\t0\t0\t10\t0\t0\t", robotName);
        };

        Because of = () => battleResult = new BattleResult(battleResultLine);

        It should_have_the_correct_robot_name = () => 
battleResult.RobotName.ShouldEqual(robotName); static string battleResultLine; static string robotName; static BattleResult battleResult; }

I've set up a line in the expected format from a real results file and create a new BattleResult. I then assert against the robot name. To get this to pass, the implementation is:

    public class BattleResult
    {
        public BattleResult(string battleResultLine)
        {
            RobotName = battleResultLine.Split('\t')[0].Split(':')[1].Trim();
        }

        public string RobotName { get; private set; }
    }

I continue to add to the specification and iteratively build each part of the results up. The final specification is shown below:

    public class when_creating_a_battle_result_from_a_result_line
    {
        Establish context = () => 
        {
            position = 8;
            robotName = "asdknoij08asd";
            totalScore = 546;
            totalScorePercent = 99;
            survival = 88;
            survivalBonus = 12;
            bulletDamage = 54;
            bulletBonus = 35;
            ramDamage = 91;
            ramBonus = 28;
            firsts = 2;
            seconds = 1;
            thirds = 12;

            battleResultLine = string.Format(
                  "{0}rd: {1}\t{2} ({3}%)\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\t",
                  position, robotName, totalScore, totalScorePercent, survival, survivalBonus,
                  bulletDamage, bulletBonus, ramDamage, ramBonus, firsts, seconds, thirds);
        };

        Because of = () => battleResult = new BattleResult(battleResultLine);

        It should_have_the_correct_position = () => 
battleResult.Position.ShouldEqual(position); It should_have_the_correct_robot_name = () =>
battleResult.RobotName.ShouldEqual(robotName); It should_have_the_correct_total_score = () =>
battleResult.TotalScore.ShouldEqual(totalScore); It should_have_the_correct_total_score_percentage = () => battleResult.TotalScorePercentage.ShouldEqual(totalScorePercent); It should_have_the_correct_survival = () =>
battleResult.Survival.ShouldEqual(survival); It should_have_the_correct_survival_bonus = () =>
battleResult.SurvivalBonus.ShouldEqual(survivalBonus); It should_have_the_correct_bullet_damage = () =>
battleResult.BulletDamage.ShouldEqual(bulletDamage); It should_have_the_correct_bullet_bonus = () =>
battleResult.BulletBonus.ShouldEqual(bulletBonus); It should_have_the_correct_ram_damage = () =>
battleResult.RamDamage.ShouldEqual(ramDamage); It should_have_the_correct_ram_bonus = () =>
battleResult.RamBonus.ShouldEqual(ramBonus); It should_have_the_correct_number_of_first_places = () => battleResult.NumberOfFirstPlaces.ShouldEqual(firsts); It should_have_the_correct_number_of_second_places = () => battleResult.NumberOfSecondPlaces.ShouldEqual(seconds); It should_have_the_correct_number_of_third_places = () => battleResult.NumberOfThirdPlaces.ShouldEqual(thirds); static string battleResultLine; static string robotName; static BattleResult battleResult; static int totalScore, position, totalScorePercent, survival, survivalBonus; static int bulletDamage, bulletBonus, ramDamage, ramBonus, firsts, seconds, thirds; }

And I'll end this post with the final implementation to pass these specifications:

    public class BattleResult
    {
        public BattleResult(string battleResultLine)
        {
            var results = battleResultLine.Split('\t');

            Position = GetPositionFrom(results[0]);
            RobotName = GetRobotNameFrom(results[0]);
            TotalScore = GetTotalScoreFrom(results[1]);
            TotalScorePercentage = GetTotalScorePercentageFrom(results[1]);
            Survival = Convert.ToInt32(results[2]);
            SurvivalBonus = Convert.ToInt32(results[3]);
            BulletDamage = Convert.ToInt32(results[4]);
            BulletBonus = Convert.ToInt32(results[5]);
            RamDamage = Convert.ToInt32(results[6]);
            RamBonus = Convert.ToInt32(results[7]);
            NumberOfFirstPlaces = Convert.ToInt32(results[8]);
            NumberOfSecondPlaces = Convert.ToInt32(results[9]);
            NumberOfThirdPlaces = Convert.ToInt32(results[10]);
        }

        public int Position { get; private set; }
        public string RobotName { get; private set; }
        public int TotalScore { get; private set; }
        public int TotalScorePercentage { get; private set; }
        public int Survival { get; private set; }
        public int SurvivalBonus { get; private set; }
        public int BulletDamage { get; private set; }
        public int BulletBonus { get; private set; }
        public int RamDamage { get; private set; }
        public int RamBonus { get; private set; }
        public int NumberOfFirstPlaces { get; private set; }
        public int NumberOfSecondPlaces { get; private set; }
        public int NumberOfThirdPlaces { get; private set; }

        int GetPositionFrom(string place)
        {
            //assuming no more than 9 robots
            return Convert.ToInt32(place.Substring(0, 1));
        }

        string GetRobotNameFrom(string result)
        {
            //comes in as "1st: sample.Tracker"
            return result.Split(':')[1].Trim();
        }

        int GetTotalScoreFrom(string result)
        {
            //comes in as "3600 (88%)"
            return Convert.ToInt32(result.Split('(')[0]);
        }

        int GetTotalScorePercentageFrom(string result)
        {
            //comes in as "3600 (88%)"
            return Convert.ToInt32(result.Split('(')[1].Split(')')[0].Replace("%", ""));
        }
    }

Posted at at 8:17 AM on Wednesday, July 21, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: ,

continuing the battle classes for robocode

In a previous post I started creating the framework for running acceptance tests through robocode and I had created my definition of a battle in a Battle class and had defined a BattleRunner that would set up the start information required for running the robocode process.

I'll now continue with implementing the concrete process runner but as this is a very lightweight class that simply starts a process I'm not going to write a specification for it directly. Instead I'm going to write an integration test that will allow me to see if it does indeed start the process as I intend:

    public class when_integrating_the_process_runner_with_the_battle_runner
    {
        Establish context = () =>
        {
            battleName = "llk0i908";
            battle = new Battle(battleName);

            battleRunner = new BattleRunner(new ProcessRunner());
        };

        It should_run_the_process = () => battleRunner.Run(battle);

        static Battle battle;
        static string battleName;
        static BattleRunner battleRunner;
    }

I'm setting up a new battle runner with the concrete ProcessRunner and in my "It" delegate am running the battle - ordinarily this would be in the "Because" delegate, but we need an "It" delegate for MSpec to pick the test up so I moved the code that exercises the process.  This test is merely a visual aid to see if the process is executed through a shell window - at present it is not, so I code the ProcessRunner:

    public class ProcessRunner : IProcessRunner
    {
        public void RunProcess(ProcessStartInfo processStartInfo)
        {
            var process = Process.Start(processStartInfo);
        }
    }

Now when I run this test, the command window fires up:

integrating_the_process_runner 

This is working exactly as intended - it locates the run_battle.bat file and the arguments are injected into the java call for the battle file and the battle results file locations.
It then runs robocode, but our test battle file is not found and this is totally expected (and I don't really want to run one at this stage) - I now have confidence that this integration between BattleRunner and ProcessRunner works they way I intended.

The next step is to look at parsing the results and returning them when we run a battle - I therefore need a new BattleResult class and I will return a collection of them when Run(battle) is called. Each item in the collection will represent a result for a particular robot showing their place in the battle and their score.
So I change the specifications for BattleRunner (and only new/changed code is shown below for brevity)

    public class when_the_battle_runner_runs_a_battle
    {
        ...

        Because of = () => results = battleRunner.Run(battle);

        It should_return_battle_results = () => results.ShouldNotBeNull();

        static BattleRunner battleRunner;
        static IProcessRunner processRunner;
        static Battle battle;
        static ProcessStartInfo processStartInformation;
        static IEnumerable<BattleResult> results;
    }

And I can implement this as follows for the time being:

    public class BattleRunner
    {
        readonly IProcessRunner processRunner;

        public BattleRunner(IProcessRunner processRunner)
        {
            this.processRunner = processRunner;
        }

        public IEnumerable<BattleResult> Run(Battle battle)
        {
            var startInformation = new ProcessStartInfo();
            startInformation.FileName = BattleConstants.BattleFilesLocation + "run_battle.bat";
            startInformation.WorkingDirectory = BattleConstants.RobocodeWorkingDirectory;
            startInformation.Arguments = string.Format("-battle {0} -results {1}",
                                                       battle.BattleFile,
                                                       battle.BattleResultFile);

            processRunner.RunProcess(startInformation);

            return new List<BattleResult>();
        }
    }

I'm nearly ready to move onto specifying exactly how to read the results, but I've noticed something when running the manual integration test - the test is over well before the command from the .bat file finishes - therefore my results will not be available to assert against in any acceptance test as the robocode process will still be running.
I need to put a wait mechanism in and again, only changes to the specification are shown below:

    public class when_the_battle_runner_runs_a_battle
    {
        Establish context = () =>
        {
            ...
            processRunner.Stub(p => p.RunProcess(null, 0))
                         .IgnoreArguments().Do(RecordProcessStartInfoUsedInCall);
            ...
        };


        static Action<ProcessStartInfo, int> RecordProcessStartInfoUsedInCall = (s, i) => 
            processStartInformation = s;

        Because of = () => results = battleRunner.Run(battle);

        It should_tell_the_process_runner_to_run_a_new_battle_process = () =>
            processRunner.AssertWasCalled(p => p.RunProcess(Arg<ProcessStartInfo>.Is.NotNull, 
                                                            Arg<int>.Is.GreaterThan(0)));
    }

I've added an integer to the signature of the RunProcess() method, so I can now add my implementation:

    public class BattleRunner
    {
        public IEnumerable<BattleResult> Run(Battle battle)
        {
            ...
            processRunner.RunProcess(startInformation, 60);

            return new List<BattleResult>();
        }
    }

    public class ProcessRunner : IProcessRunner
    {
        public void RunProcess(ProcessStartInfo processStartInfo, int numberOfSecondsToWait)
        {
            var process = Process.Start(processStartInfo);
            process.WaitForExit(numberOfSecondsToWait * 1000);
        }
    }

Now when I run the integration test, I can see that the test does wait for the process to end and my results should be available to be read and passed back to my acceptance tests. I also verify that it took only 6.83 seconds and not the full 60 seconds wait period the BattleRunner passes through.

My next robocode post will delve into parsing the results file produced by robocode.

Posted at at 7:37 AM on Monday, July 19, 2010 by Posted by Justin Davies | 3 comments Links to this post   | Filed under: , ,

writing a battle runner for robocode

As part of setting up acceptance testing for my robocode robot, I need to be able to run a battle from each acceptance test that I write and I therefore need to create some code that will facilitate this. I've got an idea about how I want this to take shape:

Battle - a class that holds convention led battle information from a name provided by the acceptance test
BattleRunner - a class that will run a particular battle
BattleReader - a class that will read the results of a given battle
BattleResult - a class representing an individual robot's result in the battle

So I start as usual with a specification:

    public class when_creating_a_battle
    {
        Establish context = () => battleName = "mk77askdnoasid98asd";

        Because of = () => battle = new Battle(battleName);

        It should_contain_the_battle_name_it_was_created_with = () =>
            battle.BattleName.ShouldEqual(battleName);
        
        static Battle battle;
        static string battleName;
    }

This is very straight forward:

    public class Battle
    {
        public Battle(string battleName)
        {
            BattleName = battleName;
        }

        public string BattleName { get; private set; }
    }

I now want this battle file to derive the battle file name by convention from the battle name provided - I've made the BattleFile property a System.Uri and I assert it contains the relevant parts :

    public class when_creating_a_battle
    {
        Establish context = () =>
        {
            battleName = "mk77askdnoasid98asd";

            expectedPartOfTheBattleFile = string.Format("{0}.battle", battleName);
        };

        Because of = () => battle = new Battle(battleName);

        It should_contain_the_battle_name_it_was_created_with = () =>
            battle.BattleName.ShouldEqual(battleName);

        It should_by_convention_create_the_file_name_representing_this_battle = () =>
            battle.BattleFile.LocalPath.ShouldContain(expectedPartOfTheBattleFile);

        It should_use_the_known_battle_files_location_when_creating_the_battle_file = () =>
            battle.BattleFile.LocalPath.ShouldContain(BattleConstants.BattleFilesLocation);

        static Battle battle;
        static string battleName;
        static string expectedPartOfTheBattleFile;
    }

And again, straightforward implementation:

    public class Battle
    {
        public Battle(string battleName)
        {
            BattleName = battleName;
            BattleFile = new Uri( 
                string.Format(@"{0}{1}.battle",
                    BattleConstants.BattleFilesLocation,
                    battleName));
        }

        public string BattleName { get; private set; }

        public Uri BattleFile { get; private set; }
    }

    public static class BattleConstants
    {
        public const string BattleFilesLocation = 
           @"C:\dev\Projects\RoboCodeWars\TeamSlayer\Specifications\AcceptanceSpecs\battles\";
    }

I now want to do the same for the results file location:

    public class when_creating_a_battle
    {
        Establish context = () =>
        {
            battleName = "mk77askdnoasid98asd";

            expectedPartOfTheBattleFile = string.Format("{0}.battle", battleName);
            expectedPartOfTheResultFile = string.Format("{0}.result", battleName);
        };

        Because of = () => battle = new Battle(battleName);

        It should_contain_the_battle_name_it_was_created_with = () =>
            battle.BattleName.ShouldEqual(battleName);

        It should_by_convention_create_the_file_name_representing_this_battle = () =>
            battle.BattleFile.LocalPath.ShouldContain(expectedPartOfTheBattleFile);

        It should_use_the_known_battle_files_location_when_creating_the_battle_file = () =>
            battle.BattleFile.LocalPath.ShouldContain(BattleConstants.BattleFilesLocation);

        It should_by_convention_create_the_file_name_representing_the_result = () =>
            battle.BattleResultFile.LocalPath.ShouldContain(expectedPartOfTheResultFile);

        It should_use_the_known_battle_results_file_location_for_the_results_file = () =>
            battle.BattleResultFile.LocalPath
               .ShouldContain(BattleConstants.BattleResultsLocation);

        static Battle battle;
        static string battleName;
        static string expectedPartOfTheBattleFile;
        static string expectedPartOfTheResultFile;
    }

The implementation is:

    public class Battle
    {
        public Battle(string battleName)
        {
            BattleName = battleName;
            BattleFile = new Uri( 
                string.Format(@"{0}{1}.battle",
                              BattleConstants.BattleFilesLocation,
                              battleName));
            BattleResultFile = new Uri(
                string.Format(@"{0}{1}.result",
                              BattleConstants.BattleResultsLocation,
                              battleName));
        }

        public string BattleName { get; private set; }

        public Uri BattleFile { get; private set; }

        public Uri BattleResultFile { get; private set; }
    }

Now I want to move onto the battle runner and having already spiked this at an earlier stage, I know I need to prepare data for starting a process. So I'll begin with introducing an interface for a process runner. I start with a new specification:

    public class when_the_battle_runner_runs_a_battle
    {
        Establish context = () =>
        {
            processRunner = MockRepository.GenerateStub<IProcessRunner>();
            battleRunner = new BattleRunner(processRunner);

            string battleName = "p4389y78asdj";
            battle = new Battle(battleName);
        };

        Because of = () => battleRunner.Run(battle);

        It should_tell_the_process_runner_to_run_a_new_battle_process = () =>
            processRunner.AssertWasCalled(p => p.RunProcess(Arg<ProcessStartInfo>.Is.NotNull));

        static BattleRunner battleRunner;
        static IProcessRunner processRunner;
        static Battle battle;
    }

Implementation:

    public interface IProcessRunner
    {
        void RunProcess(ProcessStartInfo processStartInfo);
    }

    public class BattleRunner
    {
        readonly IProcessRunner processRunner;

        public BattleRunner(IProcessRunner processRunner)
        {
            this.processRunner = processRunner;
        }

        public void Run(Battle battle)
        {
            processRunner.RunProcess(new ProcessStartInfo());
        }
    }

Now I want to record the information that is sent in on that process start information, so I stub the method and use the Do() syntax to record (this is my personal preference and hope to blog about my thoughts on Do(), WhenCalled() and GetArgumentsForCallsMadeOn() at a later date ).

    public class when_the_battle_runner_runs_a_battle
    {
        Establish context = () =>
        {
            processRunner = MockRepository.GenerateStub<IProcessRunner>();
            processRunner.Stub(p => p.RunProcess(null))
                         .IgnoreArguments().Do(RecordProcessStartInfoUsedInCall);
            battleRunner = new BattleRunner(processRunner);

            string battleName = "p4389y78asdj";
            battle = new Battle(battleName);
        };

        static Action<ProcessStartInfo> RecordProcessStartInfoUsedInCall = s => 
            processStartInformation = s;

        Because of = () => battleRunner.Run(battle);

        It should_tell_the_process_runner_to_run_a_new_battle_process = () =>
            processRunner.AssertWasCalled(p => p.RunProcess(Arg<ProcessStartInfo>.Is.NotNull));

        It should_include_the_known_battle_runner_batch_file_in_the_start_arguments = () =>
            processStartInformation.FileName
                .ShouldEqual(BattleConstants.BattleFilesLocation + "run_battle.bat");

        It should_set_the_working_directory_for_robocode = () =>
            processStartInformation.WorkingDirectory
                .ShouldEqual(BattleConstants.RobocodeWorkingDirectory);

        It should_include_the_battle_in_the_start_arguments = () =>
            processStartInformation.Arguments.ShouldContain("-battle " + battle.BattleFile.LocalPath);

        It should_include_the_results_in_the_start_arguments = () =>
            processStartInformation.Arguments
                .ShouldContain("-results " + battle.BattleResultFile.LocalPath);

        static BattleRunner battleRunner;
        static IProcessRunner processRunner;
        static Battle battle;
        static ProcessStartInfo processStartInformation;
    }

And below is the working code so far. I'll continue the development of the battle classes in my next robocode post.

    public class BattleRunner
    {
        readonly IProcessRunner processRunner;

        public BattleRunner(IProcessRunner processRunner)
        {
            this.processRunner = processRunner;
        }

        public void Run(Battle battle)
        {
            var startInformation = new ProcessStartInfo();
            startInformation.FileName = BattleConstants.BattleFilesLocation + "run_battle.bat";
            startInformation.WorkingDirectory = BattleConstants.RobocodeWorkingDirectory;
            startInformation.Arguments = string.Format("-battle {0} -results {1}",
                                    battle.BattleFile.LocalPath,
                                    battle.BattleResultFile.LocalPath);

            processRunner.RunProcess(startInformation);
        }
    }

Posted at at 8:12 AM on Thursday, July 15, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: , ,

setting up robocode for acceptance testing

For much of this post, I obtained some really helpful information from the robocode wiki page:
debug a .NET robot in visual studio.

In my series of robocode posts I've been looking at how I can acceptance test my robot and I'd previously outlined a few steps that I needed to take to make this happen.

The first of these is to enable robocode to pick up the robot from a build folder and for my acceptance test I simply want it to point into the \bin\debug folder for my project.

Setting this up in robocode is very easy by going to Options > Preferences and adding a path into Development Options:

preferences

Now when I go to form a new battle in robocode I can pick up my robot and prove that it is available:

newBattle

Now that I have the robot available I can now move onto how to debug through visual studio and this requires the command line options being put into the Debug properties of the C# project file:

debug
The command line options I use for manual debugging (which I do very little of at all) are:
-Xmx512M
-Dsun.io.useCanonCaches=false
-cp libs/robocode.jar;libs/jni4net.j-0.7.1.0.jar 
-Ddebug=true
-DRANDOMSEED=4569234345
-DNOSECURITY=true
robocode.Robocode 
-battle battles\debugging.battle
-results results\debugResults.txt

The most salient of which are:

-DRANDOMSEED:  This allows me to run the same predictive battle situation each time - instead of the robots beginning with random facing and start positions they will consistently begin the battle the same way.

-Ddebug: This prevents robocode from skipping a turn for the robot if it is waiting for a reply for too long (which would occur with breakpoints in visual studio)

-battle: Points to a custom battle file that I've set up for debugging

- results: The results file I want written to when the battle is over.

I can use the above setup for my acceptance testing (without debug and security flags) - if I can pass in the -battle and -results command line parameters when calling a .bat file from my test I can run custom robocode battles defined by the acceptance test itself.

Below is the resulting .bat file and I'm now ready to move onto creating the acceptance testing framework.

runBattle

Last of all I want to wrap this post up by showing a battle file where you define, amongst other things, the number of rounds and the individual robots you want in the battle:

debuggingBattle

Posted at at 7:10 AM on Wednesday, July 14, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under:

acceptance testing my robocode robot

I'm embarking on an implementation of a robocode robot and my last post on this topic illustrated pushing the robot into a boundary via an adapter so that any code I write can be within my own model.

Before I continue and begin to wire up my robot one thing that strikes me is that I will need to evaluate how well my robot is doing as I change code. Rather than wait for the weekly battle against other robots created by my opponents, I should be able to verify that the changes I make are for the better.

I've therefore decided to start with acceptance testing my robot and doing this up front, so I'm going to park my implementation for the time being and write my first acceptance - I think it should be the most simple one of all:

In a one round battle, fighting against a single robot that does not move, the slayer robot should win.

So how do I go about writing and running this kind of acceptance test?

As I'm the only stakeholder on this project I don't see the need for a BDD or other acceptance framework, so I'm going to roll it in C# in an acceptance testing namespace of my specifications so I need to think about hooking into robocode and running each test.
After much research into what's required, here's what I need to do:

  1. Set up robocode to be able to read a robot from my bin/debug folder
  2. Work out how to run robocode from the command line with the right parameters for a given test
  3. Define a battle for the acceptance test
  4. During an acceptance test, run the robocode process against this battle
  5. Parse a results file and provide results back to my acceptance test

So I'll be tackling each one of these in future posts and once I've set this process up these acceptance tests will become my invariant tests that I'm attempting to give more prominence to in my work.

Posted at at 7:55 AM on Monday, July 12, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: ,

robocode series of posts

I will be posting quite a few entries about robocode so here is an index that will store links to all the posts in the series:

  1. test driven robots with robocode
  2. introduction to a robocode robot
  3. starting the robocode robot with an anti-corruption layer
  4. acceptance testing my robocode robot
  5. setting up robocode for acceptance testing
  6. writing a battle runner for robocode
  7. continuing the battle classes for robocode
  8. parsing robocode results
  9. wrapping up the battle runner for robocode
  10. writing the first acceptance test for robocode
  11. refining battle parsing

Posted at at 8:14 AM on Friday, July 9, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under:

starting the robocode robot with an anti-corruption layer

I'm about to get started with my robocode implementation and have a few ideas about what I want the robot to achieve. The first and most important thing I want to concentrate on is the initial set up of code and how I want to interact with the robocode library.

One thing I'm very aware of on recent projects is the way external dependencies influence the core of your system at an early stage. It often seems harmless to use many of the types in those third party libraries when putting those first pieces of code together, especially if that third party is another team in the same organisation. But if left to proliferate this can mean that, in those that grow into large systems, these third party hooks reach right in through all the layers like tentacles into the very heart of what we do and influence our test driven process.

So my very first goal is to separate my model from the robocode layer via an adapter giving me an anti-corruption layer. I'm aware that the robocode library is rarely going to change if at all during the lifetime of my project, but I want this layer so that I can minimise the influence that library may have on my design choices.
I also want to choose the data that filters into my domain model rather than rely on the robocode types and all the rich information on there, especially when I'm initially only going to be using some of it.

Here goes then with the first specification in the TeamSlayer project. Note that I have moved to using Machine.Specifications that give a very clean way of writing context specifications:

    public class when_a_slayer_robot_is_created
    {
        Because of = () => robot = new SlayerRobot();

        It should_be_a_robocode_robot = () =>
            robot.ShouldBeOfType<Robocode.Robot>();

        protected static SlayerRobot robot;
    }

This is setting up the core robot class in an Adapter namespace and ensuring it inherits from the robocode Robot class and I can get this to pass very easily.
I have in mind rolling in an IOC container to resolve all my future dependencies and I'm going to hide this behind a service locator so that the adapter knows very little about dependency resolution. Because the robocode library will create my robot with a default constructor I'm going to need to use property injection and I need to ensure that on construction it begins with a default concrete implementation of the service locator:

    public class when_a_slayer_robot_is_created
    {
        Because of = () => robot = new SlayerRobot();

        It should_be_a_robocode_robot = () =>
            robot.ShouldBeOfType<Robocode.Robot>();

        It should_already_have_a_service_locator_because_robocode_creates_in_a_default_way = 
           () => robot.ServiceLocator.ShouldBeOfType<ServiceLocator>();

        protected static SlayerRobot robot;
    }

Once I get this passing my code looks like this so far:

    public class SlayerRobot : Robot
    {
        public SlayerRobot()
        {
            ServiceLocator = new ServiceLocator();
        }

        public ServiceLocator ServiceLocator { get; set; }
    }

    public class ServiceLocator
    { }

For unit testing purposes, I need to be able to swap functionality in that property so I introduce a specification that allows me to do that:

    public class when_a_service_locator_is_given_to_the_slayer_robot : with_robot_set_up
    {
        Because of = () => robot.ServiceLocator = serviceLocator;

        It should_have_the_service_locator_it_was_given = () =>
            robot.ServiceLocator.ShouldEqual(serviceLocator);
    }

    public class with_robot_set_up
    {
        Establish context = () =>
        {
            serviceLocator = MockRepository.GenerateStub<ICanLocateServices>();
            robot = new SlayerRobot();
        };

        protected static SlayerRobot robot;
        protected static ICanLocateServices serviceLocator;
    }

I have now rolled in a base specification set up class called "with_robot_set_up" (and moved the earlier specification to use that also). I now introduce a new interface ICanLocateServices and inject that into the property in my Because delegate. This requires a few changes to implementation here and there and leaves me with the following code:

namespace TeamSlayer.Services
{
    public class ServiceLocator : ICanLocateServices
    { }

    public interface ICanLocateServices
    { }
}

namespace TeamSlayer.Adapter
{
    public class SlayerRobot : Robot, IRobot
    {
        public SlayerRobot()
        {
            ServiceLocator = new ServiceLocator();
        }

        public ICanLocateServices ServiceLocator { get; set; }
    }
}

So now I'm all wired up I need to now look at what happens when a robot is activated by the robocode library. A virtual method Run() on the robot class is called to enable me to start my processes and issue the first commands for the robot. This seems like a good place to do my initialisation:

    public class when_the_slayer_robot_is_run : with_robot_set_up
    {
        Establish context = () => robot.ServiceLocator = serviceLocator;

        Because of = () => robot.Run();

        It should_ask_the_service_locator_for_a_robot_engine = () =>
            serviceLocator.AssertWasCalled(x => x.ProvideRobotEngine());
    }

I inject a service locator stub into the robot's property in my set up and then call the Run() method. I expect the adapter to ask the service locator for a robot engine which I describe with a new interface ImARobotEngine. The implementation looks like this:

    public class SlayerRobot : Robot
    {
        public SlayerRobot()
        {
            ServiceLocator = new ServiceLocator();
        }

        public ICanLocateServices ServiceLocator { get; set; }        

        public override void Run()
        {
            ImARobotEngine robotEngine = ServiceLocator.ProvideRobotEngine();
        }
    }

I now want the robot to hand control over to my model by asking the robot engine to initialise. I plan on sending the robot itself in the initialisation call, but I do not want this adapter type to leak into my model. So I now want an abstracted ImARobot interface that lives in my own model and describes interactions in my own terms. I go back to the original specification and add to the bottom of that:

    public class when_a_slayer_robot_is_created : with_robot_set_up
    {
        Because of = () => robot = new SlayerRobot();

        It should_already_have_a_service_locator_because_robocode_creates_in_a_default_way 
= () => robot.ServiceLocator.ShouldBeOfType<ServiceLocator>(); It should_be_a_robocode_robot = () => robot.ShouldBeOfType<Robocode.Robot>(); It should_be_a_model_based_robot = () => robot.ShouldBeOfType<ImARobot>(); }

I can now write my specification for this initialisation where the Initialise() method will take in an ImARobot type:

   public class when_the_slayer_robot_is_run : with_robot_set_up
    {
        Establish context = () => 
        {
            robot.ServiceLocator = serviceLocator;

            robotEngine = MockRepository.GenerateStub<ImARobotEngine>();
            serviceLocator.Stub(x => x.ProvideRobotEngine()).Return(robotEngine);
        };

        Because of = () => robot.Run();

        It should_ask_the_service_locator_for_a_robot_engine = () =>
            serviceLocator.AssertWasCalled(x => x.ProvideRobotEngine());

        It should_ask_the_robot_engine_to_initialise_with_itself = () =>
            robotEngine.AssertWasCalled(x => x.Initialise(robot));

        static ImARobotEngine robotEngine;
    }

I now have an anti-corruption layer where I've sorted my code into distinct boundaries and formed a walking skeleton.
Here is the final cut of code for this first piece of work:

(Note that the service locator purposefully returns null for the time being and causes a null reference exception when the Robot is run. This is so I can observe what happens when a robot does not function correctly and I'll be covering this in one of the next few posts.)

namespace TeamSlayer.Adapter
{
    public class SlayerRobot : Robot, ImARobot
    {
        public SlayerRobot()
        {
            ServiceLocator = new ServiceLocator();
        }

        public ICanLocateServices ServiceLocator { get; set; }        

        public override void Run()
        {
            ImARobotEngine robotEngine = ServiceLocator.ProvideRobotEngine();
            robotEngine.Initialise(this);
        }
    }
}

namespace TeamSlayer.Service
{
    public class ServiceLocator : ICanLocateServices
    {
        public ImARobotEngine ProvideRobotEngine()
        {
            return null;
        }
    }

    public interface ICanLocateServices
    {
        ImARobotEngine ProvideRobotEngine();
    }
}

namespace TeamSlayer.Model
{
    public interface ImARobot
    {
    }

    public interface ImARobotEngine
    {
        void Initialise(ImARobot robot);
    }
}

Posted at at 8:01 AM on Thursday, July 8, 2010 by Posted by Justin Davies | 4 comments Links to this post   | Filed under: , , ,

invariant tests

In a previous post I discussed the importance of behavioural unit tests and how their seemingly brittle nature is part of the evolution of test first code bases.

Having accepted the fact that my behavioural specifications are open to change because as I evolve my design and model, be it through refinements, refactoring or rework, how can I be sure that during the change of my specifications I don't change the overall behaviour of my application?

Gojko Adzic discusses this briefly in the podcast of his DDD eXchange talk entitled DDD, TDD, BDD where he talks about the synergies to be found in the x-DD practices. He explains that iterative design requires effective regression tests, but often the unit tests are bound to the design and thus must change and evolve with them.
He also infers that the often touted phrase "unit tests enable me to refactor efficiently" isn't strictly true if those specifications or unit tests can change.

I totally agree - by having malleable specifications I open myself up to the prospect whereby, if I change them enough so that the specifications are reworks rather then refactor, then I no longer have those over-arching regression tests that inform me that I have not changed currently described behaviour.

Gojko calls this the need for invariant tests - those BDD level tests that must cover the system at a higher level than unit test level specifications.

These invariant tests are often what is missing in my working practice at the moment, either through my own omission, the project or team set up not being aligned to BDD practices or the fact that this was never done up front on the project and is just very difficult to introduce at a later date.
I believe I need to give this greater importance and will be my next part of my "being new" - ensuring invariant tests are present where possible so they can support my malleable specifications.

Posted at at 7:22 AM on Wednesday, July 7, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: , ,

introduction to a robocode robot

As I'm going to be illustrating some code for a robot using the robocode library I thought I'd illustrate a few main things about how robots are structured in the .NET robocode integration assembly (robocode is in java).
There is also some good literature on the wiki:
http://robowiki.net/wiki/Robocode/.NET/Create_a_.NET_robot_with_Visual_Studio#Robocode_API

There are many members to the robocode robot, but here are the main ones:
(a full list available from this well formatted API page robocode robot api )

Run()
This virtual method is the first thing called when the robot is activated. Here I can hook up the first commands for the robot and introduce a loop or similar way of entering commands.

OnScannedRobot() - informs when the radar detects another robot, giving information on that robot's position

OnHitRobot(), OnHitWall(), OnHitByBullet() - a few of many events that enable you to react to certain situations

Ahead(pixels), Back(pixels), TurnLeft(), TurnRight() - moves the robot

Scan() - enables you to scan after you've stopped moving or to interrupt the current OnScannedEvent

Fire(power), FireBullet(power) - fires using current gun position

TurnGunLeft(), TurnGunRight() - moves the robot's gun independently of the body

TurnRadarLeft(), TurnRadarRight() - moves the robot's radar independently of the other parts

Energy, GunHeat, Heading, GunHeading, RadarHeading, Velocity, X, Y - various properties on the robot

So there's lots of stuff to work with and this is just the most relevant ones worth posting in this quick introduction.

Here's an example of a robot in action, taken from the C# samples provided with robocode:

    public class MyFirstRobot : Robot
    {
        public override void Run()
        {
            while (true)
            {
                Ahead(100); // Move ahead 100
                TurnGunRight(360); // Spin gun around
                Back(100); // Move back 100
                TurnGunRight(360); // Spin gun around
            }
        }

        public override void OnScannedRobot(ScannedRobotEvent e)
        {
            Fire(1);
        }

        public override void OnHitByBullet(HitByBulletEvent e)
        {
            TurnLeft(90 - e.Bearing);
        }
    }

Posted at at 8:01 AM on Monday, July 5, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under:

test driven robots with robocode

With all the test driven development I've being doing at work, on personal projects and for fun I have found that although some of it has been challenging, there has been a lot of it that involves honing already existing skills and I've been looking for something to get my teeth into that will stretch me in new ways.

I saw a post from Gojko Adzic earlier this year on Effective exercises for teaching TDD and in there was a link to a little gem called Robocode - a programming game where robot tanks battle with each other in real time.
It is primarily a Java application, but as there is now a .NET integration API, I saw this as a great opportunity to stretch myself and apply my skills to something completely new; coding deterministic strategies and artificial intelligence.

So to get this project started I downloaded Robocode and set up some private subversion repositories and a few TeamCity builds that create robot artifacts ready for use in a real time battle. In the spirit of the Xbots workshops, with a few friends and I developing each week, our plan is that on a regular basis, perhaps once a week, a Robocode battle will commence and each participant will receive points after battling it out against other robots. This will therefore be a case of small iterative development in my spare time and a complete blank slate to work from - should be very interesting.

So I hope to be posting about what I learn - I don't promise that any of my strategies will be the right ones as I know very little about this area, but I think it will definitely be an interesting challenge and a chance to try some new things out.

Posted at at 7:34 AM on Thursday, July 1, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: ,