Quick Tip on Generating Test Cases with FlexUnit 4/Flash Builder 4

Updated just a little while after posting, see the end

In my Presentation on FlexUnit 4 and Flash Builder 4, I made a flippant comment about the "Class to test" field on the New Test Case wizard not doing anything very helpful.

It turns out I missed a benefit, one potentially more useful than having a variable named classToTestRef created for me. But it turns out that enabling this option in the wizard allows you to choose "Next" instead of just "Finish".

And the next screen is pretty useful in certain circumstances:

This screen allows you to automatically generate test method stubs for each selected method in the class under test. As I've been adding a lot of unit tests to an existing, mature application that had none, this has been very useful indeed.

The generated test methods immediately fail, which is reasonable:

 
[Test]
public function testUpdateTask():void
{
	Assert.fail("Test method Not yet implemented");
}
 

However, if you don't have the option of completing all the tests before doing anything else, I think it's also reasonable to ignore the ones you just haven't got to yet.

 
[Ignore]
[Test]
public function testUpdateTask():void
{
	Assert.fail("Test method Not yet implemented");
}
 

This raises the "ignored" count in your test run results, and an "ignore" count > 0 is a constant reminder that there is some work needing to be done. But I think that an unwritten test, while still a problem that needs to be addressed, is a different kind of problem than a failure in a test that should work. Maybe I'm just not hardcore enough.

Update

Actually it seems that this option doesn't even create the classToTestRef variable any more, so my original objection is now completely invalid, and I'm happy about it :)

Displaying Flex Log Messages In Your Flex Application

One of the first things I want to do after spending any time in an application is enable logging. We all know that trace() is the moral equivalent of System.out.println(), sharing its ease of use, ubiquity and distastefulness. Logging (whether you use the Flex logging API or some other tool) is far superior, for reasons best left to another post.

Usually the TraceTarget is good enough for my purposes as a developer, but I recently found myself tasked to build a utility application that would be testing the behavior of other components and loaded SWF files, and I want all of my lovely log messages to be displayed in a panel within the application itself. It turns out that this is very straightforward, just as long as you already know how to do it. Here's how (or at least here's how I did it).

1. Create a Simple Log Target

First, I created a simple log target that would provide an easy way for a visual component to display the log messages. I settled on creating a target that exposed a bindable ArrayCollection. To keep things from spinning wildly out of control, I added a configurable limit on the number of log message the ArrayCollection would retain, but other than that I didn't design this with performance in mind; it's a utility class for a utility application, and I'd want to do a more thorough job of analyzing how it would fare under high stress before it was deployed in a production application.

 
package com.chrisluebcke.utils
{
	import mx.collections.ArrayCollection;
	import mx.core.mx_internal;
	import mx.logging.targets.LineFormattedTarget;
 
	use namespace mx_internal;
 
	/**
	 * A log target that provdes an ArrayCollection (with a configurable maximum size) that can
	 * (for example) be used by UI components to display log messages on-screen.
	 */
	public class ArrayCollectionLogTarget extends LineFormattedTarget
	{
		[Bindable]
		[ArrayElementType("String")]
		/**
		 * The collection containing the log messages
		 */
		public var log : ArrayCollection;
 
		/**
		 * The maximum number of log messages.
		 */
		public var maxMessages : Number = 10000;
 
		/**
		 * Constructor.
		 */
		public function ArrayCollectionLogTarget()
		{
			super();
			log = new ArrayCollection();
		}
 
		override mx_internal function internalLog(message : String) : void {
			log.disableAutoUpdate();
			log.addItem(message);
			if (log.length > maxMessages) {
				log.removeItemAt(0);
			}
			log.enableAutoUpdate();
		}
	}
}
 

The bit about mx_internal is what takes you hours to figure out the first time you try to write a useful subclass of LineFormattedTarget. You're welcome. Other than that, this should be pretty straightforward. (It's very helpful to look at the code for TraceTarget, which is really even simpler than this, as a guide).

2. Instantiate and Bind The Target

To use the target, you need to declare it in MXML. I'm not sure if doing so somewhere besides your top-level Application (or subclass thereof) would work, but it always seems to go there. (I'm sure that you could create a more flexible system by creating your log targets via ActionScript. Another day).

 
<utils:ArrayCollectionLogTarget id="acLogTarget"
		includeDate="false"
		includeTime="true"
		includeCategory="true"
		includeLevel="true"
		level="{LogEventLevel.DEBUG}"/>
 

(This is, naturally, exactly like setting up a TraceTarget.)

With that done, you can now use the target's log property (a bindable ArrayCollection) however you'd like. Say, in a List:

 
<mx:Panel id="logPanel" title="Log" width="100%" height="50%" >
	<mx:List id="logList"
			horizontalScrollPolicy="on"
			width="100%" height="100%"
			dataProvider="{acLogTarget.log}"/>
</mx:Panel>
 

Now any logger statements that exceed your log level (and match any filters) will show up in UI, as well as any other targets you've configured. I've found this quite useful, and I hope you do too.

The Official Flex Singleton

Didn't know there was one, didja? Well, you was wrong.

 
package mx.core
{
 
[ExcludeClass]
 
/**
 *  @private
 *  This all-static class serves as a singleton registry.
 *
 *  For example, pop-up management throughout a Flex application
 *  is provided by a single instance of the PopUpManagerImpl class,
 *  even when the main application loads modules and sub-applications
 *  each of which might have PopUpManagerImpl linked in.
 *
 *  The factory class for a framework-based application
 *  or a module (i.e., SystemManager or FlexModuleFactory,
 *  both of which implements IFlexModuleFactory) calls
 *  the registerClass() method to populate the registry.
 *
 *  Later, other classes call getInstance() to access
 *  the singleton instance.
 *
 *  The registry policy is "first class in wins".
 *  For example, if the main application registers its
 *  PopUpManagerImpl, then a loaded SWF will use that one.
 *  However, if the main application doesn't contain
 *  a PopUpManagerImpl, then it registers null,
 *  and the first loaded SWF containing a PopUpManagerImpl
 *  will register that one.
 */
public class Singleton
 

Etcetera.

I actually completely get why it's there, and also why it's as far out of view as an open source class could be. It's there to support the myriad *Manager classes (and for a few other things, like the IEmbeddedFontFactory and ITextFieldFactory), by both providing a registry for them and helping to enforce their singleton-ness. It's on the down low, I imagine, because it would probably be abused to hell if it weren't. I mean, sure, common wisdom these days trends towards calling them "Stinkletons" and throwing rotten fruit at them, but look at the sheer amount of bandwidth that's been devoted to making them bulletproof. If you build an inviting home for singletons, people will start stacking them ten deep.

Singletons: Smelly, yet appealing

The truth is, this thing isn't a singleton; it's a static registry, and it doesn't have anything to do with implementing a singleton pattern. What it does is make sure that you can only register a class for a given interface once (hence the dreaded errors when some module, rather than the main application, happens to be the first to register a manager class), and it conveniently calls getInstance() when you want an instance of the interface in question, but that's about it.

Still, having elevated the profile of this class in my own small way, I have to say that you probably shouldn't use it unless you're doing the exact same thing--registering a manager or factory of the type that already use this. Resist at all costs the creeping suspicion that you've finally found a good point to which to affix your data model, and go get yourself some dependency injection.

Loading Files Into Flex Applications–Now Server-Free!

Okay, maybe it's been server-free for a while, and there are apparently limitations, but this is still pretty cool. Turns out that as of later versions of Flash Player 9 (and continuing on to today), you can inspect a file selected by a user for upload without having to send it off to a server and get it back again. I stumbled across this while poking around for resources on the nitty gritty details of the Spark architecture--it wasn't what I was looking for, but it was a nice surprise, since the last time I'd been asked to look into this (a couple years ago), the answer seemed to be a pretty resounding "no".

Behold:

Screen shot showing MXML file loaded locally into Flex application

Awesome. And meta.

The code for the above is quite simple:

 
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx">
 
	<fx:Script>
		<![CDATA[
			private var fr : FileReference = new FileReference();
 
			private function getFile() : void {
				fr.browse();
				fr.addEventListener(Event.SELECT, handleSelect);
				fr.addEventListener(Event.COMPLETE, handleComplete);
			}
 
			private function handleSelect(event : Event) : void {
				fr.load();
			}
 
			private function handleComplete(event : Event) : void {
				contents.text = String(fr.data);
			}
 
			protected function button1_clickHandler(event:MouseEvent):void
			{
				getFile();
			}
 
		]]>
	</fx:Script>
 
	<s:layout>
		<s:VerticalLayout paddingLeft="10" paddingRight="10" paddingBottom="10" paddingTop="10" gap="10"/>
	</s:layout>
 
	<s:Button label="Select File" click="button1_clickHandler(event)"/>
	<s:Label text="File Contents:"/>
	<s:TextArea id="contents" width="100%" height="100%"/>
</s:Application>
 

The original point of the post at Flex Pasta (which I'm new to, but seems delicious, although filling) was to get around upload bugs with Firefox, and various commenters pointed out additional limitations in using this technique for uploading data to a server. That said, this seems imminently useful in a number of applications-for example, reading a CSV into a data grid (yeah, that's the kind of super-sleek development I do a lot of).

Unit Testing Flex with FlexUnit 4 and Flash Builder 4

I had a great time giving a presentation on these subjects at the Silicon Valley Flex User Group (forevermore referred to as "silvafug") last week--actually twice, once for the San Francisco meting and the next day in San Jose. I'm not going to try to recreate the presentation in this post, but I wanted to provide some resources. Before I move on, though, I again want to thank Mike Labriola at Digital Primates for graciously answering my largely esoteric questions in detail.

This was the first time I used Apple's Keynote, so that's the native form for my presentation. I had a great time experimenting with the builds and transitions, and I'm sure nobody enjoyed all the pizazz more than me. I've also exported it to PowerPoint for the majority of you out there; the transitions came across pretty chunky, but I really didn't feel like spending a couple hours cleaning it up for PPT. Sorry, Windows users. Anyway, here are both versions:

  • Keynote version: UnitTestingFB4.key_.txt (You'll need to change the extension to just ".key"; either WordPress or my penny-ante hosting provider didn't like that extension, for reasons that are obvious but silly)
  • PowerPoint version: UnitTestingFB4.ppt

Keynote also has a handy export-to-PDF feature which, thanks to all the aforementioned pizazz, resulted in a PDF that was approximately 15 MB, 150 pages, and had half the text colors switched to black. You didn't really want that, so I'm not going to try and give it to you.

That said, if you weren't at the presentation (or don't already know a bit about the subject matter) these won't be easy to follow. I use slides to support what I'm saying, rather than as something to read in front of a crowd of people, so they work better with me talking over them. We're working on getting the recorded presentations posted, and I'll update this with the link when they're ready.

Now for the useful stuff--link party!

FlexUnit 4

Flash Builder 4 and FlexUnit

FlexUnit is Not the Only Game In Town

General Unit Testing Topics

Test-Driven Development

Code Coverage

Thanks to everyone who came out.

Image of Kent Beck, creator of SUnit, superimposed on Michaelangelo's "Creation" from the Sistene Chapel

Kent Beck, the Creator of SUnit (a clip from one of my slides; that's God bringing Adam to life in the Sistine Chapel, if you didn't get it.)

Return top