This package has been deprecated

    Author message:

    Sorry folks, no time to maintain this good old friend


    0.3.0 • Public • Published

    wru :: JavaScript tests have never been that easy

    wru is an essential general purpose test framework compatible with web environment, node.js, Rhino, and now PhantomJS too.


    • runs in both client and server environments, compatible with html files, node.js, Rhino, PhantomJS, and JavaScriptCore.
    • both synchronous and asynchronous tests in an absolutely intuitive way
    • ES5 and ready, compatible with "use strict" directive which means no with statements, eval, or misused this references
    • easy, probably the easiest way to test JS code out there thanks to its simplified API: test, assert, async, and log ... you already remember "all of them", isn't it?
    • unobtrusive and self defensive, since everything that could possibly change in such dynamic environment as JS is, is "sandboxed" inside the wru closure. This means no matter how "nasty" your code is, wru won't pollute or change the global environment, neither it will rely in native constructor.prototypes changes (Array.prototype.push = ... or Object.prototype.hasOwnProperty = ...? not a problem!)
    • cursor included in both web and console ... you gonna realize how much "THE CURSOR" is important, specially to understand if your test is stuck or simply "waiting for" ... cursor is working in both Unix and OSX consoles (unfortunately PhantomJS does not support the cursor while jsc does not support timers at all)
    • tiny, even if it's not important in tests world, wru fits into about 2Kb (1.2Kb minzpped) which means not much to fix or change here, just a simple, reliable, and essential framework for your tests
    • under your control, since there is absolutely no magic behind the wru scene. You assert what you want, you async what you need, you describe what's needed, and you are ready to go in less than 5 minutes

    If you can't believe it check html, node.js, Rhino, or PhantomJS test and see how wru does work ;-)


    wru is compatible with basically all possible browsers out there included IE5.5, IE6, IE7, IE8, IE9, IE10, Chrome, Firefox, Safari, Webkit based, Mobile Browsers, and Opera.

    On server side wru is compatible with latest node.js, Rhino, PhantomJS, and JavaScriptCore versions. I swear if I find an easy way to easily test Spider/Iron/JagerMonkey I will support them too.

    how to test wru

    The simplest way to test wru is to use template.html for web tests or template.js for node, rhino, and jsc tests or template.phantom.js for PhantomJS tests.

    With these 3 options you don't even need to fork or download the entire repository ... but if you do that ...

    From wru root directory, simply run these commands accordingly with what you want to test:

    // node.js test
    node test/test.js
    // Rhino
    java -jar builder/jar/js.jar test/test.js
    // PhantomJS test
    phantomjs test/phantom.js
    // JavaScriptCore test
    jsc test/test.js
    // web (through Mac OSX but you can open test.html with any browser)
    open test/test.html

    PhantomJS supports tests for both plain JavaScript in a blank page, or any url adding it as argument.

    // PhantomJS test on about:blank
    phantomjs build/template.phantom.js
    // PhantomJS test on any url
    phantomjs build/template.phantom.js ""

    PhantomJS tests should always starts when the DOM has been already parsed.

    JavaScriptCore does not implement (yet) setTimeout and setInterval so it's not possible to test via async() calls.

    If you forked the project, you made some change, and you want to rebuild wru, this is all you have to do:

    // still inside wru folder
    python builder/
    // or now with node
    node builder/build.js

    After the build process is finished, no more than 3 seconds with forced waiting time included to read stats if build has been double-clicked, you should be able to run again the test for your own environment.

    Please bear in mind JSbuilder.(js|py) works with node-js 0.4+ or Python < 3 (2.6 or 2.7 are fine) so be sure you have it (you should by default on Mac or Linux).

    wru basics

    // probably all you need as "one shot" test
        name: "Hello wru!",
        test: function () {
            wru.assert("it works!", 1);
    // for multiple tests ... pass an Array
        name: "test #1",
        setup: function () {
            // setup before the test
        test: function () {
            // async test example
            setTimeout(wru.async(function () {
                wru.assert("executed", true);
            }), 1000);
        teardown: function () {
            // clean up after the test
        name: "test #2",
        test: function () {
            // do other stuf here

    To know more about wru possibilities ... please keep reading ;-)

    wru API

    There are truly few things you need to know, and even less properties you need to configure!


    • test(object) or test([object, ..., object]) to execute one or more tests. A generic test object may have one or more properties:
      • test property, as function, to execute the test with one or more wru.assert() or wru.async() calls. optional but recommended
      • name or description property, as string, to have visual knowledge of the current test optional
      • setup property, as function, that will be executed right before the test: optional
      • teardown property, as function, that will be executed right after the test: optopnal
    • assert("description", truishOrFalsyValue) to manually assert whatever you want where description is optional (but suggested) and the assertion is compatible with truish or falsy values. You are in charge of strictly compared results if necessary by === operator, nothing new to learn here
    • async("description", callback, timeout) to tell wru that a test will be executed at some point later and where both description and timeout are optionals
    • log(anything, forceFallback) the equivalent of console.log(obj) where supported, the equivalent of alert() or print() if the forceFallback flag is set to true (or better, truish)


    • random, as true or false, to make tests order execution random (by default false)
    • node on web version only to set a different node from the default one (which is an element with id == "wru"or the document.body or the document.documentElement if body is not present yet)

    test properties

    Each test can be either an object or, if you are that lazy typer, a function.

    • name as test title or test name, if the test is a function the function name (expression or declared) will be used where available, anonymous otherwise.
    • setup as function to do something before the test is executed. Bear in mind every test will receive a freshly baked object as argument, from setup, to test, and teardown, the same object. Use it if you need.
    • test as function to execute if the test is not a function itself. Receives the shared object per test as first argument.
    • teardown as function to do something after the test is executed. Receives the same shared object setup and test receive as argument.

    how does wru work

    following a list of explained tasks that are possible with wru

    synchronous tests and wru.assert()

    Every test may have one or more wru.assert() calls inside. The method itself accepts one or two arguments. Following a sequence of valid operations.

    // the test object ...
        name: "existance test",
        test: function () {
            // example only: if next property is not
            // null, undefined, 0, false, "", or NaN
            // the assertion will pass the test
            wru.assert("callback exists", window.onload);
            // if necessary, assertion can be strict without problems
                "it is a callback",
                typeof window.onload === "function"
            // the description is visually useful
            // if the test fails but it's not mandatory
            // next example is still valid, no description
            wru.assert("isArray" in Array);
            // if a condition supposes to be truish
            // wru.assert can make test life easier
            // returning the asserted value
            if (wru.assert("defineProperty" in Object)) {
                    Object.defineProperty({}, "_", {value: true})._

    asynchronous tests and wru.async()

    Every test is performed synchronously unless there is one or more wru.async() calls. In latter case all tests after the current one will be waiting for the asynchronous call to be executed. When it happens, if the asynchronous call performed one or more assertions, the framework keep going without requiring any extra step: is that easy!

    // the test object ...
        name: "load content",
        test: function () {
            // asynchronous test example
            // this will be synchronous
            wru.assert("condition accepted", true);
            // this will be asynchronous
            var xhr = new XMLHttpRequest;
  "get", "file.txt", true);
            xhr.onreadystatechange = wru.async(function () {
                if (this.readyState === 4) {
                    // only on readyState 4 there is an assertion
                    wru.assert("text is not empty", this.responseText.length);
                    // if necessary, async call can be nested
                    setTimeout(wru.async(function () {
                            "DOM changed in the meanwhile",
                            docment.body.innerHTML != storedLayout
                    }, 500));
            // this will be performed regardless
            wru.assert("something else to check", 1);

    In above example, the onreadystatechange function may be executed many times on different readyState. The wru logic cannot care less about it since an asynchronous callback is considered done when at least one assertion has been performed. If this does not happen the internal TIMEOUT constant, by default 10 seconds, will kill the procedure. You have to admit there is no reason to create an asynchronous test without performing some assertion inside the callback ... and this is where wru is smart. If many assertions have been defined and one of them is not reached is most likely because there was an error or a failure in the test. wru tracks all tests without problems so forget things such lib.expectedAssertions(3) and "friends" ... you really may not need that!

    the temporary object

    If needed, every setup, test, or teardown function will receive a "freshly new backed" object for the current test. This can be handy to store some reference or value on setup, use them during the test, and drop them during the teardown if necessary.

    // the test object ...
        name: "tmp object all over",
        setup: function (tmp) {
   = window;
   = Math.random();
        test: function (tmp) {
       === window // true
                typeof == "number" // true again
        teardown: function (tmp) {

    the build process

    wru is based on javascript-builder which is able to aggregate distributed files in order to produce the final library/framework even if the source/JS logic is split in more files.

    This is the wru case, where some file is dedicated for web environment rather than console/shell one. If you fork the project and you make some change/improvement, first of all let me know :-), secondly remember to re-build the script. This is the list of files actually created by wru build process inside the build folder:

    • wru.console.max.js is the full script console/shell related, suitable for node.js or rhino tests
    • wru.console.js is the minified version of the precedent one with wru.debug() stripped out
    • wru.dom.js is the full script DOM related, suitable for web and browsers
    • wru.min.js is the minified version of the precedent one with wru.debug() stripped out

    wru.debug() is a method used to export, track, test, or change internals. You should never use this method unless strictly necessary but it's there for debugging purpose. wru.debug() is automatically removed from built versions so that no evaluation of internals can be possible.

    If you want to have an overall view of the framework check already built output since if not familiar with this build process it may be hard at the beginning.

    This is the HTML version, and this is the console one, you will notice things make sense there since the order is specified in the file.

    Please remember all you have to do to build wru is this call in the wru project root

    python builder/

    wru against others

    Other tests frameworks may offer more than what wru does but this rarely comes for free. Some of them may have such complicated/articulated logic that it may happens is the test framework itself that's failing rather than your code. Also you need to read a lot of documentation and most likely to obtain something already possible with wru. I am not saying wru is the best test framework out there, I am just saying you should consider your requirements before you chose a test framework ;-) In any case, wru aim is to make any sort of test simplified and under control.

    As example: "do you really need so much 'magic' to perform these tasks?"

    // rather than specify expected arguments
    // via magic/complicated operations
    function (a, b, c) {
        wru.assert("received numbers",
            typeof a == "number"
            typeof b == "number"
            typeof c == "number"
    // rather than specify returned values
    // via magic/complicated operations
    wru.assert(typeof callbac() != "undefined");
    // did you know the console object
    // may have already an assert() method
    // since that's basically all you need?
        "if true, I can get rid of wru since all I need is 'assert'",
        "assert" in console
    // the only reason wru may be handy is the
    // cross platform/environment compatibility
    // and its async method interlaced with
    // current environment layout (HTML or shell/console/bash)
    wru.assert("oh come on but this is so easy!", 1);

    Just give it a try ;-)

    HTML VS console

    wru core functionality is exactly the same in both environments ... it cannot be easier to maintain, imo. However, there are few substantial differences between HTML results and those shown in the console

    HTML tests

    • based on classes, easily to customize via CSS
    • differential colors accordingly with test results: green if successful, red if failed, black if cryptical (e.g. unmanaged exceptions)
    • failures or errors are not shown by default, one click to see the list of problems in any of those non green tests
    • summary on top, no need to scroll 'till the end of the document to understand how it was. A nice summary with all passed, failed, or unmanaged errors test is shown on top

    console tests

    • based on stdout
    • differential prefixes accordingly with test results: [OK] if successful, [FAILURE] if failed, [ERROR] if cryptical (e.g. unmanaged exceptions)
    • failures and errors are always listed in the output
    • summary always at the end of the test

    I need a setup per each test!

    Sure you do :-)

    // just create a simple wrapper before your tests
    // to fully automate the procedure
    wru.test = (function (test) {
        // we got a closure here, do whaveter you want!
        function whateverSetupIsNeeded(tmp) {
            // do setup stuff
        return function (testObjects) {
            // be sure it's an array, convert otherwise
            testObjects = [].conca(testObjects);
            // per each object
            for (var
                // reassign the setup if present
                reassign = function (setup) {
                    testObjects[i].setup = function (tmp) {
                        setup && setup(tmp);
                i = testObjects.length; i--;
            // invoke wru.test() which is self bound
            // that's pretty much it

    Similar technique if you need same teardown call per each test.

    I need other edge cases too !

    The cool part is that being simple, wru is also highly customizable. Please keep an eye in the solutions.html file. I will try to update it as soon as some request or edge case comes up.

    wrap it if you want

    If you think wru is too simple, you still have a chance to improve it wrapping its basic methods and create something wonderful out of it. Arguments automations? Returned values? Expected number of calls per callback?

    The wru cross environment core is easy to hack for anybody, check wru.js and your are already half way through ;-)


    wru general purpose test framework and the rest of the project is under Mit Style License

    Copyright (C) 2011 by Andrea Giammarchi, @WebReflection
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.

    OT: some fun during wru development

    If you check the built source you will realize that a wru.test() lifecycle is between a call to internal isGonnaBeLegen() function, passing through the waitForIt variable if some asynchronous call has been required, and ending up into the Dary() callback.

    I know you don't care but at least now you know how is the wru.test() lifecycle :{D


    npm i wru

    DownloadsWeekly Downloads






    Last publish


    • webreflection