Unit testing Actionscript 2.0 with ASUnit

We’re going to have a shot at unit-testing actionscript 2.0, after we’ve decided what unit-testing is, and why’s it’s worth doing.

Firstly, what’s going on? Aren’t I a bit behind the times? AS2.0, indeed. Well, yes, you’re absolutely right – but right now that’s where my money’s currently coming from: bringing a timeline-based AS1.0 project slightly closer to the present (AS3.0 isn’t an option, as we’re still targetting the Flash 8 player).

What is unit testing?
Wikipedia says:

… unit testing is a procedure used to validate that individual units of source code are working properly. A unit is the smallest testable part of an application. In [...] object-oriented programming, the smallest unit is a method.

So, we’re breaking our application down into the smallest possible pieces – methods – and testing them to ensure that, at that basic level, they do what we expect (and that they don’t do what we don’t expect them to).

Most languages that I’ve heard of have a unit-testing framework, which automates the process of running through each of the tests. Such a framework ensures:

  • testing is easy
  • testing is fast
  • testing is fun (this isn’t pure/sad geek joy, there’s visceral satisfasfaction to be had in turning red to green. More anon.)
  • each test is run in isolation, with state being wiped clean before the next test is run
  • a body of tests is built up and run each time, which ensures that making a change here doesn’t break something over there, or that re-writing this bit today doesn’t break all that good work.

All of which is pretty good, isn’t it? Another advantage for developers like me – who do a certain amount of design, but then as soon as we start coding struggle to step back to do more design – is that writing tests requires us to think about how our code is going to work, in what situations we want it to fail and how. That’s because I practise* Test-Driven Development (thanks, Kent Beck), which I’ll talk more about later, if time is kind.

AsUnit

As I said most languages have their framework (JUnit for Java, NUnit for .NET, etc., collectively known as xUnit), and thankfully Actionscript 2 is no exception. Luke Bayes and Ali Mills created ASUnit, which provides a test-running GUI, and 3 (three, like one’s not enough!) frameworks.

The ASUnit test GUI

So, what does it do? It’s just a blank text area and a green bar. Yep, pretty much, and that’s as simple as you want it – not much there. Run your hundreds of passing tests, and you’ll see the same thing – that’s the point: when you’re getting stuff right, it keeps out of the way.

The ASUnit test GUI with failing tests

When something goes wrong, however, the bar goes red. Just one ickle lickle slip, and there it is. Blood-soaked redness. When your eyes are criss-crossed with tendrils of that self same colour in the early hours, the bar will let you know. And it’ll point out which tests failed: class name, method name, assertion type and message, which does a great job of narrowing down the problem (that reminds me, we once had a brilliant site, which I loved and was very proud of, but – this is back in the dark days of Flash 5 – bugs would appear and be extremely expensive, because even though they only took 15 minutes to fix, they took 2 days to find).

So there you pretty much have it: write code, the bar’s green, continue. Write code, the bar’s red, find and fix the problem.

A couple of tests to prove the point
If you’ve installed the MXP, it’s given you a couple of commands in the IDE to make your job even easier (thanks, guys).
- Create a new AS2.0 fla, and save it somewhere – that’s important because a whole lot of files are about to be created recursively, so start from a dank dead-end corner of your hard drive, and those files won’t infect everything (i.e. NOT your desktop).
- command > create class, give it the name Example, set it to open automatically in your AS editor, don’t bother with adding a symbol. Hit it.
- open the asunit gui
- in the first frame of the fla:

  1. import AllTests;
  2. var at:AllTests = new AllTests();

- Tadaaa!: your first failing test. That’s a bit poor, isn’t it?

Well no, not really. ASUnit has given you a failing test to prove that the command worked, and to give you somewhere to start. There’s nothing quite like making that first move. Notice how the bar’s red. That right there is something to work on.

Go to the failing test (ExampleTest.as), which should be open in your editor, and take a look – the offending line is

  1. assertTrue("failing test", false);

Easily rectified: change false to true, save, test the movie again. The bar is now green. Did you feel it? Did ya, did ya? That nice fluttery feeling in your belly, the slightest drop of tension in your shoulders? That’s going to become a Pavlovian reaction to seeing red turn to green, and makes waiting at traffic lights much more bearable.

So, another quick example, open your test class and add the following:

  1. public function testIsHappy():Void {
  2.   var mood:String = "sad";
  3.   instance.setMood(mood);
  4.   assertEquals("This example makes me happy", "sad", instance.getMood());
  5. }

test the movie – compile error!
That’s a good thing – I’m working by defining the way I want the functionality to behave before I write it. That means I’m thinking about the design before I write it. That by itself has to give you a warm, fuzzy feeling, doesn’t it?

onwards.

open your class and add the following:

  1.  
  2. private var _mood:String;
  3.  
  4. public function setMood(mood:String):Void {
  5.   _mood = mood;
  6. }
  7.  
  8. public function getMood():String {
  9.   return _mood;
  10. }

test the movie – red bar!

Change the test to:

  1. public function testIsHappy():Void {
  2.   var mood:String = "happy";
  3.   instance.setMood(mood);
  4.   assertEquals("This example makes me happy", "happy", instance.getMood());
  5. }

and truly, you will be.

Available assertions

  • assertTrue
  • assertFalse
  • assertNull
  • assertNotNull
  • assertUndefined
  • assertNotUndefined
  • assertEquals
  • assertSame

Each of which is fairly self-explanatory – the expected parameters for the last two are (message, expectedResult, actualResult), and for the others: (message, ).

* why does the verb ‘practise’ have religious connotations, or is that just me? As it happens, with TDD the subject, it’s not far wrong, but that’s another story …

This website uses IntenseDebate comments, but they are not currently loaded because either your browser doesn't support JavaScript, or they didn't load fast enough.

1 Comment

  1. Luke Bayes — May 12, 2008 @ 7:11 am

    Thanks for the post, I’m sure other folks will find it helpful!

RSS feed for comments on this post. TrackBack URI

Leave a comment