Black Pepper Blog

The thoughts and musings of our team


The problem I had is how to automate acceptance or functional testing of a web application with a Flex front end. I wanted to solve this problem because functional testing increases confidence that the software meets customers' requirements. Automating the tests - coding tests and running them as part of the build - pays dividends over and over, as agile developers well know. We're able to check that user stories are implemented and catch bugs early in the lifecycle.

Kieran's blog entry unit testing Flex tells how he solved the problem of writing and automating unit tests for Flex front-ends. He found there was little available material on unit testing for Flex - and I found even less on acceptance testing for Flex. However, we had done automated acceptance testing for non-Flex web apps.

Selenium is a popular tool in the open source community for automating functional tests for web applications. It allows developers to write tests that drive your web application via the browser. You can write tests in various languages, including Java and JavaScript, and in the test you can manipulate web page components using XPath or JavaScript. So for example I can write a test to enter text into an input element of an HTML form, click the submit button, and verify data on the response page. But how can I do the same sort of thing for a Flex front-end?

I need to be able to manipulate the Flex components of the application. I found two software tools which should help, FlashSelenium and Selenium Flex API.

FlashSelenium is an extension to the Selenium client Java driver that allows a Java test class to call ActionScript methods of the Flex application. These ActionScript methods must be exposed by the Flex developer using the Flex ExternalInterface API to write explicit callbacks into the Flex code under test. The ExternalInterface API allows two-way interaction between JavaScript and ActionScript. FlashSelenium converts the developer's Java test code into JavaScript which the Selenium Remote Control server fires at the Flex application. This looks promising. But there is a big drawback to this approach: I'd have to write extra Flex code for all the callbacks that I want to make, and maybe even extra custom ActionScript methods to support the testing. I'd really like to be able to call general methods to manipulate UI components and inspect values.

Selenium Flex API is an extension to Selenium IDE, a Firefox plug-in which allows interactive testing of web applications. It consists of two parts, ActionScript methods that access MXML components and JavaScript extensions to Selenium IDE to call those ActionScript methods. The developer includes the ActionScript methods in the Flex code under test. The JavaScript extensions then allow a tester to interact via Selenium IDE with the Flex app. Selenium Flex API, like FlashSelenium, uses the Flex ExternalInterface API to facilitate interaction between JavaScript and ActionScript. It exposes a limited number of ActionScript methods for interaction and requires fewer intrusive additions to the code under test: no custom Flex code for testing has to be written. But the major drawback from my point of view is that the testing is not automated, but performed using Selenium IDE. I want to be able to use Selenium Remote Control to run my tests for me.

What I'd like to be able to do is:

  • to write functional tests in Java
  • to run those tests automatically
  • to minimize additions to the application code

If I can integrate FlashSelenium with the Selenium Flex API ActionScript methods, I have a solution. I'll be able to write JUnit test classes using FlashSelenium that call the Selenium Flex API ActionScript methods to manipulate my Flex app. Then I can use Selenium Remote Control to drive my tests. And I will be able to run the whole lot with ant.

JUnit test class --> FlashSelenium --> Selenium-RC Java client --> Selenium-RC server --> Flex app + Selenium Flex API

Here's the JUnit set up code of my test class.

 
   private final static String URL = "http://localhost:8080/MyFlexApp.html";
 
   public void setUp() throws InterruptedException
  {
    selenium = new DefaultSelenium("localhost", 4444, "*firefox", URL);
    selenium.start();
    flashApp = new FlashSelenium(selenium, "MyFlexSWF");
    selenium.open(URL);
    while (flashApp.PercentLoaded() != 100)
    {
      Thread.sleep(1000);
    }
  }
 

This method creates a Selenium object selenium that connects to a local tomcat instance hosting my flex app, and a FlashSelenium object flashApp that allows calls to components of the app.

Here's one of my test methods. This method uses the FlashSelenium object flashApp to make calls to the Selenium Flex API methods getFlexText() and doFlexClick().

 
  public void testInvalidLogin() throws InterruptedException
  {
    assertEquals("", flashApp.call("getFlexText", "userName", ""));
    assertEquals("", flashApp.call("getFlexText", "password", ""));
    flashApp.call("doFlexClick", "submit", "");
    Thread.sleep(2000);
    assertEquals("Invalid username or password", flashApp.call("getFlexText", "loginmesg", ""));
  }
 

The purpose of this method is to test that an attempt to log in with no user name and password will cause an "Invalid username or password" message to be shown. The Flex app contains a couple of text input fields, userName and password, a submit button submit, and a label field loginmesg for display of error messages. The test gets the text value of the userName field with this call:

 
   flashApp.call("getFlexText", "userName", "")
 

and verifies that it's empty, then does the same for the password field. Next it clicks the submit button:

 
   flashApp.call("doFlexClick", "submit", "");
 

and finally checks that the loginmesg field's text value is as expected.

Because I can now write JUnit tests, it's straightforward to automate running the tests with an ant target of the usual JUnit ant task flavour. For my app, the development environment against which to run this ant target consists of a MySQL database and an instance of tomcat hosting the (Java) web app and the Flex front end (swf and HTML). This entry covers adding the test execution to the Hudson continuous integration process. Meanwhile I'm very pleased to be able to add automated functional tests to our Flex project's quality assurance efforts.

P.S. Here's the SeleniumFlexAPI.as file of ActionScript code that I included in my Flex mxml code.


Comments (15)Add Comment
Tim Fulmer
September 26, 2008
74.212.149.2
Votes: +0
...

Excellent post. Seems to be the best Flex app integration testing plan out there now and could close a serious continuous integration testing hole we've got when developing BlazeDS/Spring applications. It would be nice if Selenium Flex API got their recording feature out the door soon, though :) No complaints and good work all around :)

Stu Stern
September 27, 2008
67.176.82.9
Votes: +0
...

You might also want to check out FlexMonkey, an open source Flex GUI testing tool just open sourced by Gorilla Logic. It provides comprehensive record/playback and generates Action-script based tests that can be managed from xUnit frameworks such as FlexUnit.

http://flexmonkey.googlecode.com

Ivan
October 09, 2008
201.195.2.209
Votes: +0
...

Excellent posts... any ideas for testing integration with back end in a continuous way? I've been using Flex Unit to invoke remote methods and it seems to work ok.. just wondering if you have another idea. Thnks

Bernard
October 10, 2008
122.55.80.194
Votes: +0
...

Excellent post indeed!
We are using Selenium-RC's ruby client driver. Any idea how we can integrate the Selenium Flex API to it?
In this example, the SeleniumFlash object is calling the methods/functions from Selenium Flex which is a user extension for Selenium IDE. How did you integrate the javascript file to your JUnit test class? import maybe? Any idea how it can be integrated with ruby's test unit?

Julia Dain
October 13, 2008
78.86.232.161
Votes: +0
...

Thanks for all the nice comments!

Tim - I see that v0.2.2 of SeleniumFlexAPI has been published, but the recording feature is still not implemented.

Ivan - I'm using the above mechanism for integration and system testing driven by Ant, in a Hudson continuous integration environment.

Bernard - SeleniumFlexAPI comes in 2 parts, and this mechanism only uses the part consisting of ActionScript methods which I included in my Flex code. It doesn't use the other part, the user extensions for SeleniumIDE. The JUnit test class calls the ActionScript methods via the FlashSelenium object. One approach to integrating with Ruby might be to rewrite the FlashSelenium Java class in Ruby, for use with your Ruby testing framework. The Java class is an extension of the Selenium RC Java client driver. It's not long and is mostly boilerplate code. So I'm thinking you could write the equivalent Ruby class to extend the Ruby client driver.

I did make some edits to the SeleniumFlexAPI ActionScript include, to remove the tool tips feature and to include DataGrid access. I've added a link to this file, above.

Simon Tiffert
November 13, 2008
78.34.13.10
Votes: +0
...

Thanks for sharing your ideas on Flex testing in this post. It was very helpful and leads me to the right path.

You can find a Maven integration on top of your ideas:
http://www.agimatec.de/blog/2008/11/selenium-flex-tests-with-maven/

Simon

Scott Galloway
January 13, 2009
65.90.33.15
Votes: +0
...

Great post!

I noticed in your SeleniumFlexAPI.as that you added some support for DataGrids which is great, but I was wondering if anyone has solved the problem of getting the UIComponents of a DataGrid. I've been trying for the last couple of days without success.

The example in the SeleniumFlexAPI.as only gets the data which is helpful, but the ItemRenderer of the DataGridColumns might do something with the data and a tester might want to verify the rederered value.

Thanks in advance for any suggestions!

Scott Galloway
January 26, 2009
76.19.150.67
Votes: +0
...

I've since figured out how to add support for DataGrids and their child UIComponents and submitted it to the project admin, with any luck it will be in the next release.

Julia Dain
January 26, 2009
78.86.232.161
Votes: +0
...

Thanks Scott. Look forward to seeing the addition to SeleniumFlexAPI.

fruity
March 19, 2009
122.160.152.27
Votes: +0
...

Thanks for writting such an post . Litreally , helped a lot

Pooja
April 23, 2009
59.162.253.222
Votes: +0
...

Thanks a lot...
post was a great help....

To Bernard...
Did you figure out how to use Selenium Flex API with Ruby Client Driver?? If yes... can you please help me with it...

Paresh
April 28, 2009
203.189.181.135
Votes: +0
...

hey how to include that action script file in flex code

i dont have the source code..

i just hav web pages and swf

Radha
May 15, 2009
202.54.41.53
Votes: +0
...

Hi.. I found it to be very useful information.
I have query. please if anyone can help on it..its urgent..
i ahve to test Flex application using selenium.
I have downloded both FlashSelenium and Selenium Flex API .
but to get Flex objects identified by selenium, we have to add some special code to flex . What is this code , can anyone tell .

Julia Dain
May 18, 2009
78.86.232.161
Votes: +0
...

The Flex code that your Flex app needs is contained in the SeleniumFlexAPI distribution .swc file, SeleniumFlexAPI.swc. Just include this file as a library when you compile your Flex app.

Radha
May 18, 2009
202.54.41.53
Votes: +0
...

Hi.. Julia.
Thanks for reply. According your reply,
we do not need any special code to FLex internals , rite?
I will try it.

Write comment
 
  smaller | bigger
 

security image
Write the displayed characters


busy