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 (27)Add Comment
Tim Fulmer
September 26, 2008
74.212.149.2
Votes: +1
...

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: +1
...

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.

navi
July 14, 2009
125.16.81.252
Votes: +0
...

Really nice post.. thanks alot.

I am facing problem in getting data from data grid, in tab navigations & clicking links.

Can u plz help me & provide any solution to it..

Thanks in advance

Akbar
July 15, 2009
208.240.243.170
Votes: +0
...

Hi,

I had a question. whats does "MyFlexSWF" in the statement
flashApp = new FlashSelenium(selenium, "MyFlexSWF");
correspond to?

Thank You in Advance

Julia Dain
July 15, 2009
78.86.232.161
Votes: +0
...

@navi - Fergal Hanley, the Selenium Flex API project owner, says that "Better support for DataGrid will be provided with the 0.2.6 release (17th July 09). It'll be well documented also" so perhaps that will help with your problems.

@Akbar - "MyFlexSWF" corresponds with the name of your .swf file, without the .swf suffix.

navi
July 16, 2009
125.16.81.252
Votes: +0
...

Hi Julia,

Thanks for your reply..

I had one question.. will 0.2.6 verion will provide support for advance data grid also??

I am using 0.2.4 version of selenium Flex API, I have tried to click links & tabs, but I am facing problem in that. Previously focus was not coming to link, the same is happening now but click event is not triggering.

Can u plz help me by providing some solution to it..

Thanks in advance.

raj
July 20, 2009
163.231.6.67
Votes: +0
...

Hi Julia,

This article was very helpful for me. In the actionscript methods, the flex elements are identified using the "id". How do we make it work using the property "automationName". Some of the flex controls do not have the "id" property populated. But it has the automationName. I have been trying to modify the methods "getElementById" and "getElementByIdRecursive" to make it work for "automationName". No luck so far.

Any help would be greatly appreciated.

Thanks much
Raj

navi
July 29, 2009
125.16.81.252
Votes: +0
...

Hi,

I am trying to automate Menu bar, button bar using Selenium Flex API. I have used click,select & also flexClickMenuBarUIComponent command but in all the cases I am getting error as "Object doesn't support this property or method".

Can u plz provide any solution to resolve this issue..

Thanks in Advance..

Shri
August 08, 2009
204.50.70.7
Votes: +0
...

Hi,

I have TabPanels in my flex app i'm not able to navigate from one tab to the other tab i'm using flexseleniumAPI.And wat are the diferent methods availble in FlexUISelenium for working with differenr components like dropdownlists.

Thanks
Shri

Akbar
August 11, 2009
208.240.243.170
Votes: +0
...

Hi Julia,

I have been stuck at this problem real bad. I use a repeater component with id say "x" and it has 2 components which would be repeated with ids say "y" and "z". Now if the repeater runs multiple times i am not able to test these multiple instances of components coz they have just one id. Could you please help me out with this prb.

Thank You in Advance
Akbar

Abbas
August 18, 2009
65.116.116.6
Votes: +0
...

Excellent post indeed!
@Akbar - Did you get your issue resolved? Have you already tried FlexMonkey for this i.e. capture the actions, component properties and verifications in flexmonkey and export its actionscript to your xUnit framework?

Shri
September 02, 2009
203.13.146.61
Votes: +0
...

Hi all,
I have tree & popup(menu bar) in my flex app how to handle them.


Thanks
Shri

Shri
September 04, 2009
203.13.146.61
Votes: +0
...

Hi all,
Wats up frnds! i'm finding no responses for any of the quries.
Did any one worked on link buttons in flex i'm not able to detect the link button & if i try to read the text its giving null value.

Thanks,
Shri

Joao
December 15, 2009
189.89.46.250
Votes: +0
...

You link an article about unit tests and continuos integration, but your link points to an admin area ( http://www.blackpepper.co.uk/m...ation.html )

I guess it should be http://www.blackpepper.co.uk/b...ation.html

Write comment
 
  smaller | bigger
 

security image
Write the displayed characters


busy