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.
The Simulator enables developers to:
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.
The following sections describe the steps necessary to set up Simulator tests for an application based on qooxdoo's GUI or inline skeleton.
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 (see below).
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"]
}
The "settings" section of the "simulation-run" 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-run" :
{
"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. Additional runtime options are available, although their default settings should be fine for most cases. See the simulate job key reference for details.
As mentioned above, Simulator test cases are qooxdoo classes living (at least by default) in the application's simulation name space. They inherit from simulator.unit.TestCase, which includes the assertion functions from qx.core.MAssert. Simulator tests look very similar to qooxdoo unit tests as they follow the same pattern of setUp, testSomething, tearDown. Typically, each test* method will use the QxSelenium API to interact with some part of the AUT, then use assertions to check if the AUT's state has changed as expected, e.g. by querying the value of a qooxdoo property.
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.
The "simulation-build" job explained above is used to generate the Simulator application (in the AUT's root directory):
generate.py simulation-build
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 <QOOXDOO-TRUNK>/component/simulator/tool/user-extensions/user-extensions.js
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