Automated Unit Testing of Flash Applications

Author: AutomatedQA
Last Updated: August 10, 2009
Applies to: TestComplete 7 and ActionScript 2.0

Introduction

Unit testing is a well-known approach for testing different applications and is successfully used in the extreme programming approach. Unit tests can be used as a part of complex regression testing of the application. Automated unit testing is the best mixture of modern testing techniques that provide the most effective business process for software development companies.

TestComplete allows you to create automated unit tests with ease. This article explains an interesting QA testing technique that you can use for checking Flash applications. It’s based on using the ExternalInterface class in Flash applications and testing the movie via the Flash container’s methods.

This article describes how to easily automate unit tests for Flash applications with TestComplete.

Basic Concepts

Unit testing is a powerful QA testing technique, which can be used when testing Flash applications as well as other applications developed in C++, C# and many others. Unit testing is at its highest efficiency when automated.

What is Unit Testing

Unit testing is an effective approach for checking the application functionality. According to this approach, you create applications and write unit tests for them simultaneously. A “unit” may be anything from a single function to an entire library. The essential point of unit testing is that only a small part of the intended application is tested. A unit test checks how a particular application unit interacts with other application parts and modules or with the user. A unit test can be a group of methods called with particular parameter values. These methods must retrieve previously known results. The results should reflect the behavior of the tested application’s unit. If the obtained results differ from the expected results, an error notification is sent to the developer.

Unit tests are used in test-driven programming approach or Test Driven Development, which is often common with Agile development. According to this technique, tests for checking the application’s behavior are written before this behavior is implemented. There is a common scheme used in this approach and is explained further in The Test-Code-Simplify cycle chapter, pg 159, of the Extreme Programming Applied book:

  • Write a single test
  • Compile it. It must not compile, because you haven't written the implementation code it calls
  • Implement just enough code to get the test to compile
  • Run the test and see if it fails
  • Implement just enough code to get the test to pass
  • Run the test and see if it passes
  • Refactor for clarity and "once and only once"
  • Repeat

We will keep to this scheme in this article.

Selecting Automated Testing Tools for Unit Testing

Flash applications can be developed according to the test-driven development approach as well as other applications. There are two possible unit testing techniques for Flash applications:

  • Create unit tests with special frameworks. For instance, the AsUnit framework

    In this case you should study the framework to be able to write tests with it. You should also make arrangements for additional features that include test automation.

  • Create and automate unit tests with TestComplete

    With TestComplete you don’t need any other tools for creating unit tests. Furthermore, you will be able to easily automate the QA testing process, even if you don’t have programming or testing experience. TestComplete provides high-level test automation as well as back end database and Unit testing.

This article uses TestComplete to create unit tests for unit testing Flash applications.

More Than a Unit Test

Usually, unit tests are created as a part of a tested application. Intended for checking the application’s internal functionality, unit tests do not cover all testing aspects that should be taken into account when creating a quality product. Using unit tests, we cannot check the application’s user interface or, for instance, integration of applications into each other and many other scenarios.

With TestComplete, we create unit tests separately from the application in a special environment. These tests are not strongly “unit” in a common meaning. However, these tests allow us to check the application’s internal methods and they are very similar to natural unit tests in behavior.

Another important aspect of using TestComplete is that you can combine different QA testing techniques for checking your application from all different sides. TestComplete supports a great number of software testing types. So, if you want to create UI tests for a movie, you can create the appropriate tests with TestComplete. If you want to connect unit tests to your regression testing process, you can also do that with TestComplete. Thereby you will save time and money that could be spent on searching for additional techniques and even exploratory testing.

Unit Testing Requirements

The following section describes the needed software and configurations used in unit testing Flash applications.

TestComplete Enterprise Edition

Testing Flash applications requires the Web Testing plug-in that is included in the TestComplete Enterprise Edition. So, unit testing of Flash applications is only available in TestComplete Enterprise.

Internet Explorer 5 or later

With Internet Explorer 5, support for the ExternalInterface class was introduced and all later versions kept up with this support. Currently, TestComplete supports unit testing for Flash applications that are displayed in Internet Explorer.

Adobe Flash Player 10

You can download the latest version of Adobe Player from Adobe’s web site: http://www.adobe.com/go/getflashplayer/

Special Global Security Settings

Working with ExternalInterface class is only allowed for trusted locations, so you should configure your Flash security settings to be able to call ActionScript methods from TestComplete. If you test a local copy of the application, for instance, located on C:\Documents And Settings\user\My Documents\Flash, you should add this location to the trusted location list:

After the location has been specified, we can test Flash applications stored in this folder C:\Documents And Settings\user\My Documents\Flash.

Calling ActionScript Methods from TestComplete

TestComplete has access to class methods defined in Flash applications, which are written in ActionScript. This is possible because TestComplete can use the ExternalInterface class in Flash applications. The ExternalInterface class enables communication between ActionScript and the Flash Player container. The Flash Player container can be an HTML page with JavaScript, or a desktop application with a Flash Player embedded.

You can call ActionScript methods from TestComplete tests if they are exposed to the Flash Player container that is an HTML page. Using a scripting language in TestComplete, you can call ActionScript functions in a Flash Player. ActionScript functions can return a value, and TestComplete receives it immediately as the return value of the call.

TestComplete can receive values of simple data types that can be returned by ActionScript methods:

  • Boolean
  • Number
  • String
  • Date
  • Char

TestComplete cannot operate with custom ActionScript objects. Objects of the Number, String or Date class are custom ActionScript objects that cannot be processed by TestComplete. For instance, if you create numbers as Number class’ instances in your Flash application, you will not be able to check their values with TestComplete. To work around this problem, you can obtain the Number object’s primitive value using the valueOf() method and then return it to TestComplete:

//ActionScript 2.0
public function myFlashFunc() {
var myNumberObject:Number = new Number(5);
return myNumberObject.valueOf(); //returns 5
}

Note that you can also call JavaScript functions defined within HTML pages from TestComplete tests. This allows you not only test Flash applications, but also test the whole web page where the movie is.

Making ActionScript Methods Available to TestComplete

TestComplete can call methods declared in Flash application sources (.as files) via the ExternalInterface class. To use this feature you should add some code to your Flash application.

Modifying Flash Applications (in Flash IDE)

For example, we have an ActionScript class – MyFlashObject which is declared in the MyFlashObject.as file and we are going to test its methods with TestComplete:

//ActionScript 2.0
class MyFlashObject {
public function MyFlashObject() {
}
// Public Methods:
public function NumberToString(n:Number) {
var str = n.toString(); return str;
}
}

To make methods of this class available to TestComplete, you should perform the following actions:

  • Add this reference at the beginning of the MyFlashObject.as file:
    import flash.external.*;
  • Make the desired method external by calling the ExternalInterface.addCallback() method. The following code means that the MyFlashObject.NumberToString() method will be registered as the NumToStr() method of a Flash container. Null is an auxiliary parameter, leave it as null. You can add this code to the class constructor:
    //ActionScript 2.0
    ExternalInterface.addCallback("NumToStr",null,NumberToString);

The NumberToString() method will be registered as callable from a Flash container when you create a class instance. For example, you can create a class instance within the Scene 1 Actions:

//ActionScript 2.0
var MyFlashObject1:MyFlashObject = new MyFlashObject();

Using (in TestComplete)

You can call registered methods from TestComplete tests. You can also receive variant data type values that they return. To do this, you should obtain the Flash container object and then call its method.

For instance, we have an HTML page with a Flash movie in it. The movie uses the MyFlashObject class for converting numbers into strings. This code demonstrates how to call a Flash method from an automated test script. When TestComplete invokes the flashMovie.NumToStr() method of the Flash container, the MyFlashObject.NumberToString() method will be called in the movie:

//JScript
function testExternal() {
// obtaining the page with the tested Flash application
var page = Aliases.Sys.iexplore.pageOrderscontainerHtm;
//obtaining the Flash container object
var flashMovie = page.objectBridgemovie;
//calling the MyFlashObject.NumberToString method
var str = flashMovie.NumToStr(5);
//posting the result value to the test log
Log.Message(str);
}

You may notice the Aliases object in the code above. This object refers to application objects by their short names, or aliases. Aliases can be created automatically when you are recording a TestComplete test or manually from TestComplete’s UI.

Unit Test Sample

All QA tests are organized into projects in TestComplete. For instance, you can have a project for each tested application. Let’s create a new TestComplete project for our Flash application:

  • Launch TestComplete.
  • Click Create New Project on the Start Page.
  • Type the project’s name, select the scripting language and save the project.

Test code samples are written in JScript in this article. The JScript language is very similar to ActionScript, which is used in Flash applications. So, Flash application developers should have no problems with creating automated tests in JScript. However, you may use any preferred scripting language supported by TestComplete. You can also write tests using the keyword testing technology that does not require programming experience at all.

After the project is created, we can add different project items to the project. Project items provide different automated testing features. We will use the Script project item for creating unit tests in it. The Script project item is added to the project by default.

TestComplete Project Structure

Preparing Assertion Functions

According to the unit testing technique, we need special methods for controlling the testing process. These methods inform us about errors that happen during the test execution and save test results to the log. These functions are usually called “assertion functions”.

The assertion functions will be defined in a separate unit. We will add a new unit to the project and name it “AssertionFunctions”. This unit will contain three routines. The isEqual() function checks whether two objects are equal. If not, it uses the equalsError() function to post the error message to the log. In the same way, the isNotEqual() function checks whether the two objects are not equal . The aqObject.GetVarType() method returns the object type code number that is used for comparing object types.

//AssertionFunctions unit
//JScript
function equalsError (Actual, Expected, Msg) {
Log.Error(Msg+": Expected "+Expected+" , but was "+Actual); }

function isEqual(Actual, Expected, Message) {
if (aqObject.GetVarType(Expected)!= aqObject.GetVarType(Actual)) {
Log.Message("Assertion Error: Could not compare: type mismatch. Expected:"+Expected+" Actual: "+Actual); return;
};
if (Expected != Actual) {
equalsError(Actual, Expected, Message);
} else {
Log.Message("Correct: Expected: "+Expected+" Actual: "+Actual);
}
}

function isNotEqual(Actual, Expected, Message) {
if (aqObject.GetVarType(Expected)!= aqObject.GetVarType(Actual)) {
Log.Message("Assertion Error: Could not compare: type mismatch. Expected:"+Expected+" Actual: "+Actual); return;
};
if (Expected == Actual) {
equalsError(Actual, Expected, Message);
} else {
Log.Message("Correct: expected: "+Expected+" Not Equal To actual: "+Actual);
}
}

Creating the Tested Object

Suppose we need a class that would convert degrees from one temperature scale to another, like a TempConverter class defined in our Flash application. For instance, this class will have three methods for temperature conversion:

  • Celsius to Reaumur
  • Celsius to Fahrenheit
  • Celsius to Kelvin

Let’s create the skeleton of this class in our Flash project. Note that we should add the flash.external.* reference at the beginning of the class definition to be able to test its methods from TestComplete.

//ActionScript 2.0
//TempConverter class
import flash.external.*;
class TempConverter {
// Initialization:
public function TempConverter() {
//make methods available for testing with TestComplete
ExternalInterface.addCallback("CelsToReaum",null,CelsToReaum);
ExternalInterface.addCallback("CelsToFah",null,CelsToFah);
ExternalInterface.addCallback("CelsToKel",null,CelsToKel);
}
// Public Methods:
//Celsuis to Reaumur
public function CelsToReaum (CelsDeg) { }
//Celsuis to Fahrenheit
public function CelsToFah (CelsDeg) { }
//Celsius to Kelvin
public function CelsToKel (CelsDeg) { }
}

We should also make sure that an instance of the TempConverter class exists when the unit test starts. To do this, we will create an instance in the Actions Scene 1:

//ActionScript 2.0
//Actions: Frame 1
var TempConverter1:TempConverter = new TempConverter();

Now we are able to call the TempConverter class’s methods after the Flash application movie has loaded to the browser.

Creating a Unit Test

The unit test will consist of individual test cases. Test cases check particular parts of the application that can be tested. We can create a test case for each TempConverter’s method. We will define test cases as scripting routines that check the method’s specific response to a particular set of inputs. To do this, we will add a new script unit to the TestComplete project and define testing routines in it.

At the beginning of each test case routine we obtain the HTML page (the pageOrderscontainerhtm object) with the tested Flash application on it. After that we use the reference to the Flash application’s container to call ActionScript methods from TestComplete. Note that we use aliases for application objects in our script, for instance, “pageOrderscontainerhtm” is an alias. These aliases were automatically generated when we previously recorded a simple test for the tested Flash application. However, you can also create alias names manually from TestComplete’s UI. For more information, see the TestComplete help.

The following testCelsToReaum() routine is the test case for the CelsToReam() method:

//USEUNIT AssertionFunctions
//JScript
//TestTempConverter unit
function testCelsToReaum() {
Log.Message("Unit Test: Celsius To Reaumur. Test Start");
// URL: C:\Documents and Settings\user\My Documents\Flash\OrdersContainer.htm
var page = Aliases.Sys.iexplore.pageOrderscontainerHtm;
var flashMovie = page.objectBridgemovie;
// testing
isEqual(flashMovie.CelsToReaum(100),80,"Convertion Celsius to Reaumur scale is not correct");
isEqual(flashMovie.CelsToReaum(120.5),96.4,"Convertion Celsius to Reaumur scale is not correct. Fractional numbers");
isNotEqual(flashMovie.CelsToReaum(20),0,"Convertion Celsius to Reaumur scale is not correct. 0 is retrieved");
Log.Message("Unit Test: Celsius To Reaumur. Test End");
}

The testCelsToFah() routine is the test case for the CelsToFah() method:

//USEUNIT AssertionFunctions
//JScript
//TestTempConverter unit
function testCelsToFah() {
Log.Message("Unit Test: Celsius To Fahrenheit. Test Start");
// URL: C:\Documents and Settings\user\My Documents\Flash\OrdersContainer.htm
var page = Aliases.Sys.iexplore.pageOrderscontainerHtm;
var flashMovie = page.objectBridgemovie;
// testing equality
isEqual(flashMovie.CelsToFah(68),20,"Convertion Celsius to Fahrenheit scale is not correct");
isEqual(flashMovie.CelsToFah(113),45,"Convertion Celsius to Fahrenheit scale is not correct. Fractional numbers");
isNotEqual(flashMovie.CelsToFah(20),0,"Convertion Celsius to Fahrenheit scale is not correct. 0 is retrieved");
Log.Message("Unit Test: Celsius to Fahrenheit. Test End");
}

The last test case routine checks the CelsToKel() method:

//USEUNIT AssertionFunctions
//JScript
//TestTempConverter unit
function testCelsToKel() {
Log.Message("Unit Test: Celsius To Kelvin. Test Start");
// URL: C:\Documents and Settings\user\My Documents\Flash\OrdersContainer.htm
var page = Aliases.Sys.iexplore.pageOrderscontainerHtm;
var flashMovie = page.objectBridgemovie;
// testing equality
isEqual(flashMovie.CelsToKel(100),373,"Convertion Celsius to Kelvin scale is not correct");
isEqual(flashMovie.CelsToKel(120.5),393.5,"Convertion Celsius to Kelvin scale is not correct. Fractional numbers");
isNotEqual(flashMovie.CelsToKel(20),0,"Convertion Celsius to Kelvin scale is not correct. 0 is retrieved");
Log.Message("Unit Test: Celsius to Kelvin. Test End");
}

Our unit test will consist of three routines: testCelsToReaum, testCelsToFah and testCelsToKel. It is time to automate the test execution.

Automating Unit Tests

The Flash application is tested on an actual web page, so it is useful to automate loading the web page in a browser before starting the unit test. To do this, add Internet Explorer as the tested application to the TestComplete project and then specify the page to be loaded in the browser:

  • Add the Tested Applications project item to the TestComplete project.
  • Add the Internet Explorer executable to the tested applications list.
  • Specify the tested application’s run parameter that is the page’s URL, for instance, file:////C:\Documents and Settings\user\My Documents\Flash\OrdersContainer.htm.

Now we should create two routines that automate starting and closing the browser:

//JScript
//BrowserActions unit
function startBrowser() {
//loads the C:\Documents and Settings\user\My Documents\Flash\OrdersContainer.htm page
TestedApps.iexplore.Run();
}
function stopBrowser() {
TestedApps.iexplore.Close();
}

After preparing all required routines, we can configure our TestComplete project for complete automation. You just need to specify the sequence of scripting routines that will be called and run the whole project. For instance, you can simply drag the needed test routines from the Code Explorer panel to the Test Items page. In our example we created the following test sequence:

Project’s Test Items

For more information on how to specify the test execution order, see the TestComplete help. Now the TestComplete project is completely ready to perform unit testing of our Flash sample, you just need to click the Run Project button from TestComplete’s toolbar to start testing:

Running the TestComplete project

You can schedule TestComplete project’s run and integrate it into your software development process as a part of a big automated macro. AutomatedQA’s Automated Build Studio can automate the whole software build, testing and release process.

The First Testing Act

After preparing the unit test, we should execute it for the first time and see if it fails. To do this, run the TestComplete project and view the unit test results in the test log:

Test Log: Unit Test Failed

As we expected, the unit test failed because tested methods have not been implemented yet.

Implementing the Tested Object

We should implement the TempConverter class’s methods so that they can pass through our unit test. To do this, open the TempConverter.as source file and add the code for temperature conversion:

//ActionScript 2.0
//TempConverter class ...
public function CelsToReaum (CelsDeg) {
var ReDeg = 0.8*CelsDeg;
return ReDeg;
}
public function CelsToFah (CelsDeg) {
var FahDeg = (5/9)*(CelsDeg-32);
return FahDeg;
}
public function CelsToKel (CelsDeg) {
var KelDeg = CelsDeg+273;
return KelDeg;
} ...

Now the tested methods are ready to check for the correct return value results. Note that you should republish the movie after you have made changes to the application source code.

The Second Testing Act

The second test iteration is the main check that controls the results returned by the unit testing methods. You should run the TestComplete project again to get the results:

Test Log: Unit Tests Passed Successfully

As you can see, all unit tests passed successfully. You can view the test log and make decisions on how the tested application works and whether any changes are needed. You can also easily export test results in the XML format, send them by e-mail to the result storage and view them externally in a .mht format.

Conclusion

With TestComplete you can easily create unit tests for Flash applications and automate them. This article describes how to get access to the internal methods of Flash applications via the ExternalInterface class in TestComplete. If you haven’t tried TestComplete, be sure to download it today.

 
© 2010 AutomatedQA Corp. All rights reserved.
Home | Privacy | Terms of Use | About | Contact Us | Site Map | Print