Testing the implementation ensures that all parts of the implementation function according to the specification.
In this module we will be learning how to run Test262 tests, as well as implement tests ourselves.
There are two different test suites built into SpiderMonkey: jstests (also known as Test262) to test adherence to the specification, and tests testing behavior specific to SpiderMonkey. An example of the latter behavior is Monkey Patching, which is discussed in Module 5.
Tests from the Test262 test suite are located in the folder mozilla-unified/js/src/tests/test262.
To run a test from Test262:
$ ./mach jstests TEST_PATH_SUBSTRING TEST_PATH_SUBSTRING designates the path to either the directory of tests, or a specific test to be executed.
For example, in order to run the tests for all Array built-ins, the following command is used:
$ ./mach jstests built-ins/ArrayThe jstests has a number of flags, some of them include:
-
-s (--show-cmd): Show the exact command line used to run each test.
-
-o (--show-output): Print each test’s output.
-
--args SHELL_ARGS: Extra arguments to pass to the JS shell.
-
--rr Run tests under the rr record-and-replay debugger.
To show more options run
$ ./mach jstests -- -h-
Run the tests associated with
Array.prototype.filter. -
Make
jstestsoutput the result of each test withinArray.prototype.filter.
Tests provide quick and simple functionality to determine if previously implemented parts of the specification break when new code is added.
You as an implementor may either implement tests before implementing the Array Grouping proposal (essentially meaning test-driven development), or after it. In any case, implementing tests is mandatory for every new addition to Ecma-262.
Consider the following imaginary proposal for Ecma-262:
Note 1: The function should always return a Number. Note 2: The number returned is always 1. Array.prototype.one([,thisArg]) 1. return 1
This proposal has only one line to test, however, there are two parts of this proposal that have to be tested:
- The function has to return a
Number - The
Numberhas to be 1
Now, to write the test, we create a file isNumber.js in the Array/prototype/ folder. The contents of the file will be as follows:
assert(function(){
return Number.isInteger([].one())
}, "Result of one() is integer")
reportCompare(0,0);The tests created for Test262 use a Test262 function called assert. This function allows asserting several different conditions. These are as follows:
assert(function => boolean, message): Asserts the boolean is true, otherwise displays message if-ois run as test optionassert.throws(e, f(){CODE_TO_TEST}): asserts that the functionfreturns the erroreassert.sameValue(a, b, message): asserts thataandbcontain the same value.assert.notSameValue(a, b, message): asserts thataandbdo not contain the same value
It is also important to add reportCompare(0,0); at the end of a test. This function is somewhat similar to assertEq, though some differences exist (a short overview can be found here).
During an execution of a test, if the line reportCompare(0,0) is reached, the test will show as passed.
In order to explicitly fail a test, reportCompare can be called with non-equal parameters:
if(failedCondition){
reportCompare(1,0);
}else{
reportCompare(0,0);
}Create a small test that tests whether or not the functionArray.prototype.one from our imaginary proposal returns the value 1.
Consider line 3 of the specification of the Array Grouping proposal:
If IsCallable(callbackfn) is false, throw a TypeError exception.Create a subfolder groupBy in the folder mozilla-unified/js/src/tests/test262/built-ins/Array/prototype/ and create a test file named appropriately.
Run your test and verify that your implementation of line 3 works.
Writing Test262 tests for Array Grouping will take place in Module 8.