This example shows how to create an asynchronous test with the YUI Test framework for testing browser-based JavaScript code. A YUITest.TestCase
object is created with a test that waits for a
few seconds before continuing. The YUITest.TestRunner
is then used to run the tests once the page has loaded.
The first step is to create a new YUITest.TestCase
object called AsyncTestCase
.
To do so, using the YUITest.TestCase
constructor and pass in an object literal containing information about the tests to be run:
var asyncTestCase = new YUITest.TestCase({
//name of the test case - if not provided, one is auto-generated
name : "Asynchronous Tests",
//---------------------------------------------------------------------
// setUp and tearDown methods - optional
//---------------------------------------------------------------------
/*
* Sets up data that is needed by each test.
*/
setUp : function () {
this.data = {
name: "test",
year: 2007,
beta: true
};
},
/*
* Cleans up everything that was created by setUp().
*/
tearDown : function () {
delete this.data;
},
//---------------------------------------------------------------------
// Test methods - names must begin with "test"
//---------------------------------------------------------------------
testWait : function (){
var Assert = YUITest.Assert;
//do some assertions now
Assert.isTrue(this.data.beta);
Assert.isNumber(this.data.year);
//wait five seconds and do some more
this.wait(function(){
Assert.isString(this.data.name);
}, 5000);
}
});
The object literal passed into the constructor contains two different sections. The first section contains the name
property,
which is used to determine which YUITest.TestCase
is being executed. A name is necessary, so one is generated if it isn't specified.
Next, the setUp()
and tearDown()
methods are included. The setUp()
method is used in a YUITest.TestCase
to set up data that may be needed for tests to be completed. This method is called immediately before each test is executed. For this example,
setUp()
creates a data object. The tearDown()
is responsible for undoing what was done in setUp()
. It is
run immediately after each test is run and, in this case, deletes the data object that was created by setUp
. These methods are optional.
The second section contains the actual tests to be run. The only test is testWait()
, which demonstrates using
the wait()
method to delay test execution. There are two arguments passed in: a function to run once the test resumes
and the number of milliseconds to wait before running this function (same basic format as setTimeout()
). When
the test resumes, the function is executed in the context of the YUITest.TestCase
object, meaning that it still has
access to all of the same data as the test that called wait()
, including properties and methods on the YUITest.TestCase
itself. This example shows the anonymous function using both the YUITest.Assert
object and the data
property
of the YUITest.TestCase
.
Since the standalone YUI Test library isn't a graphical library, you'll need to use something to visualize the results. This example uses a YUI 3 Console
object. To output the appropriate information into the console, a function is created to handle TestRunner
events:
//function to handle events generated by the testrunner
var TestRunner = YUITest.TestRunner;
function logEvent(event){
//data variables
var message = "",
messageType = "";
switch(event.type){
case TestRunner.BEGIN_EVENT:
message = "Testing began at " + (new Date()).toString() + ".";
messageType = "info";
break;
case TestRunner.COMPLETE_EVENT:
message = Y.substitute("Testing completed at " +
(new Date()).toString() + ".\n" +
"Passed:{passed} Failed:{failed} " +
"Total:{total} ({ignored} ignored)",
event.results);
messageType = "info";
break;
case TestRunner.TEST_FAIL_EVENT:
message = event.testName + ": failed.\n" + event.error.getMessage();
messageType = "fail";
break;
case TestRunner.TEST_IGNORE_EVENT:
message = event.testName + ": ignored.";
messageType = "ignore";
break;
case TestRunner.TEST_PASS_EVENT:
message = event.testName + ": passed.";
messageType = "pass";
break;
case TestRunner.TEST_SUITE_BEGIN_EVENT:
message = "Test suite \"" + event.testSuite.name + "\" started.";
messageType = "info";
break;
case TestRunner.TEST_SUITE_COMPLETE_EVENT:
message = Y.substitute("Test suite \"" +
event.testSuite.name + "\" completed" + ".\n" +
"Passed:{passed} Failed:{failed} " +
"Total:{total} ({ignored} ignored)",
event.results);
messageType = "info";
break;
case TestRunner.TEST_CASE_BEGIN_EVENT:
message = "Test case \"" + event.testCase.name + "\" started.";
messageType = "info";
break;
case TestRunner.TEST_CASE_COMPLETE_EVENT:
message = Y.substitute("Test case \"" +
event.testCase.name + "\" completed.\n" +
"Passed:{passed} Failed:{failed} " +
"Total:{total} ({ignored} ignored)",
event.results);
messageType = "info";
break;
default:
message = "Unexpected event " + event.type;
message = "info";
}
//only log if required
Y.log(message, messageType, "TestRunner");
}
//listen for events to publish to the logger
TestRunner.attach(TestRunner.BEGIN_EVENT, logEvent);
TestRunner.attach(TestRunner.COMPLETE_EVENT, logEvent);
TestRunner.attach(TestRunner.TEST_CASE_BEGIN_EVENT, logEvent);
TestRunner.attach(TestRunner.TEST_CASE_COMPLETE_EVENT, logEvent);
TestRunner.attach(TestRunner.TEST_SUITE_BEGIN_EVENT, logEvent);
TestRunner.attach(TestRunner.TEST_SUITE_COMPLETE_EVENT, logEvent);
TestRunner.attach(TestRunner.TEST_PASS_EVENT, logEvent);
TestRunner.attach(TestRunner.TEST_FAIL_EVENT, logEvent);
TestRunner.attach(TestRunner.TEST_IGNORE_EVENT, logEvent);
The logEvent()
function is used to handle all events. Based on the event, the message and the message type are determined and then a message is logged. This event handler is assigned to the TestRunner
events by using the attach()
method.
With all of the tests defined, the last step is to run them. This initialization is assigned to take place when all of the YUI components have been loaded:
//create the console
var r = new Y.Console({
verbose : true,
newestOnTop : false
});
r.render('#testLogger');
TestRunner.add(asyncTestCase);
//run the tests
TestRunner.run();
Before running the tests, it's necessary to create a Y.Console
object to display the results (otherwise the tests would run
but you wouldn't see the results). After that, the YUITest.TestRunner
is loaded with the YUITest.TestCase
object by calling
add()
(any number of YUITest.TestCase
and YUITest.TestSuite
objects can be added to a YUITest.TestRunner
,
this example only adds one for simplicity). The very last step is to call run()
, which begins executing the tests in its
queue and displays the results in the Y.Console
.