A light, modular, promissory, isomorphic Jasmine test scaffold clone
“Jasmine (taxonomic name Jasminum /ˈdʒæzmɨnəm/) is a genus of shrubs and vines in the olive family (Oleaceae)” — Wikipedia
First, write a test.
// test/my-test.jsdescribe"my library"it"should work"expect10toBeLessThan20;;;
You can install the
jasminum command using
❯ [sudo] npm install jasminum -g
jasminum to run your test.
jasminum will run all test files specified,
*-spec.js files within each specified directory.
❯ jasminum test1 tests passed1 assertions passed0 tests failed0 assertions failed0 errors0 tests skipped
The results will be colored to draw your attention either to passed, failed, or
skipped tests depending on the situation. You can use
focus on certain tests, skipping all others. You can use
to skip certain tests.
You can use the
-f command line flag to only show information about failed
tests. Because the test runner does not know whether to show the name of the
test until it fails, test names, and all of their parent suite names, will be
logged after the test fails instead of before. Arrows draw your attention to
With PhantomJS installed, Jasminum can run the same tests in the PhantomJS headless browser. The interface and reports are identical.
❯ jasminum-phantom test1 tests passed1 assertions passed0 tests failed0 assertions failed0 errors0 tests skipped
You can create an “isomorphic” test runner that you can use to run tests in Node.js directly, or using a browser module loader, or to measure test coverage.
// test/index.jsvar Suite = require"jasminum";"my tests"describerequire"./my-test";runAndReportdone;
Jasminum can be installed with
npm. Make sure you have a
npm init will walk you through that.
Add Jasminum to your package with
npm install jasminum --save-dev and create a
test script so that it will run with
npm test will run your tests.
To run the same tests in a web browser, use
npm install mr@~0.13.3 --save-dev
and use the following HTML test scaffold.
<!-- test/index.html -->
The page under test will be blank. You can use this space as a stage for your tests. The test runner reports directly to your web inspector console. It will change the background color to grey while tests are running, red when the first test fails, or green if all tests complete without any failures.
To get test coverage measurements, use
npm install istanbul@~0.2.4 --save-dev
npm install opener --save-dev and add a script to your
This will cause
npm run cover to run coverage and display the results.
Jasminum supports asynchronous tests that either use a
done callback or
return a promise.
describe"an asynchronous task"it"waits for one second using done"setTimeoutdone 1000;;it"waits for one second using a promise"return Qdelay1000;;;
If a test returns a promise, it is expected to be fulfilled with
Jasminum does not support
The Collections library establishes foundations that Jasminum employs for
comparing values, particularly polymorphic
Object.has operators, as well as the non-polymorphic
These do not behave exactly the same way as Jasmine, but are designed with
extensibility in mind both within and beyond testing. Partcularly, “any” objects
simply override their “equals” method to recognize any object of the same type
“The scare quotes will come off when I say they come off.” — Math
Jasminum supports an “isomorphic” test runner. The following test can be run in
// test/index.jsvar Suite = require"jasminum";var suite = "Q"describerequire"./q";require"./eta";require"./traces";require"./never-again";require"./node";require"./queue";;suiterunAndReportdone;
It can also be run with Mr with no modification.
<!-- test/index.html -->
The default test reporter for Node.js and for browsers are designed with
debugging in mind. Either way, all results are reported to the console as they
are executed. The scaffold logs messages between tests to assist in isolating
problems. Jasminum does not use clever techniques to capture or interfere with
standard output and console messages. In the browser, the inspected window is
left as a stage for the application under test and the test runner will only
fiddle with the
fail classes of the
In addition to
it, Jasmine and Jasminum both supportxdescribe
to quickly or temporarily disable a test. In addition, Jasminum [supports][iidd]ddescribe
andiit` that will cause the test runner to focus
on the annotated suites or tests.
Jasminum only runs in CommonJS module loaders.
Jasminum will not include a mock clock. Please seek refuge in
Jasminum does not attempt to capture errors in the “domain” of a test. Promises will usually funnel exceptions into the test scaffold, but if you throw an error from a timeout event, or any other kind of event, Jasminum will stop exactly where the problem occurred.
Jasminum does not redirect standard IO or console messages to the test reporter. Jasminum instead elects to direct its reports to the console and standard IO so that it interleaves the chronology of your program.
Jasminum only provides reporters for Node.js and console browsing.
Jasminum does not automatically run tests whenever tests or their dependencies change, but such a contraption is easy to imagine based on the dependency graph that Mr can produce.
Jasminum provides Jasmine 1.3 spies to ease migration. However, please migrate to an external spy package like Sinon for spies. Jasmine spies will be removed in a future release.
Jasminum compensates for its minimalism with extensibility.
By way of background, the DSL provides a few extra methods.
returns the suite instance for the containing
describe block, both at
declaration time and at test time.
getCurrentTest returns the current test
instances at test time, and
getCurrentReport returns the current report at
test time. There is no current test or report at declaration time.
Jasminum also supports corresponding
set methods, but these are intended only
for the use of the test runner.
Jasminum expectations can be extended in a variety of ways.
The current suite will always have an
Expectation property, that the suite
will use to construct expectation instances when the test calls
nested suite, in a
describe block, will have a prototypically inherited child
of the parent
Expectation constructor to isolate any extensions to the
The simplest is to provide overrides for existing expectation methods. Any
object can implement
compare, which will affect the behavior of
Look into Montage Collections for details about these generic methods.
You can create custom expectation constructors. The Jasminum
constructor provides an
assert method that makes most expectations
implementable with a single call to this utility method. It handles the case
where the expectation has been negated and gives the reporter great flexibility
in rendering the involved objects and negating the messages.
Expectationcallthis value report;// Also sets up the .not.isNot = true, .not.not = this stuff;ObjectcreateExpectationprototype;FunnyExpectation;var isFunny = thisvalueisFunny;this.assertisFunny "expected" "[not] to be funny" thisvalue;;
Any value can implement
expect(report) and return a custom expectation for
expect(value) will delegate to
and return your custom expectation object. This is best illustrated by the
spy-expectation modules which use this facility to provide special methods
thisfunny = funny;thisscary = scary;return this report;;
Also, every suite has a specialized copy of the
Expectation type from its
parent suite. Methods can be added to the
Expectation.prototype or the
Expectation constructor can be replaced outright and the change will only
apply in the current scope.
var Expectation = require"jasminum/expectation";describe"funny objects"getCurrentSuiteExpectation = FunnyExpecation;it"are funny"expecttoBeFunny;expectnottoBeFunny;;;
Jasminum provides a console reporter that is suitable for tests run by Node.js, or tests run through PhantomJS and forwarded to the Node.js console. It also provides a reporter suitable for running tests in an arbitrary browser, reporting results to the browser console.
However, tests can be run with an arbitrary reporter. The Suite
runAndReportSync methods both accept an
options object which may include
Reporter constructor. If neither are provided, it falls
back to calling the
Reporter on its prototype chain, so Suites can be extended
to have an alternate default reporter. The Suite shares the run-and-report
options with the reporter constructor.
The Reporter must implement:
start(test) -> reporter: returns a nested reporter instance for the given test.
end(test): concludes a test. This is a good point to check whether any assertions have failed and to calculate and propagate the test’s statistics.
skip(test): notes that the test has been skipped.
endwill still be called.
error(error, test): notes that an error was thrown while running the test, albeit in a promise handler.
endwill still be called.
assert(guard, isNot, messages, objects): reports on an assertion.
The guard may be a truthy or falsy value, but will be either exactly
isNot indicates that the assertion is negative, so the
the opposite meaning, and if any of the
messages contain the phrase
" [not]", these must be replaced with
" not". Otherwise, these phrases must be
replaced with an empty string. The objects are intended to be interleaved after
the corresponding message and there may be more messages than objects, or more
objects than messages.
The Reporter may implement:
The suite runner will call
enter once before running tests, and
after running all tests. If the tests are exiting prematurely, the
flag will be true, in which case, it would be innapropriate to call
process.exit because doing so would prevent Node.js from printing an uncaught
exception to the console.
Suite constructor can be extended. The
Suite is not hard-coded to use
Reporter constructors. Specialized
expectations and tests can be overridden on the
Jasminum provides a
reporter module with an alternate
implementation that will be used in place of
reporter automatically if it is
loaded by Browserify, Mr, or Mop.