XForms - Client-Side Unit Tests


Rationale

Some of the sandbox examples are extended to use YUI Test to test themselves automatically as they are loaded in the sandbox. To run the tests, you can either load in your browser:
  • A specific test page – This will run just the tests on that page.
  • The unit-tests sandbox example – This will run all the tests, and report the outcome in a table.

Running the unit tests

To run a specific text page, just load it as you would load any sandbox example. The test will start right away, and the YUI logger window will show you how many test cases ran, and out of those how many passed or failed. For instance, the following screenshot shows a case where 1 test case ran successfully.


To run all the example, load the unit-tests sandbox example. The unit-tests example will typically be available on:


It will report on the outcome of all the test pages in a table that looks as follows.



Creating a unit test

Overview

  1. Write the test as you would normally do, and test it manually.
  2. Add the following, after </xforms:model>:
<xhtml:link type="text/css" rel="stylesheet" href="/ops/yui/logger/assets/logger.css"/>
<xhtml:script type="text/javascript" src="/ops/yui/logger/logger.js"/>
<xhtml:script type="text/javascript" src="/ops/yui/yuitest/yuitest.js"/>
<xhtml:script type="text/javascript">
    <![CDATA[
        YAHOO.tool.TestRunner.add(new YAHOO.tool.TestCase({

            name: "Description of this test case",

            testSomething: function() {
                ORBEON.util.Test.executeCausingAjaxRequest(this, function() {
                    var trigger = document.getElementById("trigger");
                    YAHOO.util.UserAction.click(trigger);
                }, function() {
                    YAHOO.util.Assert.isTrue(...);
                });
            }
        }));
        ORBEON.xforms.Events.orbeonLoadedEvent.subscribe(function() {
            if (parent && parent.TestManager) {
                parent.TestManager.load();
            } else {
                new YAHOO.tool.TestLogger();
                YAHOO.tool.TestRunner.run();
            }
        });
    ]]>
</xhtml:script>

The code above is just an example:
  • You'll want to change the "Something" in the name of the function testSomething to reflect what your test case does.
  • You can have multiple test cases defined in the same way (multiple functions testThis, testThat).
  • The YUI Test functions you'll use the most are:
    • Within YAHOO.util.UserAction to simulate user actions
    • Within YAHOO.util.Assert for assertions
    • , including isTrue() or areEqual()
  • Use the YUI setUp() and tearDown() methods if you need actions done pre/post tests.
  • If you are testing code which does not expect an Ajax response back, you won't need ORBEON.util.Test.executeCausingAjaxRequest().


Frequent tasks

TaskCode
Get the value of a control
ORBEON.xforms.Document.getValue("my-id");
Set the value of a control
ORBEON.xforms.Document.setValue("my-id", "new-value");
Getting the ID for a control in a repeat
"my-id" + XFORMS_SEPARATOR_1 + "42"
Run operation causing Ajax request
ORBEON.util.Test.executeCausingAjaxRequest(this, function() {
    // What causes the Ajax request
}, function() {
    // What should after the Ajax response has been received
});
Assert comparing to expected value
YAHOO.util.Assert.areEqual("expected-value", expression);


Services returning a large hierarchy

The following 3 services return a hierarchy of states, cities, and zip codes. They can be used by test cases, for instance to populate <xforms:select> or <xforms:select1>.
  • /xforms-sandbox/service/zip-states returns:
<states>
    <state abbreviation="AK" name="Alaska"/>
    <state abbreviation="AL" name="Alabama"/>
    <state abbreviation="AR" name="Arkansas"/>
    ...
</states>

  • /xforms-sandbox/service/zip-cities?state-abbreviation=CA returns:
<cities>
    <city name="Acampo"/>
    <city name="Acton"/>
    <city name="Adelaide"/>
    ...
</cities>

  • /xforms-sandbox/service/zip-zips?state-abbreviation=CA&city=San+Francisco returns:
<zips>
    <zip code="94102" latitute=" 37.779329" longitude="-122.41915"/>
    <zip code="94103" latitute=" 37.772329" longitude="-122.41087"/>
    <zip code="94104" latitute=" 37.791728" longitude="-122.40190"/>
    ...
</zips>


Comments