The VMware Flex Training Program


I’m very pleased to welcome all VMware developers to the Obecto Training Portal. We’ve setup this blog with the intend to open a portal to the knowledge we have in the field of RIA and especially Flex and Flash. This is a portal, but also this is an open conversation – feel free to write comments and to ask all your questions.

Even though we’re bulgarians, the official language of the portal is English. The reason for that is to make our discussions as reusable as possible and as open as possible to everyone else interested.

If you find it difficult to express yourself in English (or just don’t want to), here’s the Bulgarian Flex User-group which has its Google Group – the preferred language there is Bulgarian.

The topics in the course

The topics in the course are updated according to the feedback we’ve got from the first group who attended the course:

  1. Overview of the Flash Platform
  2. Introduction to ActionScript 3 & MXML
  3. DataBinding – a Look into the Generated Code
  4. Overview of the Flex SDK
  5. Creating & Extending Flex 3 Components
  6. Remoting
  7. Flex Applications’ Architectures
  8. MVCS Example and MVC Example – Refactored
  9. Creating Modular Applications
  10. Flex 3 Localization Support
  11. Test Driven Development
  12. Optimizing Flex Applications

The MVCS Sample is moved closer to the beginning, because the concept is quite important and it brought lots of controversy and confusion during the last course. The whole idea is revised and some issues and aspects noticed by the seniors (special thanks to Alex and Stefan) that attended are going to be further clarified.

What’s left out of the course

There are quite a lot topics that are out of the above topic list:

  • Skinning and Styling Flex Components
  • Preloading Flex Applications
  • Integrating Flash Content
  • Using Shared Objects
  • Printing from Flex Application
  • Introduction to Gumbo

Recommended List of Books

Today, I was asked to provide a list of books about Flex. The problem is, I’ve never read a book about Flex. Well at least not published in paper. I can recall reading Creating & Extending Adobe Flex 3 Components and you can find this title also here in the sidebar. I can recall also using Essential ActionScript 3.0 as a reference in some Flash related tasks. And that’s about all I’ve ever read in paper about Flash and Flex.

ActionScript 3.0 Design Patterns: Object Oriented Programming Techniques – the contents of this book looks pretty intriguing, but I haven’t read the book. Anyway it looks really promising.

2 | comment

Flex Training Course for QA Engineers


VMware requested from me to prepare a Flex course for their QA engineers and here it is – I’m pleased to share with you the first and only (to my knowledge) course especially prepared to train QA engineers in the intricacies of testing Flex application. This course shares some of the material I teach to the software engineers, but the lab exercises are totally different – instead of focusing on building an application, we’ll focus on understanding the Flex technology and how it can be tested in programmatic fashion.

The course is structured in 5 lecture topics and 9 practical labs in the course of which we’ll build an app an explore different aspects of its testing. Each lecture has slides that you can download from here. Each lab will end up with a project that would be uploaded here for future download.

Topic 1 – Overview of Flash and Flex

DOWNLOAD SLIDES

Topic 2 – Introduction to ActionScript 3 & MXML

DOWNLOAD SLIDES

Topic 3 – Introduction to Flex Components

DOWNLOAD SLIDES

Topic 4 – Event Handling

DOWNLOAD SLIDES

Topic 5 – Remoting Basics

DOWNLOAD SLIDES

Almost all of the lab projects are based on a sample project prepared especially for the QA course. The sample is available for download. After each lab the current state of the project will also be made available for download.

DOWNLOAD THE COMPLETED PROJECT

The ZIP contains two projects that you need to import – a library project and a regular Flex project.

Each lab covers a set of goals as defined here:

Lab 1 – Project Setup & Getting to Know the Flex Builder

  • importing the complete project
  • creating a new project
  • preparing the directory structure
  • adding the entity classes
  • writing the Resources-Utility (plain AS3)
  • adding the Main-Model (demonstrate both in AS3 and in MXML)
  • getting comfortable with DataBinding

DOWNLOAD LAB 1 PROJECT

Lab 2 – Adding Code Behind and View Components

  • adding the Main-View (just MXML)
  • adding code behind for handling events (demonstrate both the Script tag, the base class and the source file)

DOWNLOAD DATA BINDING SAMPLES
DOWNLOAD CODE BEHIND PROJECTS
DOWNLOAD CUSTOM UICOMPONENT PROJECT
DOWNLOAD STATES & TRANSITIONS SAMPLE

DOWNLOAD LAB 2 PROJECT

Lab 3 – Adding and Understanding id’s

Lab 4 – Feeding the List Components with Mock-Up Data

  • use data binding to feed the list components
  • writing the Resources-Data-Adapter (plain AS3)
  • writing the Tree-Data-Adapter (plain AS3)
  • introduce the tree component

DOWNLOAD EVENT HANDLING SAMPLE

DOWNLOAD LAB 4 PROJECT

Lab 5 – Traversing the TreeCheckBox-component

  • understanding why using the Automation API is important
  • including all needed libraries
  • understanding the custom AutomationImpl component

Lab 6 – Adding Custom Method to ExternalInterface and Invoke them through JavaScript

  • adding ExternalInterface.addCallback
  • invoking through Firebug

FLEX SAMPLES: AUTOMATION API SAMPLE APPLICATIONS
DOWNLOAD THE AUTOMATION API DOCUMENTATION (PDF)

DOWNLOAD LAB 5 + 6 PROJECT

Lab 7 – Invoking the Selenium API through JavaScript and Firebug

  • copy the SeleniumFlexAPI.swc to libs
  • add -include-libs “../libs/SeleniumFlexAPI.swc” to compiler arguments
  • demonstrate document["QAFlexCourseProject"].getFlexProperty(“viewstack”, “selectedIndex”);
  • demonstrate document["QAFlexCourseProject"].doFlexProperty(“viewstack.selectedIndex”, 0);
  • add a Button to the Test-View which opens an Alert
  • demonstrate document["QAFlexCourseProject"].doFlexClick(“seleniumTestButton”, “”);

Lab 8 – Simulating User Actions through Dispatching Events

  • demo an attempt of automating user gestures this way
  • demonstrate FlexMonkey

DOWNLOAD LAB 7 + 8 PROJECT

DOWNLOAD AUTOMATION ID SAMPLE

Lab 9 – Verifying Remote Data

DOWNLOAD BLAZEDS PROJECT

0 | comment

MVC Example – Refactored


DOWNLOAD REFACTORED VERSION OF THE MVC EXAMPLE

What’s included in the re-factored version?

  • the MVC approach in now demonstrated not only for the module, but also for the item renderer used in the list component
  • the model adapter pattern is demonstrated too
  • some other minor refinements

Adapting the Model into a Presentation Model

Let’s see the Model Adapter pattern in more detail:

The MXML usage of the model adapter is pretty straight-forward – you can see this in the StatisticsView.mxml:

<programmerListItemModel:ProgrammerListItemModelAdapter id="modelAdapter"
    source="{model.programmers}"/>

And then instead of using the model.programmers you can use modelAdapter.resultCollection:

<list:CustomLayoutList id="list" styleName="programmersList" width="550"
    layout="{model.inAdvancedView ? verticalLayout : fluidLayout}"
    dataProvider="{modelAdapter.resultCollection}"
    itemRenderer="{new ClassFactory(ProgrammerListItem)}"/>

This adaptation is actually in a way demonstration of what means to have a pure abstract model and a presentation model (like in the MVP pattern).

0 | comment

Optimizing Flex Applications


DOWNLOAD SLIDES
DOWNLOAD SAMPLE WITH MEMORY LEAKS

This is the talk we gave at the Bulgarian FlexCamp this year – the event was in Bulgarian, and so is the talk:

Basically optimizations affect two areas of non-functional properties of the software – memory consumption and performance. Since Garbage Collection in Flash affects both memory and performance, it is very important to try describe how the GC works as detailed as we can.

How the GC works?

The part with the GC is mostly taken from the presentation accompanying the Alex Harui’s Garbage Collection and Memory Leaks blog post. The important things to note in this topic are:

  • how the Flash memory allocation works – it prefers to allocate big chunks less often, instead of small chunks frequently
  • the GC is only triggered by allocation
  • the GC doesn’t run completely – there is no guaranty that all unused memory is going to be released (or at least it will not be released in a single pass of the GC)

The conclusion you must absolutely remember is that:

The GC is not predictable!

How to detect memory leaks?

Thanks to the Flex profiler now we can easily observe the memory consumption of a Flex or Flash application. We can interactively run the GC when we want and we can compare memory consumption during various stages of the application. The leaking memory consumption pattern is pretty clear. And so is the stable memory consumption.

Fixing Memory Leaks

Now that we now whether our application is leaking, we need to take a course of action to fill in the leaking spots. Again we can try using the profiler and its feature to detect loitering objects. When you browse through the list of such objects you need to pay special attention to the usual suspects:

  • Array
  • Object used as map
  • Dictionary with strong references
  • failure to remove event listeners

Which event listeners can cause leaks?

We’ll see why children adding listeners to their parents are causing leaks and why there is no such problem in the vice versa situation.

Unloading Third-Party Content

When unloading modules and third-party content be sure to:

  • free bitmap memory
  • stop video streams
  • stop audio streams
  • stop all MovieClips from animating
  • remove event listeners to global list of enterFrame, exitFrame, etc.
  • stop any downloads (http, sockets, FileReference)
  • clear any fonts from the font table

You can use Loader.unloadAndStop() (but only in Flash 10).

Optimization Rules of Thumb

The following are performance optimization rules:

  • always compile in strict mode
  • use typed data structures
  • use sealed classes instead dynamic classes
  • avoid globals when code is deeply nested
  • use vector<> instead Array (only in Flash 10)

Other optimization techniques

Important techniques to mention are:

  • object reuse, especially for renderers
  • avoid the setStyle() method
  • avoid having too many nested containers

LEARN MORE OPTIMIZATION TECHNIQUES AND PRACTICES

1 | comment

Test Driven Development


DOWNLOAD MVC EXAMPLE WITH TESTS
DOWNLOAD SELENIUM AUTOMATION JAVA PROJECT

In this topic we will cover:

  • unit testing with fluint
  • integration testing with fluint
  • automation testing with Selenium and TestNG
  • overview of the Flex Automation API

fluint – Flex Unit and Integration Testing Framework

Based loosely on the concepts of FlexUnit and its ancestor JUnit, fluint provides enhanced asynchronous support, a graphical test runner, integration with continuous build systems and an optional Adobe AIR client for directory watching.

FLUINT HOME PAGE AT GOOGLE CODE
INTRODUCTION TO FLUINT

The repository of the project is organized in the best way I’ve seen so far in a Flex open source project. The structure is optimized for fast setup – you just need to check out a project into your workspace and you’re ready.

Unit Testing

The goal of unit testing is to verify and validate that individual pieces of code fit for use. With fluint you can do a variety of tests:

  • simple assertions
  • asynchronous tests (testing asynchronous communication and services)
  • asynchronous test setup (waiting for creation completed before test start)
  • test visual components

WRITING A FLUINT BASIC TEST
WRITING ASYNCHRONOUS TEST
USING ASYNCHRONOUS SETUP

If you download the MVC Example you’ll find the testing code in the src/test directory.
The simple assertion is demonstrated in TestStatisticsServiceRandomLinesOfCode.as
Simple asynchronous test is demonstrated in TestStatisticsServiceOperations.as
You can see an asynchronous test setup in the following test cases:
TestInitialization.as
TestFiltering.as
TestLayoutChange.as

Some Additions to fluint

Since we’re dealing with RIA we must pay a great deal of attention to the interactions. Some interactions can not be automated easily and may require human intervention. Thus we must create some sort of a hybrid between a unit test and a functional test. To initiate the assertions the tester must perform a certain interaction with the unit under test, which is usually a visual component with a complex gesture that’s difficult to automate. The unit test is still part of a test suite, but the difference is that is should not fail while waiting for the designated interaction to be performed. The current implementation of asychHandler() expects a timeout to be specified. I’ve introduced a slightly modified method that will wait for unspecified period of time:

/**
 * Same as asyncHandler, but doesn't have a timeout
 */
public function waitingHandler( eventHandler:Function ):Function {
    var asyncHandler:WaitingHandler = new WaitingHandler( this, eventHandler );
    asyncHandler.addEventListener( WaitingHandler.EVENT_FIRED, handleAsyncEventFired, false, 0, true );

    pendingAsyncCalls.push( asyncHandler );

    return asyncHandler.handleEvent;
}

This method is part of the CustomTestCase which inherits the fluint base TestCase class. The WaitingHandler class inherits the fluint AsyncHandler.

In order to have visual testing I’ve modified the sample TestRunner and extended it with a visual testing environment. You can take a look at my modifications in the UITestRunner.as

RUN THE UI TEST RUNNER (FIRST TEST WAITS FOR THE USER TO CHECK THE CHECKBOX)

Integration Testing with fluint

After components and modules were unit tested (individually tested), the next step is to compose them into a bigger group and test the behavior of the whole group. Integration tests may be a bit more complex than unit tests. For complex test cases fluint provides us with test sequences.

READ MORE ON TESTING WITH SEQUENCES

Check out my sample test case that’s using sequences – TestLayoutChange.as

Automating fluint Unit and Integration Tests

Automation of unit and integration test is important part of a Continuous Integration build. Currently for fluint an Ant wrapper for the tool is available.

READ MORE ON CONTINUOUS INTEGRATION WITH FLUINT

Testing Flex Application with Selenium

Bad news for the QA engineers – I was able to produce only manually Selenium tests in Java for replaying a sequence of user gestures. Right now for testing Flex applications with Selenium there is only one available extension, but it works only with the old Beta 1 of the Selenium IDE when running only on Firefox 2. I haven’t tested that configuration. So currently there is no easy way for automatically recording the user gestures taken in the course of using a Flex application. And all my Selenium tests had to be written manually.

DOWNLOAD SELENIUM AUTOMATION JAVA PROJECT

For the above project you need a Selenium server and a Selenium remote control.
There are two partial solutions available for testing Flex applications with Selenium.

Selenium Flex API

As I’m writing this I see that today a new version of the API is available and the release notes for this version claim that it should work with the latest beta of Selenium IDE. I really want to check it out but for some reason the ZIP can’t be downloaded right now.

DOWNLOAD SELENIUM FLEX API

The Selenium Flex API consists of several components:

  • SWC that you must import to the Flex application with the -include-library compiler switch
  • JavaScript extension to the Selenium IDE, so you can record user gestures – this extension works only for Flex applications that have already included the above SWC
  • Selenium Remote Control client – I bet the provided class is automatically generated with some tool – the code contained syntax errors and did not prove as working

Flash-Selenium

The flash-selenium project aims to extend the Selenium RC clients for adding Flash communication capabilities. It basically adds the capability to invoke Flash functionality through JavaScript and the ExternalInterface feature of Flash. I don’t like this approach, because you need to expose a great deal of functionality as ExternalInterface and this approach can’t be applied for black box testing.

GOOGLE CODE HOME PAGE OF FLASH-SELENIUM

My sample = Flash-Selenium + Selenium Flex API

My sample uses both the Flash-Selenium remote control client and the Selenium Flex API SWC included in the Flex project. Let’s look at the code of the test case:

@BeforeSuite
public void startSeleniumServer() throws Exception {
	seleniumServer = new SeleniumServer();
	seleniumServer.start();
}

This is TestNG preparation method before starting the test suite.

The following is a setup method for each test case. Please, note the way I’m using Flash-Selenium:

@BeforeTest
public void startBrowser() throws Exception {
	selenium = new DefaultSelenium("localhost", 4444, "*firefox", BASE_URL);
	selenium.start();
	selenium.open(URL);

	flexApp = new FlashSelenium(selenium, FLEX_APP);
	while (flexApp.PercentLoaded() != 100) {
		Thread.sleep(1000);
	}
	Thread.sleep(5000); // extra assurance that everything is loaded
}

Now that the Flex application is up and 100% loaded the test is ready to be run. Please, note the way I invoke functionality in the Selenium Flex API SWC through Flash-Selenium:

@Test
public void checkLayoutUpdate() throws Exception {
	flexApp.call("doFlexClick", "advancedViewCheckbox", "");
	Thread.sleep(5000);

	String isChecked = flexApp.call("getFlexCheckBoxChecked", "advancedViewCheckbox", "");
	Assert.assertEquals(isChecked, "true");

	String listData = flexApp.call("getCustomLayoutListData", "#");
	Assert.assertEquals(listData.split("#").length, 9);

	flexApp.call("doFlexClick", "filterTextInput", "");
	flexApp.call("doFlexType", "filterTextInput", "br");
	Thread.sleep(5000);

	listData = flexApp.call("getCustomLayoutListData", "#");
	String[] items = listData.split("#");
	Assert.assertEquals(items.length, 2);
	Assert.assertTrue(items[0].toLowerCase().contains("br"));
	Assert.assertTrue(items[1].toLowerCase().contains("br"));

	flexApp.call("doFlexDoubleClick", "filterTextInput", "");
	flexApp.call("doFlexType", "filterTextInput", "");
	Thread.sleep(5000);

	listData = flexApp.call("getCustomLayoutListData", "#");
	Assert.assertEquals(listData.split("#").length, 9);
}

Notice some methods are part of the Selenium Flex API and some methods are exposed on purpose through ExternalInterface. The following is part of the CustomLayoutList.as:

// Methods exposed only for Selenium testing purposes:
private function initializeExternalInterface() : void
{
    ExternalInterface.addCallback("getCustomLayoutListData", getCustomLayoutListData);
    ExternalInterface.addCallback("getCustomLayoutListLayout", getCustomLayoutListLayout);
}

A More Cleaner Approach

A more cleaner approach would be to use the Flex Automation API:

adobe-flashplatform-diagram

An appropriate agent class for Selenium should be created and an appropriate JavaScript extension to the Selenium IDE.

READ MORE ABOUT THE FLEX AUTOMATION APIS
CHECK ADOBE’S AUTOMATION SAMPLE

The following illustration shows the initialization process of the SystemManager, AutomationManager and Automation objects:

automation-initialization

And this is how the automation flow works:

automation-flow

Related Articles

Selenium-Flex-Tests with Maven
Flex acceptance testing and continuous integration

2 | comment

MVCS Example


DOWNLOAD MVC EXAMPLE

Just as I’ve promised an example MVC module was demonstrated and discussed in today’s session. The example is far from perfect but it provides a fundament for discussing various design decisions when we implement an MVC example.

Sample Requirements

The request is to implement a Programmer Statistics Module with the following requirements:

  • the module should provide basic and advanced view for a list of programmers
  • use text input to filter the list
  • use checkbox control to switch between the basic and advanced view
  • in advanced view the user can delete programmers
  • in advanced view the user can show the programmers statistics
  • programmers statistics should be represented by a chart showing the lines of code written in a month by the programmer
  • switching back to basic view should make all expanded items to collapse their statistics view

RUN THE MVC EXAMPLE
VIEW MVC EXAMPLE SOURCE CODE

As you look at the working application, you must be able to isolate the Model, the View, the Controller and the Services layers.

The Model

What’s comprising the model?

  • collection of programmers’ data
  • a flag indicating whether we’re in advanced view

Keep in mind that the list of programmers is pure data – a single item from the list has only data properties and no representation related properties whatsoever.

The View

Among all other controls the View also contains a List component. The abstraction of the list component can be explained basically by the following 3 things:

  • data provider – a collection of data items – the List observes all changes happening to this collection and reacts correspondingly by adding or removing list items
  • item renderer – a factory for creating item renderer components – the instances created by the factory we call list items
  • layout strategy – a strategy for arranging the positions and dimensions of the list items in the list

The List component is the only component that communicates directly with the list items. This is how the List adds a single list item:

private function addItem(itemData : Object) : void
{
    var item : IDataRenderer = itemRenderer.newInstance() as IDataRenderer;
    item.data = itemData;

    listItems.addItem(item);
    dataToItemMap[itemData] = item;

    UIComponent(item).addEventListener(ResizableItemChangeEvent.DIMENSIONS_CHANGE, handleItemDimensionsChange);

    addChild(UIComponent(item));
}

In a way the item’s data property is the item’s model, but since we feed the List with a collection of programmers’ data items, which are pure data this brings the following problem:

How do we initialize all of the properties in the Model of the item renderers’ instances?

One solution to this problem is the application of a pattern called Data Binding Adapter.

The Data Binding Adapter Pattern

The data binding adapter pattern is a way of structuring data binding expressions.
Currently the List is initialized in the following way:

<list:CustomLayoutList id="list" styleName="programmersList" width="550"
    layout="{model.inAdvancedView ? verticalLayout : fluidLayout}"
    dataProvider="{model.programmers}"
    itemRenderer="{new ClassFactory(ProgrammerListItem)}"/>

Let’s try to adapt the collection:

<adapter:ProgrammerListItemAdapter id="adaptedModel"
    programmers="{model.programmers}"
    inAdvancedView="{model.isAdvancedView}"/>

The adapter is bound to the properties of the original Model and can take actions when the original Model changes – e.g. when the inAdvancedView property changes to false the adapter goes through each item of the itemsModels collection and changes the statisticsShown property to false:

public var itemsModels : ArrayCollection /* of ProgrammerListItemModel */

private function set inAdvancedView(value : Boolean) : void
{
    if (!value)
    {
        for each (var model : ProgrammerListItemModel in itemsModels)
        {
            model.statisticsShown = false;
        }
    }
}

 

And finally we bind the List to the adaptedModel.itemsModels instead of model.programmers:

<list:CustomLayoutList id="list" styleName="programmersList" width="550"
    layout="{model.inAdvancedView ? verticalLayout : fluidLayout}"
    dataProvider="{adaptedModel.itemsModels}"
    itemRenderer="{new ClassFactory(ProgrammerListItem)}"/>

Tell me what you think about this approach?

Containers

Let’s take a look at the StatisticsModule.mxml where all components are wired to each other:

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas
    backgroundColor="0xffffff"
    creationComplete="controller.initializeModel();"
    xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:model="module.statistics.model.*" xmlns:view="module.statistics.view.*"
    xmlns:control="module.statistics.control.*" xmlns:service="module.statistics.service.*">

    <mx:Style source="module/statistics/style/statistics.css"/>

    <model:StatisticsModel id="model"/>

    <view:StatisticsView id="view" width="600" height="100%"
        model="{model}"
        viewModeChange="controller.switchViewMode();"
        deleteButtonClick="controller.deleteListItem(event.target);"
        requestStatistics="controller.loadProgrammerStatistics(event.programmer);"
        filterChange="controller.filterProgrammers();"/>

    <control:StatisticsController id="controller"
        model="{model}" view="{view}"
        programmersService="{services.programmersService}"
        statisticsService="{services.statisticsService}"/>

    <service:Services id="services"/>

</mx:Canvas>

Notice anything strange or troubling?
The question is:

Do I have to wire the Model, View, Controller and Services inside of a Canvas container? Isn’t it the View, the only View in the MVC? Why is my MVC a container itself?

You can do two different things in this case:

  1. Strip out the StatisticsView component and include its composite components directly in the module root Canvas. Thus we eliminate one redundant container. A negative side effect of this modification is that the view is not isolated in a self-container component. The following approach is better:
  2. Use a non-visual component for a root tag. When using a non-visual component for a root tag, there is an extra programming effort to add the View to the application container:
private function addStatisticsModule() : void
{
    var module : StatisticsModule = new StatisticsModule();
    container.addChild(module.view);
}

2 | comment