YUI recommends YUI3.
YUI 2 has been deprecated since 2011. This site acts as an archive for files and documentation.
This documentation is no longer maintained.
YUI Test is a testing framework for browser-based JavaScript solutions. Using YUI Test, you can easily add unit testing to your JavaScript solutions. While not a direct port from any specific xUnit framework, YUI Test does derive some characteristics from nUnit and JUnit.
YUI Test features:
In this 48-minute tech talk from October 2008, Yahoo! engineer Nicholas C. Zakas introduces you to the world of test-driven development and how it can be applied to JavaScript projects using YUI Test. [iPod/iPhone compatible download also available.]
To use YUI Test, include the following source files in your web page:
<!--CSS--> <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.9.0/build/logger/assets/logger.css"> <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.9.0/build/yuitest/assets/testlogger.css"> <!-- Dependencies --> <script src="http://yui.yahooapis.com/2.9.0/build/yahoo-dom-event/yahoo-dom-event.js"></script> <script src="http://yui.yahooapis.com/2.9.0/build/logger/logger-min.js"></script> <!-- Source File --> <script src="http://yui.yahooapis.com/2.9.0/build/yuitest/yuitest-min.js"></script>
<!--CSS--> <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.9.0/build/logger/assets/logger.css"> <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.9.0/build/yuitest/assets/testlogger.css"> <!-- Dependencies --> <script src="http://yui.yahooapis.com/2.9.0/build/yahoo-dom-event/yahoo-dom-event.js"></script> <script src="http://yui.yahooapis.com/2.9.0/build/logger/logger-min.js"></script> <!-- Source File --> <script src="http://yui.yahooapis.com/2.9.0/build/yuitest/yuitest-min.js"></script>
Instead of copying and pasting the filepaths above, try letting the YUI dependency Configurator determine the optimal file list for your desired components; the Configurator uses YUI Loader to write out the full HTML for including the precise files you need for your implementation.
Note: If you wish to include this component via the YUI Loader, its module name is yuitest
. (Click here for the full list of module names for YUI Loader.)
Where these files come from: The files included using the text above will be served from Yahoo! servers. JavaScript files are minified, meaning that comments and white space have been removed to make them more efficient to download. To use the full, commented versions or the -debug
versions of YUI JavaScript files, please download the library distribution and host the files on your own server.
Order matters: As is the case generally with JavaScript and CSS, order matters; these files should be included in the order specified above. If you include files in the wrong order, errors may result.
The basis of YUI Test is the YAHOO.tool.TestCase
object. A TestCase
object is created by using the
YAHOO.tool.TestCase
constructor and passing in an object containing methods and other information with which
to initialize the test case. Typically, the argument is an object literal, for example:
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testSomething : function () { //... }, testSomethingElse : function () { //... } });
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testSomething : function () { //... }, testSomethingElse : function () { //... } });
In this example, a simple test case is created named "TestCase Name". The name
property is automatically
applied to the test case so that it can be distinguished from other test cases that may be run during the same cycle. The two
methods in this example are tests methods ( testSomething()
and testSomethingElse())
, which means
that they are methods designed to test a specific piece of functional code. Each test method name must begin with test
in order to be recognized and
run as a test and each should have one or more assertions that test data for validity.
As each test method is called, it may be necessary to setup information before it's run and then potentially clean up that information
after the test is run. The setUp()
method is run before each and every test in the test case and likewise the tearDown()
method is run
after each test is run. These methods should be used in conjunction to create objects before a test is run and free up memory after the
test is run. For example:
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Setup and tear down //--------------------------------------------- setUp : function () { this.data = { name : "Nicholas", age : 28 }; }, tearDown : function () { delete this.data; }, //--------------------------------------------- // Tests //--------------------------------------------- testName: function () { YAHOO.util.Assert.areEqual("Nicholas", this.data.name, "Name should be 'Nicholas'"); }, testAge: function () { YAHOO.util.Assert.areEqual(28, this.data.age, "Age should be 28"); } });
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Setup and tear down //--------------------------------------------- setUp : function () { this.data = { name : "Nicholas", age : 28 }; }, tearDown : function () { delete this.data; }, //--------------------------------------------- // Tests //--------------------------------------------- testName: function () { YAHOO.util.Assert.areEqual("Nicholas", this.data.name, "Name should be 'Nicholas'"); }, testAge: function () { YAHOO.util.Assert.areEqual(28, this.data.age, "Age should be 28"); } });
In this example, a setUp()
method creates a data object with some basic information. Each property of the data object is checked with
a different test, testName()
tests the value of data.name
while testAge()
tests the value of data.age
. Afterwards, the data object is deleted
to free up the memory. Real-world implementations will have more complex tests, of course, but they should follow the basic pattern you see in the above code.
Note: Both setUp()
and tearDown()
are optional methods and are only used when defined.
There may be times when you want to ignore a test (perhaps the test is invalid for your purposes or the functionality is being re-engineered and so it shouldn't be tested at this time). To specify tests to ignore,
use the _should.ignore
property and name each test to skip as a property whose value is set to true
:
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Special instructions //--------------------------------------------- _should: { ignore: { testName: true //ignore this test } }, //--------------------------------------------- // Setup and tear down //--------------------------------------------- setUp : function () { this.data = { name : "Nicholas", age : 28 }; }, tearDown : function () { delete this.data; }, //--------------------------------------------- // Tests //--------------------------------------------- testName: function () { YAHOO.util.Assert.areEqual("Nicholas", this.data.name, "Name should be 'Nicholas'"); }, testAge: function () { YAHOO.util.Assert.areEqual(28, this.data.age, "Age should be 28"); } });
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Special instructions //--------------------------------------------- _should: { ignore: { testName: true //ignore this test } }, //--------------------------------------------- // Setup and tear down //--------------------------------------------- setUp : function () { this.data = { name : "Nicholas", age : 28 }; }, tearDown : function () { delete this.data; }, //--------------------------------------------- // Tests //--------------------------------------------- testName: function () { YAHOO.util.Assert.areEqual("Nicholas", this.data.name, "Name should be 'Nicholas'"); }, testAge: function () { YAHOO.util.Assert.areEqual(28, this.data.age, "Age should be 28"); } });
Here, the testName()
method will be ignored when the test case is run. This is accomplished by first defining the special _should
property and within it, an ignore
property. The ignore property is an object containing name-value pairs representing the names of the tests
to ignore. By defining a property named "testName" and setting its value to true
, it says that the method named "testName"
should not be executed.
There may be a time that a test throws an error that was expected. For instance, perhaps you're testing a function that should throw an error if invalid data
is passed in. A thrown error in this case can signify that the test has passed. To indicate that
a test should throw an error, use the _should.error
property. For example:
function sortArray(array) { if (array instanceof Array){ array.sort(); } else { throw new TypeError("Expected an array"); } } var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Special instructions //--------------------------------------------- _should: { error: { testSortArray: true //this test should throw an error } }, //--------------------------------------------- // Tests //--------------------------------------------- testSortArray: function () { sortArray(12); //this should throw an error } });
function sortArray(array) { if (array instanceof Array){ array.sort(); } else { throw new TypeError("Expected an array"); } } var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Special instructions //--------------------------------------------- _should: { error: { testSortArray: true //this test should throw an error } }, //--------------------------------------------- // Tests //--------------------------------------------- testSortArray: function () { sortArray(12); //this should throw an error } });
In this example, a test case is created to test the standalone sortArray()
function, which simply accepts an array and calls its sort()
method.
But if the argument is not an array, an error is thrown. When testSortArray()
is called, it throws an error because a number is passed into sortArray()
.
Since the _should.error
object has a property called "testSortArray" set to true
, this indicates that testSortArray()
should
pass only if an error is thrown.
It is possible to be more specific about the error that should be thrown. By setting a property in _should.error
to a string, you can
specify that only a specific error message can be construed as a passed test. Here's an example:
function sortArray(array) { if (array instanceof Array){ array.sort(); } else { throw new TypeError("Expected an array"); } } var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Special instructions //--------------------------------------------- _should: { error: { testSortArray: "Expected an array" } }, //--------------------------------------------- // Tests //--------------------------------------------- testSortArray: function () { sortArray(12); //this should throw an error } });
function sortArray(array) { if (array instanceof Array){ array.sort(); } else { throw new TypeError("Expected an array"); } } var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Special instructions //--------------------------------------------- _should: { error: { testSortArray: "Expected an array" } }, //--------------------------------------------- // Tests //--------------------------------------------- testSortArray: function () { sortArray(12); //this should throw an error } });
In this example, the testSortArray()
test will only pass if the error that is thrown has a message of "Expected an array".
If a different error occurs within the course of executing testSortArray()
, then the test will fail due to an unexpected error.
If you're unsure of the message but know the type of error that will be thrown, you can specify the error constructor for the error you're expecting to occur:
function sortArray(array) { if (array instanceof Array){ array.sort(); } else { throw new TypeError("Expected an array"); } } var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Special instructions //--------------------------------------------- _should: { error: { testSortArray: TypeError } }, //--------------------------------------------- // Tests //--------------------------------------------- testSortArray: function () { sortArray(12); //this should throw an error } });
function sortArray(array) { if (array instanceof Array){ array.sort(); } else { throw new TypeError("Expected an array"); } } var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Special instructions //--------------------------------------------- _should: { error: { testSortArray: TypeError } }, //--------------------------------------------- // Tests //--------------------------------------------- testSortArray: function () { sortArray(12); //this should throw an error } });
In this example, the test will pass if a TypeError
gets thrown; if any other type of error is thrown,
the test will fail. A word of caution: TypeError
is the most frequently thrown error by browsers,
so specifying a TypeError
as expected may give false passes.
To narrow the margin of error between checking for an error message and checking the error type, you can create a specific error
object and set that in the _should.error
property, such as:
function sortArray(array) { if (array instanceof Array){ array.sort(); } else { throw new TypeError("Expected an array"); } } var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Special instructions //--------------------------------------------- _should: { error: { testSortArray: new TypeError("Expected an array") } }, //--------------------------------------------- // Tests //--------------------------------------------- testSortArray: function () { sortArray(12); //this should throw an error } });
function sortArray(array) { if (array instanceof Array){ array.sort(); } else { throw new TypeError("Expected an array"); } } var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Special instructions //--------------------------------------------- _should: { error: { testSortArray: new TypeError("Expected an array") } }, //--------------------------------------------- // Tests //--------------------------------------------- testSortArray: function () { sortArray(12); //this should throw an error } });
Using this code, the testSortArray()
method will only pass if a TypeError
object is thrown with a message of
"Expected an array"; if any other type of error occurs, then the test fails due to an unexpected error.
Note: If a test is marked as expecting an error, the test will fail unless that specific error is thrown. If the test completes without an error being thrown, then it fails.
Test methods use assertions to check the validity of a particular action or function. An assertion method tests (asserts) that a
condition is valid; if not, it throws an error that causes the test to fail. If all assertions pass within a test method,
it is said that the test has passed. To aid in writing tests, the YAHOO.util.Assert
object contains several assertion
methods that can be used to validate data.
Topics covered in this section include:
The simplest assertions are areEqual()
and areNotEqual()
. Both methods accept three arguments: the expected value,
the actual value, and an optional failure message (a default one is generated if this argument is omitted). For example:
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testEqualityAsserts : function () { var Assert = YAHOO.util.Assert; Assert.areEqual(5, 5); //passes Assert.areEqual(5, "5"); //passes Assert.areNotEqual(5, 6); //passes Assert.areEqual(5, 6, "Five was expected."); //fails } });
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testEqualityAsserts : function () { var Assert = YAHOO.util.Assert; Assert.areEqual(5, 5); //passes Assert.areEqual(5, "5"); //passes Assert.areNotEqual(5, 6); //passes Assert.areEqual(5, 6, "Five was expected."); //fails } });
These methods use the double equals (==
) operator to determine if two values are equal, so type coercion may occur. This means
that the string "5"
and the number 5
are considered equal because the double equals sign converts the number to
a string before doing the comparison. If you don't want values to be converted for comparison purposes, use the sameness assertions instead.
The sameness assertions are areSame()
and areNotSame()
, and these accept the same three arguments as the equality
assertions: the expected value, the actual value, and an optional failure message. Unlike the equality assertions, these methods use
the triple equals operator (===
) for comparisions, assuring that no type coercion will occur. For example:
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testSamenessAsserts : function () { var Assert = YAHOO.util.Assert; Assert.areSame(5, 5); //passes Assert.areSame(5, "5"); //fails Assert.areNotSame(5, 6); //passes Assert.areNotSame(5, "5"); //passes Assert.areSame(5, 6, "Five was expected."); //fails } });
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testSamenessAsserts : function () { var Assert = YAHOO.util.Assert; Assert.areSame(5, 5); //passes Assert.areSame(5, "5"); //fails Assert.areNotSame(5, 6); //passes Assert.areNotSame(5, "5"); //passes Assert.areSame(5, 6, "Five was expected."); //fails } });
Note: Even though this example shows multiple assertions failing, a test will stop as soon as one assertion fails, causing all others to be skipped.
There may be times when some data should be of a particular type. To aid in this case, there are several methods that test the data type of variables. Each of these methods accepts two arguments: the data to test and an optional failure message. The data type assertions are as follows:
isArray()
- passes only if the value is an instance of Array
.isBoolean()
- passes only if the value is a Boolean.isFunction()
- passes only if the value is a function.isNumber()
- passes only if the value is a number.isObject()
- passes only if the value is an object or a function.isString()
- passes only if the value is a string.These are used as in the following example:
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testDataTypeAsserts : function () { var Assert = YAHOO.util.Assert; Assert.isString("Hello world"); //passes Assert.isNumber(1); //passes Assert.isArray([]); //passes Assert.isObject([]); //passes Assert.isFunction(function(){}); //passes Assert.isBoolean(true); //passes Assert.isObject(function(){}); //passes Assert.isNumber("1", "Value should be a number."); //fails Assert.isString(1, "Value should be a string."); //fails } });
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testDataTypeAsserts : function () { var Assert = YAHOO.util.Assert; Assert.isString("Hello world"); //passes Assert.isNumber(1); //passes Assert.isArray([]); //passes Assert.isObject([]); //passes Assert.isFunction(function(){}); //passes Assert.isBoolean(true); //passes Assert.isObject(function(){}); //passes Assert.isNumber("1", "Value should be a number."); //fails Assert.isString(1, "Value should be a string."); //fails } });
In addition to these specific data type assertions, there are two generic data type assertions.
The isTypeOf()
method tests the string returned when the typeof
operator is applied to a value. This
method accepts three arguments: the type that the value should be ("string", "number",
"boolean", "undefined", "object", or "function"), the value to test, and an optional failure message.
For example:
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testTypeOf : function () { var Assert = YAHOO.util.Assert; Assert.isTypeOf("string", "Hello world"); //passes Assert.isTypeOf("number", 1); //passes Assert.isTypeOf("boolean", true); //passes Assert.isTypeOf("number", 1.5); //passes Assert.isTypeOf("function", function(){}); //passes Assert.isTypeOf("object", {}); //passes Assert.isTypeOf("undefined", this.blah); //passes Assert.isTypeOf("number", "Hello world", "Value should be a number."); //fails } });
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testTypeOf : function () { var Assert = YAHOO.util.Assert; Assert.isTypeOf("string", "Hello world"); //passes Assert.isTypeOf("number", 1); //passes Assert.isTypeOf("boolean", true); //passes Assert.isTypeOf("number", 1.5); //passes Assert.isTypeOf("function", function(){}); //passes Assert.isTypeOf("object", {}); //passes Assert.isTypeOf("undefined", this.blah); //passes Assert.isTypeOf("number", "Hello world", "Value should be a number."); //fails } });
If you need to test object types instead of simple data types, you can also use the isInstanceOf()
assertion, which accepts three
arguments: the constructor function to test for, the value to test, and an optional failure message. This assertion uses the instanceof
operator to determine if it should pass or fail. Example:
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testInstanceOf : function () { var Assert = YAHOO.util.Assert; Assert.isInstanceOf(Object, {}); //passes Assert.isInstanceOf(Array, []); //passes Assert.isInstanceOf(Object, []); //passes Assert.isInstanceOf(Function, function(){}); //passes Assert.isInstanceOf(Object, function(){}); //passes Assert.isTypeOf(Array, {}, "Value should be an array."); //fails } });
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testInstanceOf : function () { var Assert = YAHOO.util.Assert; Assert.isInstanceOf(Object, {}); //passes Assert.isInstanceOf(Array, []); //passes Assert.isInstanceOf(Object, []); //passes Assert.isInstanceOf(Function, function(){}); //passes Assert.isInstanceOf(Object, function(){}); //passes Assert.isTypeOf(Array, {}, "Value should be an array."); //fails } });
There are numerous special values in JavaScript that may occur in code. These include true
, false
, NaN
,
null
, and undefined
. There are a number of assertions designed to test for these values specifically:
isFalse()
- passes if the value is false
.isTrue()
- passes if the value is true
.isNaN()
- passes if the value is NaN
.isNotNaN()
- passes if the value is not NaN
.isNull()
- passes if the value is null
.isNotNull()
- passes if the value is not null
.isUndefined()
- passes if the value is undefined
.isNotUndefined()
- passes if the value is not undefined
.Each of these methods accepts two arguments: the value to test and an optional failure message. All of the assertions expect the
exact value (no type cohersion occurs), so for example calling isFalse(0)
will fail.
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testSpecialValues : function () { var Assert = YAHOO.util.Assert; Assert.isFalse(false); //passes Assert.isTrue(true); //passes Assert.isNaN(NaN); //passes Assert.isNaN(5 / "5"); //passes Assert.isNotNaN(5); //passes Assert.isNull(null); //passes Assert.isNotNull(undefined); //passes Assert.isUndefined(undefined); //passes Assert.isNotUndefined(null); //passes Assert.isUndefined({}, "Value should be undefined."); //fails } });
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testSpecialValues : function () { var Assert = YAHOO.util.Assert; Assert.isFalse(false); //passes Assert.isTrue(true); //passes Assert.isNaN(NaN); //passes Assert.isNaN(5 / "5"); //passes Assert.isNotNaN(5); //passes Assert.isNull(null); //passes Assert.isNotNull(undefined); //passes Assert.isUndefined(undefined); //passes Assert.isNotUndefined(null); //passes Assert.isUndefined({}, "Value should be undefined."); //fails } });
While most tests fail as a result of an assertion, there may be times when
you want to force a test to fail or create your own assertion method. To do this, use the
fail()
method to force a test method to fail immediately:
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testForceFail : function () { YAHOO.util.Assert.fail(); //causes the test to fail } });
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testForceFail : function () { YAHOO.util.Assert.fail(); //causes the test to fail } });
In this case, the testForceFail()
method does nothing but force
the method to fail. Optionally, you can pass in a message to fail()
which will be displayed as the failure message:
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testForceFail : function () { YAHOO.util.Assert.fail("I decided this should fail."); } });
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", testForceFail : function () { YAHOO.util.Assert.fail("I decided this should fail."); } });
When the failure of this method is reported, the message "I decided this should fail." will be reported.
Simply testing function calls may not be adequate enough due to the level of interactivity provided by web applications. Since many operations require a
user to initiate them, the YAHOO.util.UserAction
object provides methods to simulate basic user events involving the keyboard
and mouse.
Simulated events are browser-created events that, most of the time, behave exactly as user-initated events. Events bubble as they normally would
and event
objects are created with properties containing data about the event (sometimes these properties are browser-specific, so it's
recommended that you make use of the browser-equalizing methods of YAHOO.util.Event
to retrieve the appropriate values for
properties such as target
, relatedTarget
, and charCode
. All event handlers are called synchronously
at each event target throughout the event's lifetime.
There are seven mouse events that can be simulated using methods on UserAction
:
Each event is fired by a corresponding method on UserAction
that accepts two arguments: the target of the event and
an optional object specifying additional information for the event. To simulate a click on the document's body element,
for example, the following code can be used:
YAHOO.util.UserAction.click(document.body);
YAHOO.util.UserAction.click(document.body);
This code simulates a click with all of the default properties on the event
object. To specify additional information,
such as the Shift key being down, the second argument must be used and the exact DOM name for the event property specified (there is
browser-normalizing logic that translates these into browser-specific properties when necessary):
YAHOO.util.UserAction.click(document.body, { shiftKey: true });
YAHOO.util.UserAction.click(document.body, { shiftKey: true });
In this updated example, a click event is fired on the document's body while simulating that the Shift key is down.
The extra properties to specify vary depending on the event being simulated and are limited to this list:
YAHOO.util.Event.getRelatedTarget()
to retrieve this value from the generated event
object
as it will be translated into browser-specific property names as necessary.Examples of the different methods and their extra properties:
var element = document.getElementById("myDiv"); //simulate a click Alt key down YAHOO.util.UserAction.click(element, { altKey: true}); //simulate a double click with Ctrl key down YAHOO.util.UserAction.dblclick(element, { ctrlKey: true }); //simulate a mouse over YAHOO.util.UserAction.mouseover(element, { relatedTarget: document.body }); //simulate a mouse out YAHOO.util.UserAction.mouseout(element, { relatedTarget: document.body }); //simulate a mouse down at point (100,100) in the client area YAHOO.util.UserAction.mousedown(element, { clientX: 100, clientY: 100 }); //simulate a mouse up at point (100,100) in the client area YAHOO.util.UserAction.mouseup(element, { clientX: 100, clientY: 100 }); //simulate a mouse move at point (200, 200) in the client area YAHOO.util.UserAction.mousemove(document.body, { clientX: 200, clientY: 200 });
var element = document.getElementById("myDiv"); //simulate a click Alt key down YAHOO.util.UserAction.click(element, { altKey: true}); //simulate a double click with Ctrl key down YAHOO.util.UserAction.dblclick(element, { ctrlKey: true }); //simulate a mouse over YAHOO.util.UserAction.mouseover(element, { relatedTarget: document.body }); //simulate a mouse out YAHOO.util.UserAction.mouseout(element, { relatedTarget: document.body }); //simulate a mouse down at point (100,100) in the client area YAHOO.util.UserAction.mousedown(element, { clientX: 100, clientY: 100 }); //simulate a mouse up at point (100,100) in the client area YAHOO.util.UserAction.mouseup(element, { clientX: 100, clientY: 100 }); //simulate a mouse move at point (200, 200) in the client area YAHOO.util.UserAction.mousemove(document.body, { clientX: 200, clientY: 200 });
There are three key event simulations available using UserAction
:
As with the mouse events, each key event has a corresponding method of the same name and accepts two arguments, which are the
target of the event and an object specifying additional properties for the event. For key events, the second argument is required
as you must specify which key was interacted with. For keyup()
and keydown()
, the keyCode
property must be specified; for keypress()
, the charCode
property must be included. In many cases,
keyCode
and charCode
may be the same value to represent the same key (97, for instance, represents the "A"
key as well as being the ASCII code for the letter "a"). For example:
var element = document.getElementById("myDiv"); //simulate a keydown on the A key YAHOO.util.UserAction.keydown(element, { keyCode: 97 }); //simulate a keyup on the A key YAHOO.util.UserAction.keydown(element, { keyCode: 97 }); //simulate typing "a" YAHOO.util.UserAction.keypress(element, { charCode: 97 });
var element = document.getElementById("myDiv"); //simulate a keydown on the A key YAHOO.util.UserAction.keydown(element, { keyCode: 97 }); //simulate a keyup on the A key YAHOO.util.UserAction.keydown(element, { keyCode: 97 }); //simulate typing "a" YAHOO.util.UserAction.keypress(element, { charCode: 97 });
Key events also support the ctrlKey
, altKey
, shiftKey
, and metaKey
event properties.
Note: Due to differences in browser implementations, key events may not be simulated in the same manner across
all browsers. For instance, when simulating a keypress event on a textbox, only Firefox will update the textbox with the new character
of the key that was simulated to be pressed. For other browsers, the events are still registered and all event handlers are called,
however, the textbox display and value
property are not updated. These differences should go away as browser support
for simulated events improves in the future.
Safari 2.x Developers: Due to a bug in the Safari 2.x codebase, simulating a keydown event may cause the browser to crash. This issue has been resolved in Safari 3.x.
YUI Test allows you to pause a currently running test and resume either after a set amount of time or
at another designated time. The TestCase
object has a method called wait()
. When wait()
is called, the test immediately exits (meaning that any code after that point will be ignored) and waits for a signal to resume
the test.
A test may be resumed after a certain amount of time by passing in two arguments to wait()
: a function to execute
and the number of milliseconds to wait before executing the function (similar to using setTimeout()
). The function
passed in as the first argument will be executed as part of the current test (in the same scope) after the specified amount of time.
For example:
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Setup and tear down //--------------------------------------------- setUp : function () { this.data = { name : "Nicholas", age : 29 }; }, tearDown : function () { delete this.data; }, //--------------------------------------------- // Tests //--------------------------------------------- testAsync: function () { YAHOO.util.Assert.areEqual("Nicholas", this.data.name, "Name should be 'Nicholas'"); //wait 1000 milliseconds and then run this function this.wait(function(){ YAHOO.util.Assert.areEqual(29, this.data.age, "Age should be 29"); }, 1000); } });
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Setup and tear down //--------------------------------------------- setUp : function () { this.data = { name : "Nicholas", age : 29 }; }, tearDown : function () { delete this.data; }, //--------------------------------------------- // Tests //--------------------------------------------- testAsync: function () { YAHOO.util.Assert.areEqual("Nicholas", this.data.name, "Name should be 'Nicholas'"); //wait 1000 milliseconds and then run this function this.wait(function(){ YAHOO.util.Assert.areEqual(29, this.data.age, "Age should be 29"); }, 1000); } });
In this code, the testAsync()
function does one assertion, then waits 1000 milliseconds before performing
another assertion. The function passed into wait()
is still in the scope of the original test, so it has
access to this.data
just as the original part of the test does. Timed waits are helpful in situations when
there are no events to indicate when the test should resume.
If you want a test to wait until a specific event occurs before resuming, the wait()
method can be called
without any arguments. At that point, testing will resume only when the resume()
method is called. The
resume()
method accepts a single argument, which is a function to run when the test resumes. This function
should specify additional assertions. The following tests to see if the Anim
object has performed its
animation completely:
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Tests //--------------------------------------------- testAnimation : function (){ var Assert = YAHOO.util.Assert; var YUD = YAHOO.util.Dom; //animate width to 400px var myAnim = new YAHOO.util.Anim('testDiv', { width: { to: 400 } }, 3, YAHOO.util.Easing.easeOut); //assign oncomplete handler myAnim.onComplete.subscribe(function(){ //tell the TestRunner to resume this.resume(function(){ Assert.areEqual(YUD.get("testDiv").offsetWidth, 400, "Width of the DIV should be 400."); }); }, this, true); //start the animation myAnim.animate(); //wait until something happens this.wait(); } });
var oTestCase = new YAHOO.tool.TestCase({ name: "TestCase Name", //--------------------------------------------- // Tests //--------------------------------------------- testAnimation : function (){ var Assert = YAHOO.util.Assert; var YUD = YAHOO.util.Dom; //animate width to 400px var myAnim = new YAHOO.util.Anim('testDiv', { width: { to: 400 } }, 3, YAHOO.util.Easing.easeOut); //assign oncomplete handler myAnim.onComplete.subscribe(function(){ //tell the TestRunner to resume this.resume(function(){ Assert.areEqual(YUD.get("testDiv").offsetWidth, 400, "Width of the DIV should be 400."); }); }, this, true); //start the animation myAnim.animate(); //wait until something happens this.wait(); } });
In this example, an Anim
object is used to animate the width of an element to 400 pixels. When the animation
is complete, the onComplete
method is fired, so that is where the resume()
method is called. The
function passed into resume()
simply tests that the final width of the element is indeed 400 pixels. Note that
for this to work, the scope of the event handler had to be adjusted by passing in the second and third arguments to
subscribe()
. Once the event handler is set up, the animation begins and then the wait()
method is
called without any arguments. At that point, testing stops until the animation completes and resume()
is called.
For large web applications, you'll probably have many test cases that should be run during a testing phase. A test suite helps to handle multiple test cases
by grouping them together into functional units that can be run together. To create new test suite, use the YAHOO.tool.TestSuite
constructor and pass in the name of the test suite. The name you pass in is for logging purposes and allows you to discern which TestSuite
instance currently running. For example:
//create the test suite var oSuite = new YAHOO.tool.TestSuite("TestSuite Name"); //add test cases oSuite.add(new YAHOO.tool.TestCase({ //... })); oSuite.add(new YAHOO.tool.TestCase({ //... })); oSuite.add(new YAHOO.tool.TestCase({ //... }));
//create the test suite var oSuite = new YAHOO.tool.TestSuite("TestSuite Name"); //add test cases oSuite.add(new YAHOO.tool.TestCase({ //... })); oSuite.add(new YAHOO.tool.TestCase({ //... })); oSuite.add(new YAHOO.tool.TestCase({ //... }));
Here, a test suite is created and three test cases are added to it using the add()
method. The test suite now contains all of the
information to run a series of tests.
It's also possible to add other multiple TestSuite
instances together under a parent TestSuite
using the same add()
method:
//create a test suite var oSuite = new YAHOO.tool.TestSuite("TestSuite Name"); //add a test case oSuite.add(new YAHOO.tool.TestCase({ ... }); //create another suite var oAnotherSuite = new YAHOO.tool.TestSuite("test_suite_name"); //add a test case oAnotherSuite.add(new YAHOO.tool.TestCase({ ... }); //add the second suite to the first oSuite.add(oAnotherSuite);
//create a test suite var oSuite = new YAHOO.tool.TestSuite("TestSuite Name"); //add a test case oSuite.add(new YAHOO.tool.TestCase({ ... }); //create another suite var oAnotherSuite = new YAHOO.tool.TestSuite("test_suite_name"); //add a test case oAnotherSuite.add(new YAHOO.tool.TestCase({ ... }); //add the second suite to the first oSuite.add(oAnotherSuite);
By grouping test suites together under a parent test suite you can more effectively manage testing of particular aspects of an application.
Test suites may also have setUp()
and tearDown()
methods. A test suite's setUp()
method is called before
the first test in the first test case is executed (prior to the test case's setUp()
method); a test suite's tearDown()
method executes after all tests in all test cases/suites have been executed (after the last test case's tearDown()
method). To specify
these methods, pass an object literal into the YAHOO.tool.TestSuite
constructor:
//create a test suite var oSuite = new YAHOO.tool.TestSuite({ name : "TestSuite Name", setUp : function () { //test-suite-level setup }, tearDown: function () { //test-suite-level teardown } });
//create a test suite var oSuite = new YAHOO.tool.TestSuite({ name : "TestSuite Name", setUp : function () { //test-suite-level setup }, tearDown: function () { //test-suite-level teardown } });
Test suite setUp()
and tearDown()
may be helpful in setting up global objects that are necessary for a multitude of tests
and test cases.
In order to run test cases and test suites, use the YAHOO.tool.TestRunner
object. This object is a singleton that
simply runs all of the tests in test cases and suites, reporting back on passes and failures. To determine which test cases/suites
will be run, add them to the TestRunner
using the add()
method. Then, to run the tests, call the run()
method:
//add the test cases and suites YAHOO.tool.TestRunner.add(oTestCase); YAHOO.tool.TestRunner.add(oTestSuite); //run all tests YAHOO.tool.TestRunner.run();
//add the test cases and suites YAHOO.tool.TestRunner.add(oTestCase); YAHOO.tool.TestRunner.add(oTestSuite); //run all tests YAHOO.tool.TestRunner.run();
If at some point you decide not to run the tests that have already been added to the TestRunner
, they can be removed by calling clear()
:
YAHOO.tool.TestRunner.clear();
YAHOO.tool.TestRunner.clear();
Making this call removes all test cases and test suites that were added using the add()
method.
The TestRunner
provides results and information about the process by publishing several events. These events can occur at four
different points of interest: at the test level, at the test case level, at the test suite level, and at the TestRunner
level.
The data available for each event depends completely on the type of event and the level at which the event occurs.
Test-level events occur during the execution of specific test methods. There are three test-level events:
TestRunner.TEST_PASS_EVENT
- occurs when the test passes.TestRunner.TEST_FAIL_EVENT
- occurs when the test fails.TestRunner.TEST_IGNORE_EVENT
- occurs when a test is ignored.For each of these events, the event data object has three properties:
type
- indicates the type of event that occurred.testCase
- the test case that is currently being run.testName
- the name of the test that was just executed or ignored.For TestRunner.TEST_FAIL_EVENT
, an error
property containing the error object
that caused the test to fail.
There are two events that occur at the test case level:
TestRunner.TEST_CASE_BEGIN_EVENT
- occurs when the test case is next to be executed but before the first test is run.TestRunner.TEST_CASE_COMPLETE_EVENT
- occurs when all tests in the test case have been executed or ignored.For these two events, the event data object has three properties:
type
- indicates the type of event that occurred.testCase
- the test case that is currently being run.For TEST_CASE_COMPLETE_EVENT
, an additional property called results
is included. The results
property is an object containing the aggregated results for all tests in the test case (it does not include information about tests that
were ignored). Each test that was run has an entry in the result
object where the property name is the name of the test method
and the value is an object with two properties: result
, which is either "pass" or "fail", and message
, which is a
text description of the result (simply "Test passed" when a test passed or the error message when a test fails). Additionally, the
failed
property indicates the number of tests that failed in the test case, the passed
property indicates the
number of tests that passed, and the total
property indicates the total number of tests executed. A typical results
object looks like this:
{ failed: 1, passed: 1, ignored: 0, total: 2, type: "testcase", name: "Test Case 0", test0: { result: "pass", message: "Test passed", type: "test", name: "test0" }, test1: { result: "fail", message: "Assertion failed", type: "test", name: "test1" } }
{ failed: 1, passed: 1, ignored: 0, total: 2, type: "testcase", name: "Test Case 0", test0: { result: "pass", message: "Test passed", type: "test", name: "test0" }, test1: { result: "fail", message: "Assertion failed", type: "test", name: "test1" } }
The TEST_CASE_COMPLETE_EVENT
provides this information for transparency into the testing process.
There are two events that occur at the test suite level:
TestRunner.TEST_SUITE_BEGIN_EVENT
- occurs when the test suite is next to be executed but before the first test is run.TestRunner.TEST_SUITE_COMPLETE_EVENT
- occurs when all tests in all test cases in the test suite have been executed or ignored.For these two events, the event data object has three properties:
type
- indicates the type of event that occurred.testSuite
- the test suite that is currently being run.The TEST_SUITE_COMPLETE_EVENT
also has a results
property, which contains aggregated results for all of the
test cases (and other test suites) it contains. Each test case and test suite contained within the main suite has an entry in the
results
object, forming a hierarchical structure of data. A typical results
object may look like this:
{ failed: 2, passed: 2, ignored: 0, total: 4, type: "testsuite", name: "Test Suite 0", testCase0: { failed: 1, passed: 1, ignored: 0, total: 2, type: "testcase", name: "testCase0", test0: { result: "pass", message: "Test passed." type: "test", name: "test0" }, test1: { result: "fail", message: "Assertion failed.", type: "test", name: "test1" } }, testCase1: { failed: 1, passed: 1, ignored: 0, total: 2, type: "testcase", name: "testCase1", test0: { result: "pass", message: "Test passed.", type: "test", name: "test0" }, test1: { result: "fail", message: "Assertion failed.", type: "test", name: "test1" } } }
{ failed: 2, passed: 2, ignored: 0, total: 4, type: "testsuite", name: "Test Suite 0", testCase0: { failed: 1, passed: 1, ignored: 0, total: 2, type: "testcase", name: "testCase0", test0: { result: "pass", message: "Test passed." type: "test", name: "test0" }, test1: { result: "fail", message: "Assertion failed.", type: "test", name: "test1" } }, testCase1: { failed: 1, passed: 1, ignored: 0, total: 2, type: "testcase", name: "testCase1", test0: { result: "pass", message: "Test passed.", type: "test", name: "test0" }, test1: { result: "fail", message: "Assertion failed.", type: "test", name: "test1" } } }
This example shows the results for a test suite with two test cases, but there may be test suites contained within test suites. In that case, the hierarchy is built out accordingly, for example:
{ failed: 3, passed: 3, ignored: 0, total: 6, type: "testsuite", name: "Test Suite 0", testCase0: { failed: 1, passed: 1, ignored: 0, total: 2, type: "testcase", name: "testCase0", test0: { result: "pass", message: "Test passed.", type: "test", name: "test0" }, test1: { result: "fail", message: "Assertion failed.", type: "test", name: "test1" } }, testCase1: { failed: 1, passed: 1, ignored: 0, total: 2, type: "testcase", name: "testCase1", test0: { result: "pass", message: "Test passed.", type: "test", name: "test0" }, test1: { result: "fail", message: "Assertion failed.", type: "test", name: "test1" } }, testSuite0:{ failed: 1, passed: 1, ignored: 0, total: 2, type: "testsuite", name: "testSuite0", testCase2: { failed: 1, passed: 1, ignored: 0, total: 2, type: "testcase", name: "testCase2", test0: { result: "pass", message: "Test passed.", type: "test", name: "test0" }, test1: { result: "fail", message: "Assertion failed.", type: "test", name: "test1" } } } }
{ failed: 3, passed: 3, ignored: 0, total: 6, type: "testsuite", name: "Test Suite 0", testCase0: { failed: 1, passed: 1, ignored: 0, total: 2, type: "testcase", name: "testCase0", test0: { result: "pass", message: "Test passed.", type: "test", name: "test0" }, test1: { result: "fail", message: "Assertion failed.", type: "test", name: "test1" } }, testCase1: { failed: 1, passed: 1, ignored: 0, total: 2, type: "testcase", name: "testCase1", test0: { result: "pass", message: "Test passed.", type: "test", name: "test0" }, test1: { result: "fail", message: "Assertion failed.", type: "test", name: "test1" } }, testSuite0:{ failed: 1, passed: 1, ignored: 0, total: 2, type: "testsuite", name: "testSuite0", testCase2: { failed: 1, passed: 1, ignored: 0, total: 2, type: "testcase", name: "testCase2", test0: { result: "pass", message: "Test passed.", type: "test", name: "test0" }, test1: { result: "fail", message: "Assertion failed.", type: "test", name: "test1" } } } }
In this code, the test suite contained another test suite named "testSuite0", which is included in the results along with its test cases. At each level, the results are aggregated so that you can tell how many tests passed or failed within each test case or test suite.
There are two events that occur at the TestRunner
level:
TestRunner.BEGIN_EVENT
- occurs when testing is about to begin but before any tests are run.TestRunner.COMPLETE_EVENT
- occurs when all tests in all test cases and test suites have been executed or ignored.The data object for these events contain a type
property, indicating the type of event that occurred. COMPLETE_EVENT
also includes a results
property that is formatted the same as the data returned from TEST_SUITE_COMPLETE_EVENT
and
contains rollup information for all test cases and tests suites that were added to the TestRunner
.
You can subscribe to particular events by calling the subscribe()
method
(see the documentation). Your event handler code
should expect a single object to be passed in as an argument. This object provides information about the event that just occured. Minimally,
the object has a type
property that tells you which type of event occurred. Example:
function handleTestFail(data){ alert("Test named '" + data.testName + "' failed with message: '" + data.error.message + "'."); } var TestRunner = YAHOO.tool.TestRunner; TestRunner.subscribe(TestRunner.TEST_FAIL_EVENT, handleTestFail); TestRunner.run();
function handleTestFail(data){ alert("Test named '" + data.testName + "' failed with message: '" + data.error.message + "'."); } var TestRunner = YAHOO.tool.TestRunner; TestRunner.subscribe(TestRunner.TEST_FAIL_EVENT, handleTestFail); TestRunner.run();
In this code, the handleTestFail()
function is assigned as an event handler for TEST_FAIL_EVENT
. You can also
use a single event handler to subscribe to any number of events, using the event data object's type
property to determine
what to do:
function handleTestResult(data){ var TestRunner = YAHOO.tool.TestRunner; switch(data.type) { case TestRunner.TEST_FAIL_EVENT: alert("Test named '" + data.testName + "' failed with message: '" + data.error.message + "'."); break; case TestRunner.TEST_PASS_EVENT: alert("Test named '" + data.testName + "' passed."); break; case TestRunner.TEST_IGNORE_EVENT: alert("Test named '" + data.testName + "' was ignored."); break; } } var TestRunner = YAHOO.tool.TestRunner; TestRunner.subscribe(TestRunner.TEST_FAIL_EVENT, handleTestResult); TestRunner.subscribe(TestRunner.TEST_IGNORE_EVENT, handleTestResult); TestRunner.subscribe(TestRunner.TEST_PASS_EVENT, handleTestResult); TestRunner.run();
function handleTestResult(data){ var TestRunner = YAHOO.tool.TestRunner; switch(data.type) { case TestRunner.TEST_FAIL_EVENT: alert("Test named '" + data.testName + "' failed with message: '" + data.error.message + "'."); break; case TestRunner.TEST_PASS_EVENT: alert("Test named '" + data.testName + "' passed."); break; case TestRunner.TEST_IGNORE_EVENT: alert("Test named '" + data.testName + "' was ignored."); break; } } var TestRunner = YAHOO.tool.TestRunner; TestRunner.subscribe(TestRunner.TEST_FAIL_EVENT, handleTestResult); TestRunner.subscribe(TestRunner.TEST_IGNORE_EVENT, handleTestResult); TestRunner.subscribe(TestRunner.TEST_PASS_EVENT, handleTestResult); TestRunner.run();
To view the results of tests, create a new YAHOO.tool.TestLogger
object. The TestLogger
is a subclass of the
Logger widget that is specifically designed to output results from the TestRunner
. Before calling
TestRunner.run()
, create a new instance of the TestLogger
to ensure that all results are reported:
var oLogger = new YAHOO.tool.TestLogger(); YAHOO.tool.TestRunner.run();
var oLogger = new YAHOO.tool.TestLogger(); YAHOO.tool.TestRunner.run();
Once created, you can filter the data to show only tests that passed, only tests that failed, etc.
When all tests have been completed and the results object has been returned, you can post those results to a server
using a YAHOO.tool.TestReporter
object. A TestReporter
object creates a form that is POSTed
to a specific URL with the following fields:
results
- the serialized results object.useragent
- the user-agent string of the browser.timestamp
- the date and time that the report was sent.You can create a new TestReporter
object by passing in the URL to report to. The results object can
then be passed into the report()
method to submit the results:
var oReporter = new YAHOO.tool.TestReporter("http://www.yourserver.com/path/to/target"); oReporter.report(results);
var oReporter = new YAHOO.tool.TestReporter("http://www.yourserver.com/path/to/target"); oReporter.report(results);
The form submission happens behind-the-scenes and will not cause your page to navigate away. This operation is one direction; the reporter does not get any content back from the server.
There are two predefined serialization formats for results objects: XML (the default) and JSON. The format can be
specified in the TestReporter
constructor by passing in YAHOO.tool.TestFormat.XML
or
YAHOO.tool.TestFormat.JSON
(when no argument is specified, YAHOO.tool.TestFormat.XML
is used:
var oReporter = new YAHOO.tool.TestReporter("http://www.yourserver.com/path/to/target", YAHOO.tool.TestFormat.JSON);
var oReporter = new YAHOO.tool.TestReporter("http://www.yourserver.com/path/to/target", YAHOO.tool.TestFormat.JSON);
The XML format outputs results in the following format:
<report name="YUI Test Results" passed="5" failed="3" ignored="1" total="5"> <testsuite name="yuisuite" passed="5" failed="0" ignored="0" total="5"> <testcase name="YAHOO.util.Anim" passed="5" failed="0" ignored="0" total="5"> <test name="test_getEl" result="pass" message="Test passed" /> <test name="test_isAnimated" result="pass" message="Test passed" /> <test name="test_stop" result="pass" message="Test passed" /> <test name="test_onStart" result="pass" message="Test passed" /> <test name="test_endValue" result="pass" message="Test passed" /> </testcase> </testsuite> </report>
<report name="YUI Test Results" passed="5" failed="3" ignored="1" total="5"> <testsuite name="yuisuite" passed="5" failed="0" ignored="0" total="5"> <testcase name="YAHOO.util.Anim" passed="5" failed="0" ignored="0" total="5"> <test name="test_getEl" result="pass" message="Test passed" /> <test name="test_isAnimated" result="pass" message="Test passed" /> <test name="test_stop" result="pass" message="Test passed" /> <test name="test_onStart" result="pass" message="Test passed" /> <test name="test_endValue" result="pass" message="Test passed" /> </testcase> </testsuite> </report>
The JSON format requires the JSON utility to be loaded on the page and outputs results in a format that follows the object/array hierarchy of the results object, such as:
{ "passed": 5, "failed": 0, "ignored": 0, "total": 0, "type": "report", "name": "YUI Test Results", "yuisuite":{ "passed": 5, "failed": 0, "ignored": 0, "total": 0, "type": "testsuite", "name": "yuisuite", "YAHOO.util.Anim":{ "passed": 5, "failed": 0, "ignored": 0, "total": 0, "type":"testcase", "name":"YAHOO.util.Anim", "test_getEl":{ "result":"pass", "message":"Test passed.", "type":"test", "name":"test_getEl" }, "test_isAnimated":{ "result":"pass", "message":"Test passed.", "type":"test", "name":"test_isAnimated" }, "test_stop":{ "result":"pass", "message":"Test passed.", "type":"test", "name":"test_stop" }, "test_onStart":{ "result":"pass", "message":"Test passed.", "type":"test", "name":"test_onStart" }, "test_endValue":{ "result":"pass", "message":"Test passed.", "type":"test", "name":"test_endValue" } } } }
{ "passed": 5, "failed": 0, "ignored": 0, "total": 0, "type": "report", "name": "YUI Test Results", "yuisuite":{ "passed": 5, "failed": 0, "ignored": 0, "total": 0, "type": "testsuite", "name": "yuisuite", "YAHOO.util.Anim":{ "passed": 5, "failed": 0, "ignored": 0, "total": 0, "type":"testcase", "name":"YAHOO.util.Anim", "test_getEl":{ "result":"pass", "message":"Test passed.", "type":"test", "name":"test_getEl" }, "test_isAnimated":{ "result":"pass", "message":"Test passed.", "type":"test", "name":"test_isAnimated" }, "test_stop":{ "result":"pass", "message":"Test passed.", "type":"test", "name":"test_stop" }, "test_onStart":{ "result":"pass", "message":"Test passed.", "type":"test", "name":"test_onStart" }, "test_endValue":{ "result":"pass", "message":"Test passed.", "type":"test", "name":"test_endValue" } } } }
Each of the formats produces a string with no extra white space (white space and indentation shown here is for readability purposes only).
You can optionally specify additional fields to be sent with the results report by using the addField()
method.
This method accepts two arguments: a name and a value. Any field added using addField()
is POSTed along with
the default fields back to the server:
oReporter.addField("color", "blue"); oReporter.addField("message", "Hello world!");
oReporter.addField("color", "blue"); oReporter.addField("message", "Hello world!");
Note that if you specify a field name that is the same as a default field, the custom field is ignored in favor of the default field.
About this Section: YUI generally works well with mobile browsers that are based on A-Grade browser foundations. For example, Nokia's N-series phones, including the N95, use a browser based on Webkit — the same foundation shared by Apple's Safari browser, which is found on the iPhone. The fundamental challenges in developing for this emerging class of full, A-Grade-derived browsers on handheld devices are:
There are other considerations, many of them device/browser specific (for example, current versions of the iPhone's Safari browser do not support Flash). The goal of these sections on YUI User's Guides is to provide you some preliminary insights about how specific components perform on this emerging class of mobile devices. Although we have not done exhaustive testing, and although these browsers are revving quickly and present a moving target, our goal is to provide some early, provisional advice to help you get started as you contemplate how your YUI-based application will render in the mobile world.
More Information:
YUI Test works with only minor issues on mobile devices. Things to be aware of:
setTimeout()
function, which is necessary for asynchronous tests. YUI Test will automatically
revert to synchronous mode for running tests in this situation and any tests that the wait()
method will throw an error.mouseover
or mouseout
and
many do not support key events at all.The YUI Library and related topics are discussed on the on the YUILibrary.com forums.
Also be sure to check out YUIBlog for updates and articles about the YUI Library written by the library's developers.
The YUI Library's public bug tracking and feature request repositories are located on the YUILibrary.com site. Before filing new feature requests or bug reports, please review our reporting guidelines.
All YUI 2.x users should review the YUI 2.8.2 security bulletin, which discusses a vulnerability present in YUI 2.4.0-2.8.1.
Copyright © 2013 Yahoo! Inc. All rights reserved.