automated user tests with apache flex
DESCRIPTION
In a recent Apache Flex project, we needed to implement automated user tests. Selenium is an (open source) tool for automating your browser, but there was no modern (aka working) extension for Flex applications. We've created the open source project Flexium, both a JAVA and ActionScript extension which enables you to communicate between Selenium and Flex.TRANSCRIPT
![Page 1: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/1.jpg)
Automated User Tests with Apache Flex
Gert Poppe@gert789
![Page 2: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/2.jpg)
About me
A Belgian consultant working at Stack & Heap.
A passionate RIA developer.
A ZEND certified PHP Engineer.
A huge fan of the Randori Framework.
![Page 3: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/3.jpg)
What are we talking about?
Wikipedia says:... test automation is the use of special
software (separate from the software being tested) to control the execution of tests and the comparison of actual outcomes to predicted outcomes. Test automation can automate some repetitive but necessary tasks in a formalized testing process already in place, or add additional testing that would be difficult to perform manually ...
![Page 4: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/4.jpg)
Why should you bother?
● Efficiency
● More complete error reports
● Huge time savings
● A more complete code coverage
![Page 5: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/5.jpg)
Why did we bother?
While taking over an existing project
● Huge and complicated code base
● No existing unit tests
● Complaints by users:○ a lot of bugs in the GUI
○ a lot of recurrent bugs
![Page 6: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/6.jpg)
How did we start?
![Page 7: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/7.jpg)
External testing tool
SeleniumA suite of tools to automate your web browser.
External Interfacecommunication between your browser and the Flash Player.
![Page 8: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/8.jpg)
● Java Test○ Selenium for Java
○ Standalone Selenium server
○ FlexiumLink and FlashSelenium
● Flex Application○ Flexium
https://github.com/StackAndHeap/flexium
The Selenium setup
![Page 9: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/9.jpg)
DEMOAvailable on our github
https://github.com/StackAndHeap/flexium
![Page 10: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/10.jpg)
public Boolean click(String objectId) throws Exception {
delay();
if(isReady()) {
String result = call("doFlexClick", objectId, "");
return checkResult(result);
}
return false;
}
Under the hood - Selenium (1)
![Page 11: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/11.jpg)
public Boolean click(String objectId) throws Exception {
delay(); if(isReady()) {
String result = call("doFlexClick", objectId, "");
return checkResult(result);
}
return false;
}
Under the hood - Selenium (1)
![Page 12: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/12.jpg)
public Boolean click(String objectId) throws Exception {
delay();
if(isReady()) { String result = call("doFlexClick", objectId, "");
return checkResult(result);
}
return false;
}
Under the hood - Selenium (1)
![Page 13: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/13.jpg)
public Boolean click(String objectId) throws Exception {
delay();
if(isReady()) {
String result = call("doFlexClick", objectId, ""); return checkResult(result);
}
return false;
}
Under the hood - Selenium (1)
![Page 14: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/14.jpg)
public Boolean click(String objectId) throws Exception {
delay();
if(isReady()) {
String result = call("doFlexClick", objectId, "");
return checkResult(result); }
return false;
}
Under the hood - Selenium (1)
![Page 15: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/15.jpg)
Under the hood - Selenium (2)
![Page 16: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/16.jpg)
Under the hood - Selenium (3)
![Page 17: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/17.jpg)
● Flexium ○ Compiles into your application
○ Parsing of your applications Stage
○ Registers your (custom) commands
Under the hood - Apache Flex (1)
![Page 18: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/18.jpg)
Compiles into your application
... separate from the software being tested...
1) Use a Mixin
... [Mixin]
public class Flexium extends Sprite {...
Under the hood - Apache Flex (2)
![Page 19: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/19.jpg)
Compiles into your application
... separate from the software being tested...
2) Include library
include-libraries library [...]
Under the hood - Apache Flex (2)
![Page 20: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/20.jpg)
Parsing of your applications stage
Every component that gets added to the stage will be parsed by the
AS3-commons Stage Processing Library
http://as3commons.org/as3-commons-stageprocessing/index.html
Under the hood - Apache Flex (3)
![Page 21: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/21.jpg)
Parsing of your applications stage with AS3Commonsprivate var _registry:FlashStageObjectProcessorRegistry;
private function initProcessor():void {
_registry = new FlashStageObjectProcessorRegistry();
_registry.useStageDestroyers = true;
_registry.registerStageObjectProcessor(
new EventDispatchingObjectProcessor(this),
new EventDispatchingObjectSelector()
);
_registry.initialize();
}
Under the hood - Apache Flex (4)
![Page 22: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/22.jpg)
Parsing of your applications stage with AS3Commonsprivate var _registry:FlashStageObjectProcessorRegistry;
private function initProcessor():void {
_registry = new FlashStageObjectProcessorRegistry();
_registry.useStageDestroyers = true; _registry.registerStageObjectProcessor(
new EventDispatchingObjectProcessor(this),
new EventDispatchingObjectSelector()
);
_registry.initialize();
}
Under the hood - Apache Flex (4)
![Page 23: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/23.jpg)
Parsing of your applications stage with AS3Commonsprivate var _registry:FlashStageObjectProcessorRegistry;
private function initProcessor():void {
_registry = new FlashStageObjectProcessorRegistry();
_registry.useStageDestroyers = true;
_registry.registerStageObjectProcessor(
new EventDispatchingObjectProcessor(this),
new EventDispatchingObjectSelector());
_registry.initialize();
}
Under the hood - Apache Flex (4)
![Page 24: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/24.jpg)
Parsing of your applications stage with AS3Commonsprivate var _registry:FlashStageObjectProcessorRegistry;
private function initProcessor():void {
_registry = new FlashStageObjectProcessorRegistry();
_registry.useStageDestroyers = true;
_registry.registerStageObjectProcessor(
new EventDispatchingObjectProcessor(this), new EventDispatchingObjectSelector()
);
_registry.initialize();
}
Under the hood - Apache Flex (4)
![Page 25: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/25.jpg)
Parsing of your applications stage with AS3Commonspublic class EventDispatchingObjectSelector implements IObjectSelector {
public function approve(object:Object):Boolean {
return object is UIComponent;
}
}
Under the hood - Apache Flex (5)
![Page 26: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/26.jpg)
Parsing of your applications stage with AS3Commonspublic function process(displayObject:DisplayObject):DisplayObject {
_stageParser.addElement((displayObject as UIComponent).id, displayObject);
return displayObject;
}
public function destroy(displayObject:DisplayObject):DisplayObject {
_stageParser.removeElement((displayObject as UIComponent).id);
return displayObject;
}
Under the hood - Apache Flex (6)
![Page 27: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/27.jpg)
Under the hood - Apache Flex (7)Registers your (custom) commandspublic class MouseAction extends AbstractAction implements IAction { public function MouseAction(parser:StageParser) {
super(parser);
}
public function attachActions():void {
attach("click", doFlexClick);
}
public function doFlexClick(id:String, args:String):String {
var child:Object = parser.getElementById(id);
if (child == null) {
return Errors.OBJECT_NOT_FOUND;
}
return String(child.dispatchEvent(new MouseEvent(MouseEvent.CLICK)));
}
}
![Page 28: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/28.jpg)
Under the hood - Apache Flex (7)Registers your (custom) commandspublic class MouseAction extends AbstractAction implements IAction {
public function MouseAction(parser:StageParser) {
super(parser);
}
public function attachActions():void {
attach("click", doFlexClick); }
public function doFlexClick(id:String, args:String):String {
var child:Object = parser.getElementById(id);
if (child == null) {
return Errors.OBJECT_NOT_FOUND;
}
return String(child.dispatchEvent(new MouseEvent(MouseEvent.CLICK)));
}
}
![Page 29: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/29.jpg)
Under the hood - Apache Flex (7)Registers your (custom) commandspublic class MouseAction extends AbstractAction implements IAction {
public function MouseAction(parser:StageParser) {
super(parser);
}
public function attachActions():void {
attach("click", doFlexClick);
}
public function doFlexClick(id:String, args:String):String { var child:Object = parser.getElementById(id);
if (child == null) {
return Errors.OBJECT_NOT_FOUND;
}
return String(child.dispatchEvent(new MouseEvent(MouseEvent.CLICK)));
}
}
![Page 30: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/30.jpg)
Under the hood - Apache Flex (7)Registers your (custom) commandspublic class MouseAction extends AbstractAction implements IAction {
public function MouseAction(parser:StageParser) {
super(parser);
}
public function attachActions():void {
attach("click", doFlexClick);
}
public function doFlexClick(id:String, args:String):String {
var child:Object = parser.getElementById(id); if (child == null) {
return Errors.OBJECT_NOT_FOUND;
}
return String(child.dispatchEvent(new MouseEvent(MouseEvent.CLICK)));
}
}
![Page 31: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/31.jpg)
Under the hood - Apache Flex (7)Registers your (custom) commandspublic class MouseAction extends AbstractAction implements IAction {
public function MouseAction(parser:StageParser) {
super(parser);
}
public function attachActions():void {
attach("click", doFlexClick);
}
public function doFlexClick(id:String, args:String):String {
var child:Object = parser.getElementById(id);
if (child == null) {
return Errors.OBJECT_NOT_FOUND; }
return String(child.dispatchEvent(new MouseEvent(MouseEvent.CLICK)));
}
}
![Page 32: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/32.jpg)
Under the hood - Apache Flex (7)Registers your (custom) commandspublic class MouseAction extends AbstractAction implements IAction {
public function MouseAction(parser:StageParser) {
super(parser);
}
public function attachActions():void {
attach("click", doFlexClick);
}
public function doFlexClick(id:String, args:String):String {
var child:Object = parser.getElementById(id);
if (child == null) {
return Errors.OBJECT_NOT_FOUND;
}
return String(child.dispatchEvent(new MouseEvent(MouseEvent.CLICK))); }
}
![Page 33: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/33.jpg)
FYI● working with data
○ mock data
■ same result on every test
■ same result on every system
![Page 34: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/34.jpg)
What's next?● My way, not the highway...
● Custom components - custom commands
![Page 35: Automated User Tests with Apache Flex](https://reader033.vdocument.in/reader033/viewer/2022052823/5553a8f2b4c905d9448b4772/html5/thumbnails/35.jpg)
https://github.com/StackAndHeap/flexium/