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.