Geeks With Blogs
Robert's Blog ideas about design and development

Recently, I completed a project for a video game prototype course that involved pathfinding. With Flash Player 9's speed gains over Flash Player 8, I thought Flash would be a good medium to demonstrate pathfinding in an online setting.

If you've never heard of Test Driven Development (TDD), it is a programming practice whereby the programmer writes tests for objects in his program before writing a single line of code. He writes his tests based on his expectations of how the objects should behave. If an object should display a message after something happens to it, the programmer writes a test that checks that the object does indeed display a message.

Some of you are undoubtedly thinking that I've hit my head on the bathtub this morning right about now. Not so. I chose to test drive my little pathfinding experiment in ActionScript 3 because one of the things that TDD excels at is helping you to take the next step forward in a new coding situation. Your focus is shifted from making something to making something that works (you may say semantics, I say otherwise). So you might start by dreaming up an object that is going to handle something like say pathfinding. All you weekend hackers out there sit on your hands as we are going to write all of our tests for our pathfinder before we write a single line of code.

In probably "the" book on TDD, Test Driven Development by Example the author starts you out by writing a kind of shopping list of expectations that your object has to fulfill. I am going to take the same approach here. For the sake of giving credit where it is due, my work and this article where inspired directly by this article: A* Pathfinding for Beginners. On with the tests.

The pathfinder object should be able to do the following things:

  • Navigate from a starting point to an ending point along a path.
  • Avoid obstacles
  • Not cut corners (has to do with the heuristic I'm using, I'll explain later)
  • Give up after a certain number of unsuccessful tries

For this example, I'll be using the AsUnit unit testing framework. Go to the website and download the XUL UI. Once you've got it downloaded, run the installer.

After the AsUnit installer has finished, Launch FlashDevelop. Open up the Global Classpaths dialog (Ctrl + F9). Add the path to the AsUnit framework (C:\Program Files\AsUnit\framework\as3 in my case).

From your desktop or some other location, create a new folder called "Libraries".

From the Project menu, select "New Project". When the New Project menu appears, select the "Empty Project" option and name the new project "Pathfinding". For the project location browse to your new "Libraries" folder. Make sure the "Create directory for project" box is unchecked. Press "OK".

Now you are going to create what is known as a "package" in ActionScript programing terms. A package is basically just a bunch of code files (classes) in folders.

Create a folder named "edu" inside your project by right clicking on "Pathfinding" in your Project Explorer and selecting "Add" > "New Folder". Create a "tamu" folder inside your "edu" folder. Next, make an "agcg" folder inside your "tamu" folder. Now you have the directory structure for a package named " edu.tamu.agcg".

It is common practice for the name of a package to be its creating organization's url in reverse (agcg.tamu.edu doesn't go to our website, but cg.tamu.edu does- agcg.tamu.edu was taken). You can see that "edu.tamu.agcg" looks like "edu\tamu\agcg" there is a relationship there. Often the package name mimicks the structure of the directory it is found in. This package naming scheme makes it easy to locate files since there is a relationship between package names and directory names.

Now for the last step in creating your package. Create a folder named "pathfinding" inside "agcg".

Right click your "pathfinding" folder in the project explorer and add a folder named "tests". This is where your unit tests for your pathfinder class will reside. Right click your new tests folder and select "Add" > "New Class". Name your class "PathFinderTestCase". Select everything in your new file and delete it. Replace it with:


package edu.tamu.agcg.pathfinding.tests
{
public class PathfinderTestCase
{

}
}

Place the following import statement in your code above your class definition:


import asunit.framework.TestCase;

This will allow you to use the AsUnit test case in your code. Next you will extend TestCase with your code:


import asunit.framework.TestCase;

public class PathfinderTestCase extends TestCase
{
...

Now you are going to want to write a constructor function for your test case. This will be used to create objects (instances) from your class.


public function PathfinderTestCase(testMethod:String = null)
{
super(testMethod);
}

Now you can start defining test functions from your list of requirements.

In the practice of TDD, you write one test at a time. We'll start with the most critical: making sure the pathfinder can find its way.

One of the mantras associated with TDD is "red, green, refactor", where "red" indicates a failing test. The first thing you want to do in a testing cycle is to write a failing test. That may seem a little bonkers, but writing a failing test first and watching it fail lets you know your test harness is working.

So for our first test:


public function testPathfinderFindsItsWay():void
{
fail("test not implemented");
}

Now that you've written your first test, you need to set up the plumbing to run it. You need a container for your test case and any that might follow. This is where a test suite comes in. Right click "tests" and select "Add" > "New Class". Name it "PathfindingSuite".

Inside your new PathfindingSuite.as file, replace its contents with the following:


package edu.tamu.agcg.pathfinding.tests
{
import asunit.framework.TestSuite;
import edu.tamu.agcg.pathfinding.tests.PathfinderTestCase;

public class PathfindingSuite extends TestSuite
{
public function PathfindingSuite()
{
addTest(new PathfinderTestCase());
}
}
}

You are going to need a test runner. Your test runner will provide you with visual feedback as to the outcome of your tests (whether they pass or fail). Start by creating a new class inside our test folder named "PathfindingTestRunner". Replace its contents with the following code:


package edu.tamu.agcg.pathfinding.tests
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import asunit.textui.TestRunner;
import edu.tamu.agcg.pathfinding.tests.PathfindingSuite;

public class PathfindingTestRunner extends TestRunner
{
public function PathfindingTestRunner()
{
var suite:PathfindingSuite = new PathfindingSuite();
this.doRun(suite, true);
}
}
}

Now you have all the mechanisms to run our test in place. All that remains is to compile your code and to watch your first test fail.

Writing test driven code is an iterative process, so you'll need to compile your code several times. Rather than run the command line compiler manually, you can write a build file that will allow you to have NAnt run the compiler for you. If you need help installing NAnt, this tutorial can guide you through the process.

Right click on "pathfinding" in the Project Explorer and select "Add" > "New File". Name your new file "default.build". Replace its contents with the following:


<?xml version="1.0"?>
<!--NAnt Build File-->
<project name="pathfinding" default="build">
<property name="basedir" value="." />
<!-- path to Libraries folder -->
<property name="classpath" value="../../../../" />
<property name="path-to-asunit" value="C:Program FilesAsUnitframeworkas3" />
<property name=" flashdevelop.path" value="C:/Program Files/FlashDevelop/Library" />
<property name="source.dir" value="tests" />
<property name="source.file" value=" PathfindingTestRunner.as" />
<property name="deploy.dir" value="tests" />
<property name="output.file" value="testrunner.swf" />
<property name="width" value="550" />
<property name="height" value="400" />
<property name="background.color" value="000000" />
<property name="framerate" value="24" />
<target name="build">
<exec program="mxmlc">
<!--Libraries-->
<arg line='-sp="${classpath}"' />
<arg line='-sp="${path-to-asunit}"' />
<!--Defaults-->
<arg line="-default-frame-rate=${framerate}" />
<arg line="-default-background-color=0x${background.color}" />
<arg line="-default-size ${width} ${height}" />
<!--Output File-->
<arg line='-o="${basedir}/${deploy.dir}/${output.file}"'/>
<!--Source File of Main Application-->
<!--Put Double Hyphen Before Source File-->
<arg line="--" />
<arg line='"${basedir}/${source.dir}/${source.file}"' />
</exec>
</target>
</project>

Open a command window by pressing Windows + R and typing "cmd" in the Run box. Change directiories to your pathfinding directory by typing in "cd C:\Users\Robert\Desktop\Libraries\edu\tamu\agcg\pathfinding" at the command prompt (or whatever your path to your pathfinding directory is).If you've got the NAnt directory in your "Path" system environmental variable (tutorial here shows how to do this), you can now just type "nant" in at the command prompt and NAnt will build your test runner for you. If you see the text "BUILD SUCCEEDED" pop up in your command window, then your build was successful. Otherwise, you may have made a typing mistake in your " default.build" file.

If your build was successful, you should see a file named "testrunner.swf" in your "tests" directory. If you've still got your command window open you can open a Windows Explorer window to see your .swf file by changing directories to "tests" (type in "cd tests" at the prompt) and typing in "explorer /select,.". This will open a Windows Explorer window to your "pathfinding" folder and highlight your "tests" folder. Click open your "tests" folder.

Now you are going to tell windows to open .swf files with the standalone Flash Player that comes with the Flex 2 SDK. In Windows Explorer, right-click on your "testrunner.swf" file and select "Open With" > "Choose Default Program". Now click on the "Browse" button. In the explorer window that pops up, enter "C:\Flex2\flex_sdk_2\player\debug" in the address bar at top left and press Enter. This should take you to the directory where the standalone player if you used the same directory structure as I did here, Now click on "SAFlashPlayer". The Flash Player should now be highlighted in the Open With window. Double click it to run your .swf file.

Now you should see a .swf movie with a red bar across the top and a message saying that your "testPathfinderFindsItsWay" function is not yet implemented. Congratulations, you've just written your first failing test.

Posted on Monday, July 16, 2007 6:53 AM FlashDevelop , NAnt , AsUnit | Back to top


Comments on this post: Test Driven Pathfinding in ActionScript 3 (Part One)

# re: Test Driven Pathfinding in ActionScript 3 (Part One)
Requesting Gravatar...
thanks for the Great article, It helped me to get jump started on development.
Is there a (part 2) somewhere? if so I have not found it.
thanks again
Left by nick on Apr 25, 2008 12:28 PM

Your comment:
 (will show your gravatar)


Copyright © Robery Stackhouse | Powered by: GeeksWithBlogs.net