JAVASCRIPT ASSERTION UNIT FRAMEWORK SourceForge.net Logo

Framework content

jsAssertUnit is a small package with two main files (the whole package content is detailled in the Download page): assert.js and reporter.js.
These two files as well as reporter.html and reporter.css MUST be located in the same directory. Name that directory as you wish but, may we suggest "assert"?
In addition, you have to adapt the REPORTER_URL global variable declared at the end of the assrt.js file.
You have two options: give this url an absolute path, for instance: http://127.0.0.1/jsAssrtUnit/reporter.html or give it a relative path mirroring the path from your test file to your reporter.html file, for instance ../reporter.html, as in the coretest.html file you will find in the test directory.

assert.js contains the core assertion classes (9):

ASSERT_Tester: the singleton class of the Assert global object whose public methods are invoked by your assertions
ASSERT_Processor: a class to test the assertions
ASSERT_Argument: a class to hold the arguments of an assertion
ASSERT_Abstract_Failure: an abstract class to wrap the informations of a failing assertion
ASSERT_Failure: a subclass of ASSERT_Abstract_Failure to report an assertion failure
ASSERT_Warning: a subclass of ASSERT_Abstract_Failure to fire a warning (not properly an assertion)
ASSERT_Reporter: a class to handle the reporting of assertion failures and warnings
ASSERT_Reporter_Stat: a class to record the statistics about a test session
ASSERT_Reporter_Viewer: a class to control the report display in a browser window

reporter.js contains 2 classes handling the display of a failure report:

ASSERT_Report_Listener: a singleton class whose instance is running in the backgroud to handle catched failures to be reported
ASSERT_Report_Formater: a class to format the report (mainly controled thru CSS)

Any class can be subclassed if you want to adapt jsAssertUnit to your needs. As you can see browsing the code, the classes have been very carefully designed to allow an easy understanding and extensibility of the tool behaviour.

To help you (and us), every class, function, argument or variable has a documented type, following the typing convention of the Java language. This typing documentation comes in the form

var
/*ASSERT_Tester*/Assert = new ASSERT_Tester();

If you use a good source code editor (we use jEdit, a fine Java open source editor) with code highlightning, these commented indications can be faded out to avoid a cluttered code reading, yet providing valuable programming indications.
That's a coding style we think very helpfull to work with JavaScript, a (very) loosely typed language.

Assert and Argument global variables

Two global variables are declared in the assert.js file to execute the assertion tests : Assert and Argument.
So, you MUST NOT have variables with these names declared in the scripts being tested.
Either change the name of these variables in jsAssertUnit files or (prefered way) give your variables another name.

Public methods

The list of the public methods available is the following (names should be self-explanatory):

ASSERT_Tester methods
/*boolean*/ Assert.isTrue	//checking methods
/*boolean*/ Assert.isFalse
/*boolean*/ Assert.isNull
/*boolean*/ Assert.isNotNull
/*boolean*/ Assert.isUndefined
/*boolean*/ Assert.isNotUndefined

/*boolean*/ Assert.isNumber	//computing methods
/*boolean*/ Assert.isNotNumber

/*boolean*/ Assert.isEqual	//comparing methods
/*boolean*/ Assert.isNotEqual

/*boolean*/ Assert.warn		//warning method
ASSERT_Argument methods
/*boolean*/ Argument.isNumber	//typing methods
/*boolean*/ Argument.isString
/*boolean*/ Argument.isUndefined
/*boolean*/ Argument.isNull
/*boolean*/ Argument.isBoolean
/*boolean*/ Argument.isArray
/*boolean*/ Argument.isObject
/*boolean*/ Argument.isEmpty	//string and array objects only
Utility methods
/*string*/ sprintf //simplified version of the sprintf C function
/*int*/ strcmp //string comparison
Global functions
/*void*/ clearReport //to clear the reporter window
/*void*/ setEnd //to end the reporting

Of course, any class method can actually be accessed from anywhere in a JavaScript script. But as we said it in the Tutorial page, we enforce a Java programming style by giving every method and member of a class a virtual Java access specifier.

Public method signatures

We've done our best to provide these public assertion methods with a kind of overloading mechanism.

Once again, this concept is a central point of the OO technology which is not actually implemented in JavaScript.
But we "emulated" it. Basically, this mechanism allows you to call a method with a variable number and type of arguments, thus giving each assertion method different possible signatures.

For checking and computing methods, the possible signatures are:

(/*any*/argument)			//inconditional check
(/*any*/argument, /*boolean*/checkingCondition)
(/*any*/argument, /*string*/assertionComment)			//inconditional check
(/*any*/argument, /*boolean*/checkingCondition, /*string*/assertionComment)

For comparing methods, the possible signatures are:

(/*any*/argument, /*any*/argument)		//inconditional check
(/*any*/argument, /*any*/argument, /*boolean*/checkingCondition)
(/*any*/argument, /*any*/argument, /*string*/assertionComment)		//inconditional check
(/*any*/argument, /*any*/argument, /*boolean*/checkingCondition, /*string*/assertionComment)

For the warning method, the possible signatures are:

(/*string*/warning)			//inconditional check
(/*string*/warning, /*boolean*/checkingCondition)

We think the possibility to conditionally check the assertion is very usefull.
First, you can define (as we've done in our sample tests), a global (public static final) variable to decide wether assertion checks are to be done. Thus, once your code is right, you're not obliged to remove every assertion instruction. They can stay in line, waiting for future code improvements; they only add a very light processing overhead. All you have to do is to give your global variable a false value to skip checking.
Second, you can chain assertions: every assertion check returns a true or false boolean value (true if assertion succeeds, false if it fails). This way you can check an assertion according to the result of a previous assertion. As, for instance:

var
/*boolean*/assertResult = Assert.isTrue(expressionToCheck, true);
Assert.isTrue(anotherExpressionToCheck, assertResult); //this assertion is checked only if previous as succeeded

Third, and it may be the most important trick for those using alert boxes to track bugs in their code, you can do assertion in loops, just affecting the checking condition argument with any boolean expression involving some "hot" value of your looping variable. For example:

var
/*string[]*/stringArray = ['primo', 'secondo', 'tertio'];
for(var i = 0, m = stringArray.length;i < m; i++){
	Assert.isEqual('primo', stringArray[i], i == 0);	//assertion checked only at the begining of the loop
	//any processing;
	Assert.isEqual('tertio', stringArray[i], i == (m - 1));	//assertion checked only at the end of the loop
	}

When faced with complex looping logic (not as in our simplistic example), this conditional checking ability is crucial, as it allows you to test only sensitive steps or to list, using a warning assertion, the output of the variables included in your loop.
Of course, you can combine these different logics and, for instance, execute the assertion checking in a loop only for a certain value of the loop counter and if a global assertion checking variable is set. It's only a matter of conditional test expression and it can be quite complex if you wish.

One thing to strictly observe to take advantage of the overloading mechanism, is that your checking condition MUST be a boolean variable, not a string variable. A string variable will be evaluated as an assertion comment.

Variable type testing

jsAssertUnit conforms to the ECMA Script 1.0 variable typing : tests use equality operators (== and !=), not the identity operators (=== and !==).
So : null and undefined are equal but not equal to 0, empty string or false.
Empty string or array are considered number (0) as they evaluate to false -- false and true are converted to 0 and 1.
See the full set of tests in the file coretest.js.

Customizing the Reporter window

The reporter window geometry can easily been customize according to your screen dimensions. Just edit the values of the global variables defined in the CONFIGURATION PARAMETERS section at the end of the assert.js script file.
Once opened, the reporter is checking for new assertion failures every second. But this tick value can be customized editing the Reporter instance global variable at the end of the reporter.js script file.