Sunday, August 8, 2010

Unit Testing For ActionScript 3.0

I was curious to see whether anyone had written unit test software for ActionScript 3.0. To my pleasant surprise I found AsUnit. With this software I found a tutorial. I followed the instructions and soon realised there had been some changes since the tutorial was posted in July 2007. Here is how I was able to get AsUnit (installed from AsUnit-20070108.msi) running with Adobe Flash CS3 Professional. 

1) Download the software from SourceForge. 

2) Install the software. I chose to install the software to this folder:

E:\Projects\Flash\asunit

3) Add the classpath to the Flash IDE preferences. From the main menu Edit -> Preferences. Select category ActionScript. Click ActionScript 3.0 Settings button. Add a new classpath for the framework\as3 folder of the install directory

E:\Projects\Flash\asunit\framework\as3

Click OK to close the ActionScript 3.0 Settings window. Click OK to close the Preferences window. The AsUnit code can now be a part of all future projects

Following is an example showing how the unit test code works

1) Create a new folder for the example. I created my folder here:

E:\Projects\Flash\tutorial

2) Create a file called AsUnitTestRunner.as with the following code:

package {
    import asunit.textui.TestRunner;

    public class AsUnitTestRunner extends TestRunner {
        public function AsUnitTestRunner() {
            start(AllTests, null, TestRunner.SHOW_TRACE);
        }
    }
 
I am led to believe this file was included in earlier versions of the ASUnit code. It was not present in the files installed by AsUnit-20070108.msi.

3) Run AsUnit.exe. This is a wizard to help set up some of the unit test code.

E:\Projects\Flash\asunit\AsUnit.exe 

The first time this runs, the developer is prompted for information by various windows. The next time it runs the developer can enter information directly into text fields. This is the information required to continue the tutorial.

Projects: "Default Project 1". I did not change the default project name.

Source Folder: the folder created in Step 1).

Test Folder: the check-box for "Same as Source Folder" is ticked. This is satisfactory for the purposes of this tutorial. It may be better to keep the test code separate from the the source code in a larger project.

Templates: ActionScript 3.0 (Flash Player 9.0). It is likely this AsUnit code has not been modified for subsequent versions of Flash Player. Caveat emptor.

Class Path: this is the path to the classes required by Flash Player.

C:\Documents and Settings\\Local Settings\Application Data\Adobe\Flash CS3\en\Configuration\Classes 

Class Name: this is the name to give to the class we want to unit test. For this tutorial use the class Example. Now click the Create button. This will create the following three files in the tutorial folder

AllTests.as
Example.as
ExampleTest.as


a) Example.as is a skeleton class.

package  {
    public class Example {
        public function Example() {
        }
    }
}

b) ExampleText.as

This class extends the TestCase class. It contains the code for the setUp() and tearDown() functions that run respectively before and after every test. It also contains the function to test instantiation - testInstantiated(). And it contains a failing test. This last function is to encourage the developer to continue writing tests before adding functionality to the Example class.

c) AllTests.as

This class extends the TestSuite class. This class can run tests for as many classes as necessary. There is an import statement for each TestCase. In this instance there is only the ExampeTest class.

import ExampleTest

In the constructor for this class there is a line to run each test suite:

addTest(new ExampleTest());

4) There is now enough code to start running unit tests. Create a SWF to run the unit test. Open the Adobe Flash CS3 IDE and create a new ActionScript 3.0 FLA. Save the file as "tutorial.fla" in the tutorial folder. Set the document class to AsUnitTestRunner and save the file again.

5) Test the project from within the IDE.

AsUnit 3.0 by Luke Bayes and Ali Mills

..F

Time: 0.072
There was 1 failure:
0) ExampleTest.test()
AssertionFailedError: failing test
    at asunit.framework::Assert$/fail()
    at asunit.framework::Assert$/assertTrue()
    at ExampleTest/test()
    at asunit.framework::TestCase/::runMethod()
    at asunit.framework::TestCase/runBare()
    at Function/http://adobe.com/AS3/2006/builtin::apply()
    at ()
    at flash.utils::SetIntervalTimer/flash.utils:SetIntervalTimer::onTimer()
    at flash.utils::Timer/flash.utils:Timer::_timerDispatch()
    at flash.utils::Timer/flash.utils:Timer::tick()

FAILURES!!!
Tests run: 2,  Failures: 1,  Errors: 0

The unit test has run to completion. It has successfully picked up the fail test which was purposely designed to fail.

6) Add a function to the ExampleTest class to unit test an add() function

/**
 * Test the addition method on example
 */
public function testAddition():void {
    var result:Number = instance.add(2,3);
    assertEquals("Expected:5 Received:"+result, result, 5);
}

In the fashion of Agile programming we have added the unit test BEFORE the code. This is a good time to remove the fail test that was generated by the wizard.

But now the FLA will not compile. The compiler has detected a call to a possibly undefined method add through a reference with static type Example.

7) Add the function to the Example class to make the test compile.

public function add(num1:Number,num2:Number):Number{
    return num1 + num2;
}

8) Now we are ready to run the test again. This time the test compiles and runs without error.


I hope this helps other developers install AsUnit correctly. Please contact me if there are any issues as a result of following the instructions in this blog.


Thank-you for reading

Wednesday, August 4, 2010

Ruby On Rails

I have not had a great deal of experience with Web development. After having worked with Ruby for a little while I became curious about Ruby On Rails. To learn more about it I follow this tutorial. I had to install specific versions of Ruby (1.8.6) and Rails (2.3.8). They are not the latest versions but they did allow me to learn a little about how Ruby On Rails works.

First of all, Ruby On Rails encourages the use of the Model-View-Controller paradigm. After working through the tutorial and seeing how useful this was I have started thinking about MVC and how it might apply to other software projects. Even if a project does not follow MVC exactly, it certainly won't hurt the developer to keep in mind the separation of data, code and interface.

The tutorial starts by setting up the project (a simple blog) and a database to go with it. The web server is very easy to get running and soon I was on my way. The first thing to do was to take care of the posts. This is where the tutorial introduced scaffolding, With one command Rails can generate a model with associated views and controllers for you. While it is not very pretty, what it produces is quite serviceable. However I was aware of this pragmatic programmer tip:

Don't Use Wizard Code You Don't Understand

So I made sure I read through the tutorial and not just entered the commands when I saw them. The tutorial also pointed out that while it was quick and easy to get a project going this way, most experienced Rails developers will use the wizards selectively to get some of the code generated and doing the rest themselves. I was glad to see Rails made it easy to extract and reuse common code. "Don't Repeat Yourself" (in addition to being another pragmatic programmer tip) is also a guiding principle of Rails.

Once posts were set up the tutorial added comments to the blog project. Instead of using scaffolding, the tutorial used generators to create a model and controller. Creating the controller also produced some skeleton views. I thought I would prefer this method to scaffolding when building my own project. I see scaffolding as an advantage when building a project from a template.

The next part of the tutorial added tags to posts to show how two related models could share a single form.

One other principle behind Rails is the REST (representational state transfer) pattern for Web applications. I have no other frame of reference but it seems to me that this is a very common sense way you to view web applications. I confess to going off on a REST tangent and to liking what I saw.

As I said earlier, I have not done any serious web development work, so I learned a lot from this tutorial. The next step would be to develop a similar project using a different methodology. One of the reasons I like looking at various ways to do similar things is to gain perspective. Should I always use Rails to build a web site? No. I should only use Rails if it is the right tool for the job. But if I only know Rails, I will be forced to use it regardless of whether or not it is appropriate. Hopefully I will be able to allocate some learning time a little later to web development.

Thank-you for reading

Saturday, July 31, 2010

Pragmatic Programmer

I have been interested in software development since I wrote my first BASIC program on a Hitachi Peach in 1984.

10 PRINT "HELLO"
20 GOTO 10

or something like that :) But I was hooked straight away. and I have spent most of my working life since then avidly pursuing the craft of software development. A lot has changed since 1984, and if I reflect on this blog in 2036 I am sure much more will change.

In March 2006 I read "The Pragmatic Programmer: From Journeyman to Master". It spoke to me so much that I have referred to myself as a pragmatic programmer ever since. I was constantly agreeing with the authors - "oh yeah" and "right on" and so on. It was really quite remarkable. I don't know that I would have come up with the list of tips they did. As that list stands I don't disagree with any of the tips.

At the start of the book they ask what makes a pragmatic programmer and define five characteristics:
1) Early adopter/fast adapter
2) Inquisitive
3) Critical thinker
4) Realistic
5) Jack of all trades

I strive to develop and enhance each of those characteristics because I am very passionate about becoming the best software developer I can be. It can be quite tiring to work along side people who do not have these characteristics. But it is the difference between someone who develops software because they are paid to do it and someone who develops software because the love developing software. At the same time it is easy to recognise a kindred spirit and I was most fortunate to work with one for too short a time: Leon Mar.

The first two tips also describe pragmatic programmers:

1) Care About Your Craft
2) Think! About Your Work

I've started this blog so I can have a place to put down thoughts and ideas and general musings about software development. In all likelihood I will refer back to this book from time to time. That is because many of the tips are common sense. If other software developers can focus on the two tips above, the rest will follow naturally.

If someone happens to pick up where I have made a mistake, please tell me. I am not perfect and I will never stop learning. 

Thank-you for reading