|
Tests
Detailed Introduction to the Test Module Service
IntroductionThe Hemi JavaScript Framework includes a set of APIs, Templates, and Fragments for creating and executing unit tests and generally promoting Test Driven Development. These features can be used to write tests for any Web page or JavaScript toolkit (eg: JQuery, Prototype, Dojo). Related Reading
General ApproachTest Modules are modules with additional instrumentation:
For example, given a script file /SomeDir/mytest.js, the following would represent one synchronous test for the HTML node (the connection between the two will follow) Synchronous Example<!-- Some HTML -->
<p id = "oPara">Some Content</p>
/// /SomeDir/mytest.js
///
function TestContent(){
this.Assert(Hemi.xml.getInnerText(Container).match(/Some Content/), "Content not found");
}Running the ExampleTo run this example, the test must be loaded for the HTML node: /// Note: The name is the file name without the .js extension
var oTest = Hemi.app.module.test.NewTest("mytest", document.getElementById("oPara"), 0, 0, "/SomeDir/");
/// Run all tests
oTest.RunTests();
/// For synchronous testing only:
/// Get a named test result:
///
var oTestResult = oTest.getTestByName("TestContent");
/// Get a formatted report of all test results
///
var sReport = oTest.getReport();Asynchronous ExampleAsynchronous tests are supported by returning false from a given Test, completed by using the dynamic Continue and virtual HandleContinue methods, and/or the dynamic End method. The following example demonstrates an asynchronous test that asynchronously loads some xml, changes the Container content, and then makes an assertion about the result. <!-- Some HTML -->
<p id = "oPara">Some Content</p>
/// /SomeDir/mytest.js
///
function TestAsyncContent(){
Hemi.xml.getXml("/SomeXml.xml",LoadXml,1);
return false;
}
function LoadXml(sName, vData){
/// Copy XML contents into HTML node
if(vData.xdom) Hemi.xml.setInnerXHTML(Container, vData.xdom);
ContinueTestAsyncContent();
}
function HandleContinueTestAsyncContent(){
this.Assert(Hemi.xml.getInnerText(Container).match(/Some Content From XML/), "Content not found");
return true;
}Running the ExampleTo run this example, the test must be loaded for the HTML node, and a callback defined to receive the results once the test status changes.
/// Invoked when the Test status changes
function HandleTestStatus(oTest, oTestModule, iState){
}
/// Invoked when the test suite has completed running
function HandleTestSuite(oTestModule){
}
/// Note: The name is the file name without the .js extension
var oTest = Hemi.app.module.test.NewTest("mytest", document.getElementById("oPara"), HandleTestStatus, HandleTestSuite, "/SomeDir/");
oTest.RunTests();Test Components and TemplatesThe Hemi JavaScript Framework includes several additional features for working with tests and Test Modules, and to streamline the connection between HTML nodes and tests without relying on global identifiers. Testable ComponentThe Component, component.testable.xml Application Component loads a set of tests defined for a particular HTML node, and renders visual indicators for the test status. The component is automatically loaded via the Application Space Service, and automatically instrumented by the XHTMLComponent class. The testable component supports the following attributes:
For example, given some HTML: <p>Some Content</p> The testable component and test configuration can be defined as a set of attributes, which in addition to instrumenting the tests also render a UI for viewing results: <p component = "testable" test-path = "/SomeDir/" tests = "mytest">Some Content</p> TestSuite TemplateThe TestSuite Template and TestSuite Fragment are provided to interact with and customize defined tests. The test suite is straightforward to load by directly referencing the Template, and then setting a custom list of tests on the suite. <input type = "button" value = "Test Suite" onclick = "Hemi.app.createWindow('Test Suite','Templates/TestSuite.xml', 'TestSuite');" />
var g_tests = "mytest";
var g_testdir = "/SomeDir/";
Hemi.message.service.subscribe("ontemplateload", function (s, v) {
if (v.getContainerComponentId() != "TestSuite") return;
v.setTests(g_tests.split(","), g_testdir);
});Defining Tests in Encoded JSON CSSThe Hemi JavaScript Framework includes a utility to decode JSON from a CSS class name. This allows test configuration to be encoded, such as: <p class = "{#HF_WebUnit{testPath:'/SomeDir/',tests:'mytest'}}"">Example Content</p>And then using Hemi, or any framework that indexes by CSS class, can be used to extract the nodes with this class, so that: var oNode = ...;
var sClass = "{#HF_WebUnit{testPath:'/SomeDir/',tests:'mytest'}}";
var oConfig = Hemi.css.decodeJSON(sClass);
var oTest = var oTest = Hemi.app.module.test.NewTest(oConfig.WebUnit.tests[0], oNode, 0, 0, oConfig.WebUnit.testPath);
oTest.RunTests();Refer to the Get Started with Hemi and TDD article for a more detailed example using the Application Space Service. Handling Test ResultsWhen a test is started per Test Module instance, a TestResult is created. The following TestResult demonstrates how a failing and incomplete test result may appear.
For convenience, a report can be generated from the results. The TestResult may be represented as part of a generated report: test.transaction Test Results Test:TestCrossUsePacketTransaction(0 sec) Errors:Yes Messages: Packet was not handled ReportThe getReport method is a convenience for visually inspecting test results when not using the Testable Component or Test Suite indicators. TestResultThe TestResult object is available as a parameter to the Test and HandleContinueTest test methods, and the test handler specified in the constructor. Test results can be retrieved from a Test Module instance via the getTests and getTestByName methods. |