Sunday, 28 February 2010

Running FlexUnit 0.9 tests on a headless *nix server

Using continuous builds to provide a constant overview of the health of your code base is a fairly easy to achieve with Flex projects, by using Ant. Running unit tests should ideally also be a part of this process, because developers often won’t run them before every check in. There is no problem running Flex Unit tests on a Windows server but *nix servers are often used as compile servers for a variety of reasons including cost. Flash Player requires a display to run, and most compile servers in my experience don’t have one. It is in fact very easy to get around this problem, by using a piece of software called XVFB (X Virtual Frame Buffer).

XVFB creates a virtual X server which can be used to satisfy Flash Player’s requirement for a display without having a physical display. This is very useful for running FlexUnit tests as it’s not necessary to see flash player running, just to retrieve the test report at the end. You can read more about the ant task here.

xvfb :21 &
export DISPLAY=:21
#Run your tests here, eg, ant runTestsTarget 

These commands will start the virtual server, set it as the current display and run your tests. You can, of course, just start XVFB once and leave it running rather than continuously starting and stopping it on every run of your tests. This simple tool makes running unit tests on a headless *nix server very simple.

Sunday, 14 February 2010

Optimising Modular Flex Applications using Link Reports

The benefits of creating a modular architecture for large Flex applications has been widely discussed.  When using such an architecture it is important to ensure that your compile process is correctly optimised. The risk with using multiple modules is that classes are compiled into more than one module which results in an unnecessary overhead.  Remember that once the definition for a class has been loaded, any future definitions will be ignored when using a single ApplicationDomain or child ApplicationDomains.  This means that if your main application includes a given classes, a definition for it in any modules you load will never be used. The simple fix for this is to compile all of your modules against the link report of your main application.  This is obviously only suitable if your modules are not going to be loaded by any other application.  The link report is an XML file that describes every class that has been compiled into a SWF, it includes information on the unoptimised and optimised size of every class. To generate a link report you need to apply the following compiler argument: -link-report=myReport.xml.  To compile against a link report and hence optimise your modules, use the following compiler argument: -load-extern=mainAppReport.xml.

The basic optimisation described above may suffice for simple use cases, but sometimes a better understanding of the compiled output is required.  If you compile a main application and multiple modules, analysing the compiled output can help you to understand where optimisation can be achieved.  The following shell script can be run over a directory of link reports, so simply apply the compiler argument given above to your main application and all your modules and run this script (*nix based OS, not Windows).  The output of this is a list of every class compiled into your SWFs and the number of times each class is compiled in.

grep -o "(.*)" *.xml | sed -e 's/\//./g' | sed -e 's/[()]//g' | sort | uniq -c | sort -r

Here's a brief explanation of how it works:  Extract all of the class names (contained between brackets) from the xml link report files, replace the slashes with dots (to give standard fully qualified class names), remove the brackets, sort the list (required by uniq), output a list of unique names with a count and then sort the list in reverse order.

The resulting list should help you to identify classes that are compiled in lots of times.  The libraries that these classes are in will most likely make good candidates for RSLs.  By using the library as an RSL you will load all of the class definition at application startup, which means that that you can externalise these dependancies from all of your modules.  After doing this if you run the script again you should find that these classes are not duplicated.  The first obvious choice for RSLs are the framework, RPC and visualisation RSLs, as these are provided ready to use (see this). It is vital that you externalise any RSLs for SWFs you load, be that compiled style sheets or modules.  To do this use the -external-library-path argument, or in Flex Builder in the project properties set the link type to external.  You can do this with Flex ant as follows:

<mxmlc ...>
   <external-library-path dir="path/to/lib_directory" includes="parlsey.swc"/>
</mxmlc>

It may be a matter of trial and error, but by looking at your link reports you can learn a lot about the classes included in your application and how this affects your file sizes.  Keeping an eye on these statistics over the lifetime of your application is vital so that you can see when things change and understand how to put them right.  A class that is compiled in more than once isn't necessarily a bad thing, you shouldn't expect to see a list of classes where there is only one occurrence of each.  Using RSLs adds a startup overhead of both time and memory.  If you only use 10% of the classes in a library you are undoubtedly better to compile in a few duplicate classes across your modules rather than load the whole library as an RSL at startup.

Sunday, 17 January 2010

Debugging Flex/QTP Issues

Once you have setup a working QTP build, debugging problems can be really tricky. This is mainly because the errors that are reported (if any) aren’t particularly helpful and the documentation is pretty slim. It can also be pretty hard to know how to tackle QTP performance issues. This post will explain some of the techniques I’ve found useful in debugging and solving these issues.

When the Flex/QTP integration encounters an error it traces the problem rather than logging it. This means that to debug problems you will need to connect your QTP enabled application to a debugger in order to see the trace statements. This can make everything run very slowly, so I suggest enabling the logging of trace to a log file which you can examine when you encounter a problem. This can only be done on a debug player, full details can be found here. The second place you can look is QTP’s logs, although I have generally not found them to be very helpful. An explanation of how to enable these logs can be found here.

The most common problem I've encountered while recording or replaying QTP scripts is the object you are trying to identify simply shows up as a “WinObject” or “ActiveX Object”. This happens because QTP cannot detect the hierarchy of object within Flash Player so it simply identifies it an the ActiveX object, i.e. the ActiveX Flash Player. When you see this happen there should be trace of the error message that has occurred for you to check. Most frequently the error message will be “2 matches for criteria {...}”, this generally means that QTP found 2 or more objects that appear to be the same. By default QTP will only use the type of the object, the automationName and the object's location to uniquely identify it, so if multiple objects exist that are the same type and have the same or no automation name then this error will occur. Remember that QTP does not necessarily see the same hierarchy of objects that actually exist in your view. Components that are under different parents may appear to be under the same parent to QTP if the common parent has its showInAutomationHierarchy set to false. This problem can easily be solved by picking unique automation names and including extra containers in the automation hierarchy to ensure uniqueness.

When built with automation support, mouse clicks only propagate through one level of the view hierarchy. This means that if you have a container on top of another component, say a button, you will not be able to press the button, and hence record clicks on it.  Details of this "bug" can be found here. One way around this is to rearrange your view so the component you wish to interact with is on top of the container, alternatively you can set mouseEnabled to false on the container so the event propagates through.

The performance of recording and replaying QTP scripts should generally be good on a small application but it can become a problem on larger applications. QTP descends the view hierarchy looking for the components to interact with, this can become slow in certain situations. It seems that the search works much better if your tree of components, that QTP sees, is deeper rather than flat. This can easily be achieved by setting showInAutomationHierarchy to true on key containers. This partitions the search space and makes it faster to search, and hence replay scripts. The downside of this is that the scripts recorded will have longer chains of components which couples the scripts even further to the layout of your application. This coupling is a problem when you change the layout of view components in your application because your QTP scripts will need updating to reflect the new layout. Flex 4 claims to improve this performance issue relating to automation.

Sunday, 3 January 2010

Flex/QTP Automation Delegates

In the previous posts I alluded to the fact that you may sometimes have to write custom delegates. Delegates are objects that sit along side every instance of a visual component (when automation is enabled) and interact with the automation software. Delegates exist so that you do not have to place automation related code in you standard components, after all, most people don’t want to run their applications with automation support. Delegates are provided for all the framework classes and will generally work out of the box for any framework class you extend. The need to write custom delegates arrises if you create a custom component that directly extends UIComponent or if you have complex requirements for a component which already has a framework provided delegate.

Delegates register themselves with a given type, for example UIComponentAutomationImpl registers itself as the delegate for UIComponent. When determining which delegate to use for a component the inheritance hierarchy is ascended until a class with a delegate registered is found. If you extend UIComponent then you will, by default, get the delegate for UIComponent. The implementation of UIComponentAutomationImpl provides most of the functionality that you will need for a custom delegate by simply subclassing it.

Automation delegates have two main roles. The first is to record and replay the events generated by user interaction. The second is to provide the automation framework with a collection of automation enabled children. The implementation of UIComponentAutomationImpl does neither of these things by default. In most circumstances, simply recording click events and returning all children is enough to automation enable your component. I have provided a sample implementation below.
[Mixin]
public class ExampleComponentAutomationImpl extends UIComponentAutomationImpl
{
 public function ExampleComponentAutomationImpl( obj : ExampleComponent )
 {
  super( obj );
  recordClick = true;
 }
  
 public static function init( root : DisplayObject ) : void
 {
         Automation.registerDelegateClass( ExampleComponent, ExampleComponentAutomationImpl);
 }
  
 override public function get numAutomationChildren() : int
 {
  return ExampleComponent( uiComponent ).numChildren;
 }
  
 override public function getAutomationChildAt( index : int ) : IAutomationObject
 {
  return ExampleComponent( uiComponent ).getChildAt( index );
 }
}
This delegate enables the recording of clicks by setting a property in the super class. If you wish to listen for other events then you should add listeners in the constructor, you can follow the example of UIComponentAutomationImpl to do this. This implementation also overrides the two functions (get numAutomationChildren and getAutomationChildAt) needed to enable a component’s children to be found by the automation framework. You could put more complex logic in these functions to exclude certain children. The only code here that may strike you as slightly strange is the use of the [Mixin] metadata. This is an almost undocumented feature that ensure that the init function of a class will be called at class loading (generally application startup). We need this “bootstrap” to initially register our delegate before any instances of the related components are created.

Delegates are designed to be non-intrusive objects that can be loaded if necessary when using automation software. This means that your components should never reference a delegate, the result of this is that they will not be compiled into your resulting application. To force this inclusion you need to use the “-includes” compiler argument, which given a list of space separated fully qualified class names ensures that the classes are compiled into the resulting application whether or not they are referenced. The easiest way to maintain this list may be to create a custom flex config file which would take the following format, loading these is described here

<flex-config>
   <includes>
      <symbol>name.space.ExampleComponentAutomationImpl</symbol>
      <symbol>name.space2.ExampleComponentAutomationImpl2</symbol>
   </includes>
</flex-config>

The final step in supporting custom flex components is updating the TEAFlexCustom.xml file which lives in the “QTP_Plugin_Install_Location\Flex 3 Plug-in for Mercury QuickTest Pro” directory. This file is used by QTP to find out the events, properties and function that can be accessed on the components. This file must be maintained to match the components and delegates. A good guide to editing this file can be found here. One point to clarify is the forVerification and forDescription attributes of properties. forDescription specifies if the property can be used to help uniquely identify the component and forVerification specifies if the property can be verified during a test.

Monday, 19 October 2009

“Updating Duplicate Resources”?

What is Flex Builder doing when it tells you it is “Updating duplicate resources” at the end of building your application? During this step Flex Builder copies over various files other than the compiled SWFs to your output directory. These files include everything in your html-template folder and any non-embedded source files. Depending on where you build to, this can take a fair bit of time. For example, if you build to a directory on a non-local web server.

There are a few ways to minimise this and hence speed up your builds a little. The first is to unselect the “Copy non-embedded files to output folder” option on your projects’ compiler settings. This option causes any files under your source directory to be copied to the output directory if they have not been compiled into the SWF. You may however need this option if you keep files such as assets under your source folder that need to be loaded by your application from the build location.

The second thing you can do is to only keep required things in your html-template folder. By default this contains a Flash Player installer SWF and history files, in reality you probably only want to distribute these with you release builds and not copy them over every time you compile the application as a developer (hopefully you have Flash Player installed!). The problem may be even worse if you build modules, because each one of these may have an html-template directory. Sometimes it is convenient to keep other files in your html-template, such as assets, xml data files, etc. If the content of these has not changed since you last build then there is no need to copy these over again as it just adds time to your compilation. I would suggest just copying these over manually when they change or creating a simple script to do it for you. You could even link this script into Flex Builder as an External Tool so that you can run it from Flex Builder.

Saturday, 10 October 2009

Building & Deploying an Automated Flex Application

There are a couple of ways to building a QTP enabled application. The first approach is to directly compile your application with the automation SWCs. The second approach is to create an application with a SWFLoader that has been compiled with the automation SWCs and load in your main application. The pros and cons of the two approaches are discussed further below.

Building a QTP enabled Flex application is simple (details here), but the issues around it require some consideration. If you simply compile your application with the automation SWCs your production code will be automation enabled. This introduces a security risk by allow users (other than your test team) to use the application with QTP. There is also a performance cost because SWFs are larger (due to the addition of extra automation classes), which will increase the initial download time. A runtime memory and performance overhead is also observed due to the attachment of a delegate object to every instance of a visual component and the registering of these at application startup. More on delegates coming in a later post.

Regression testing should always be performed on the same build that will be used in production, this leaves the automated tester with a problem. Do you create two builds, an automated and non-automated one, or do you allow automation enabled applications to be used as production systems. I would always push for the former, although you may be best to let the teams concerned with security, performance and testing decide. If you do opt for building two versions of the application this will double your build time, not insignificant on most enterprise projects.

The alternative is to create a QTP wrapper application. This application will load you main application and enable the automated testing of it. If you have a basic application then you can simply use the example given on the Adobe LiveDocs. If you need to use custom delegates then you will also need to compile these into the wrapper application. When doing this it is vital that you load the application into the same Application Domain as the wrapper. Failing to do this will most likely cause run time exceptions or unexpected behaviour. The clear advantage with this approach is that you only need to compile one additional application and this application is small and quick to build.

Using the wrapper approach has one other benefit, and this is that your wrapper and application can have separate release cycles, meaning that fixing a QTP related bug does not necessarily require a new build of the whole application. For example, if you need to change the logic in a custom delegate then you can simply modify that and recompile the wrapper. As your delegates will reference and hence cause classes form your main application to be compiled in to the wrapper, you must ensure that the versions of these classes in the main application and the wrapper are the same to prevent run-time conflicts. One final tip is that if your loaded application requires flash args then you can simply pass them in through the source URL:
<mx:SWFLoader
 source=”loadedApplication.swf?myFlashArg=foo&myOtherArg=bar”
 loaderContext=”myContextWithTheSameAppDomain”
 />
In general I prefer the wrapper approach as it overcomes some of the concerns that the first approach raises. However, if you have a simple application where you are not concerned about the performance overheads (which are not that high on a small application) then the first approach may be easier for you. Although the first approach allows a user to easily use your application with QTP, if they really wanted to, they could follow the second approach and write their own wrapper and use it anyway.

Wednesday, 30 September 2009

Flex Manifest Files (with Flex ant)

All of the Flex framework components are mapped to a single namespace, this means that you are only required to use one import in MXML to use any framework component (xmlns:mx="http://www.adobe.com/2006/mxml"). The main advantage of this is a short list of imports, but it also means that the underlying package structure could change without needing to recompile your MXML classes.  Note that Actionscript classes always require the full package name when imported.  The following snippet provides an example of how the single namespace will appear even though the three components are in different packages:
<mx:Application
   xmlns:mx="http://www.adobe.com/2006/mxml"
   xmlns:custom="http://custom.namespace"
   >
   <custom:MyComponent />
   <custom:MyContainer />
   <custom:MyAsset />
</mx:Application>
It is actually possible to do the same for your own libraries, by using a manifest file. A manifest file is specified when compiling your library, and it provides a mapping between a single namespace and a list of fully qualified class names.  Your library must be included as a SWC in Flex Builder in order for the single namespace to be picked up, it will not work if the library is included as a project.  Auto-complete will work in Flex Builder providing the library is included in this way.  Although a new namespace is specified, the old namespace can still be used, this makes introducing a single namespace backwards compatible.

There are two steps to compiling your library in this way, the first is creating a manifest file. This is a simple XML file like the one below, which specifies mappings between the fully qualified class name and the new tag for the class:
<?xml version="1.0" encoding="UTF-8" ?>
<componentPackages>
   <component id="MyComponent" class="com.benlondon.component.MyComponent"/>
   <component id="MyContainer" class="com.benlondon.container.MyContainer"/>
   <component id="MyAsset" class="com.benlondon.asset.MyAsset"/>
</componentPackages>
The second step is to specify the new namespace and manifest file to the compc compiler. In this example the compiler arguments would be:
-namespace http://custom.namespace manifest.xml
-include-namespaces http://custom.namespace
The Flex ant compc task requires configuration as follows:
<compc ...
  >
   <namespace uri="http://custom.namespace" manifest="manifest.xml" />
   <include-namespaces>http://custom.namespace</include-namespaces>
</compc>
Once you have built your library as specified above, users of your library are ready to start using a single namespace. Flex Builder seems to choose the namespace prefix (in my example "custom") as the first part of a URL chosen as a namespace.