qooxdoo

the new era of web development

 

Simulator (Experimental)

Overview

The purpose of the Simulator component is to help developers rapidly develop and run a suite of simulated user interaction tests for their application with a minimum amount of configuration and using familiar technologies, e.g. qooxdoo-style JavaScript. To do so it uses a combination of qooxdoo's own toolchain, Mozilla's Rhino JavaScript engine and Selenium RC.

Note

The Simulator is a highly experimental feature; the API is by no means finalized. It is included in this qooxdoo release as a preview. Also, the Simulator is not intended as a replacement for any existing automated test setup, e.g. using Selenium with JUnit. It is merely one of many ways to run Selenium tests on a qooxdoo application.

Feature Highlights

The Simulator enables developers to:

  • Define Selenium test cases by writing qooxdoo classes
  • Use the JUnit-style setUp, test*, tearDown pattern
  • Define test jobs using the qooxdoo toolchain's configuration system
  • Utilize the standard Selenium API and the qooxdoo user extensions to locate and interact with qooxdoo widgets
  • Capture and log uncaught exceptions thrown in the tested application
  • Use Selenium RC to run tests in many different browser/platform combinations
  • Write custom logger classes using qooxdoo's flexible logging system

How it works

Similar to unit tests, Simulator test cases are defined as qooxdoo classes living in the application's source directory. As such they support qooxdoo's OO features such as inheritance and nested namespaces. The setUp, testSomething, tearDown pattern is supported, as well as all assertion functions defined by qx.core.MAssert.

The main API that is used to define the test logic is QxSelenium, which means the DefaultSelenium API plus the Locator strategies and commands from the qooxdoo user extensions for Selenium.

As with qooxdoo's unit testing framework, the Generator is used to create a test runner application (the Simulator). User-defined test classes are included into this application, which extends qx.application.Native and uses a simplified loader so it can run in Rhino.

A separate Generator job is used to start Rhino and instruct it to load the Simulator application, which uses Selenium's Java API to send test commands to a Selenium RC server (over HTTP, so the server can run on a separate machine). The Server then launches the selected browser, loads the qooxdoo application to be tested and executes the commands specified in the test case.

Setting up the test environment

The following sections describe the steps necessary to set up Simulator tests for an application based on qooxdoo's GUI or inline skeleton.

Required Libraries

The Simulator needs the following external resources to run:

The Selenium Client Driver (selenium-java-client-driver.jar) and Rhino (js.jar) archives must be located on the same machine as the application to be tested.

The Selenium Server (selenium-server.jar) can optionally run on a physically separate host (see the Selenium RC documentation for details). The qooxdoo user extensions must be located on the same machine as the server.

Note

The qooxdoo User Extensions for Selenium will be moved into the Simulator component for a future release so that it will no longer be necessary to download the file or check out the contribution repository.

Generator Configuration

Unlike other framework components, the Simulator isn't ready to run out of the box: The application developer needs to specify the location of the required external libraries (Selenium's Java Client Driver and Mozilla Rhino). This is easily accomplished by redefining the SIMULATOR_CLASSPATH macro (in the applicaton's config.json file):

"let" :
{
  "SIMULATOR_CLASSPATH" : ["../selenium/selenium-java-client-driver.jar", "../rhino/js.jar"]
}

Additional options are available, although their default settings should be fine for most cases. See the simulate job key reference for details.

The "settings" section of the "simulation-build" job configures where the AUT is located and how to reach the Selenium RC server that will launch the test browser and run the test commands. The following example shows the minimum configuration needed to build a Simulator application that will test the source version of the current library in Firefox 3 using a Selenium RC server instance running on the same machine (localhost):

"simulation-build" :
{
  "settings" :
  {
    "simulator.testBrowser" : "*firefox3",
    "simulator.selServer" : "localhost",
    "simulator.selPort" : 4444,
    "simulator.autHost" : "http://localhost",
    "simulator.autPath" : "/${APPLICATION}/source/index.html"
  }
}

See the job reference for a listing of all supported settings and their default values.

Note

Since these settings are integrated into the Simulator application by qooxdoo's compile process, the simulation-build job must be run again whenever configuration settings were modified. Future versions of the Simulator will get rid of this limitation by using a more flexible configuration approach.

Writing Test Cases

The following articles describe the QxSelenium API in greater detail than can be covered here:

Also, qooxdoo's Inspector component can provide assistance to test developers.

Generating the Simulator

The "simulation-build" job explained above is used to generate the Simulator application (in the AUT's root directory):

Note

generate.py simulation-build

Starting the Selenium RC server

The Selenium RC server must be started with the -userExtensions command line option pointing to the qooxdoo user extenions for Selenium mentioned above:

java -jar selenium-server.jar -userExtensions ../some/path/user-extensions.js

Note that the user extension file must be named user-extensions.js.

Running the Tests

Once the Simulator application is configured and compiled and the Selenium RC server is running, the test suite can be executed using the "simulation-run" job:

generate.py simulation-run

The Simulator's default logger writes the result of each test to the shell as it's executed. The full output looks something like this:

============================================================================
    EXECUTING: SIMULATION-RUN
============================================================================
>>> Initializing cache...
>>> Running Simulation...
>>> Load runtime: 360ms
>>> Simulator run on Thu, 02 Dec 2010 15:57:30 GMT
>>> Application under test: http://localhost/~dwagner/workspace/myApplication/source/index.html
>>> Platform: Linux
>>> User agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12
>>> PASS  myapplication.simulation.DemoSimulation:testButtonPresent
>>> PASS  myapplication.simulation.DemoSimulation:testButtonClick
>>> Main runtime: 11476ms
>>> Finalize runtime: 0ms
>>> Done