My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.
Showing posts with label wru. Show all posts
Showing posts with label wru. Show all posts

Saturday, February 18, 2012

JavaScript Test Framewors: more than 30 + 1

After @szafranek hint and suggestion, wru landed almost at the end of this Wikipedia List of unit testing frameworks page.

If you use this tweet size hand made imperfect script in the wikipedia page console:

a=q="querySelectorAll",[].map.call(document[q](".mw-headline,.wikitable"),function(v,i){i%2?a=v.textContent:o[a]=v[q]("tr").length},o={}),o

You gonna see that JavaScript is third when it comes to number of test frameworks ... and not sure that's good, anyway, here a quick description of mine.

About wru

You can find most info in github page itself but essentially wru is a generic purpose, environment agnostic, JavaScript tests framework compatible with both client and server, where client means every bloody browser, and server means Rhino, node.js, and recently phantom.js too.
To be really fair, wru is not exactly a unit test framework since it does not provide by default anything related to mocks or stubs.
However, wru is so tiny and unobtrusive that any 3rd parts library could be integrated without effort in whatever test you want + need.

wru In A Nutshell

Well, the first thing to do with wru is to write code such:

wru.test([
{
name: "the test name, for feedback purpose",
setup: function (obj) {
// the OPTIONAL setup property performed before the test
// obj will be a freshly new created object
// with a single test lifecycle ... reusable within the test
},
test: function (obj) {
// obj comes from setup, if any
wru.assert(true); // a generic truish condition
setTimeout(wru.async(function () {
// a generic asynchronous condition
// where you will inevitably assert something
wru.assert("this is also true", true);
}), 1000);

// the handy possibility to reuse assert itself
if (wru.assert("this is a truish value", obj)) {
// do stuff with obj
// or simply log the object
wru.log(obj);
}
},
teardown: function (obj) {
// the OPTIONAL teardown property performed after the test
// obj comes from the test function, is the same
// passed through setup, if present, and test
}
}
]);

After this you are basically ready to go.
Both assert() and async() accept one up to two arguments: the optional description of the test, recommended if you want at least understand what's going on and where if something failed, and the second parameter which is returned in both cases.
Via assert() the condition/expression is evaluated as it is, truish or falsy, and returned if addressed.
Via async() the callback is wrapped in an unobtrusive way and this is simply to let wru know that something is going to happen, hopefully in a reasonable timeout of 10 seconds.

How To See Results

Once you have your test in place, you can re-use the same code all over supported environments.
The cool part about wru is that templates for all scenarios are automagically created at build time.
You don't even need to npm install wru to use the test, or include it in a page via script tag, you can simply grab a template and copy and paste or replace, during a build process, the test. This will make your life easier than any setup oriented test framework, isn't it?

Write Once, Run Everywhere

Isn't this the dream we all have about JavaScript in both browsers and server side environments? As far as I know wru is the only one that supports all these environments with a unified, cross platform, and easy to remember API. (until I have discovered JS Class via @jcoglan)
Main principles behind wru? KISS and YAGNI, so that everyone can start, at least, writing tests for what's needed, without any ulterior waste of time about environment, library dependency, or programming language setup.
And what if you want to test platform specific gotchas ? Oh well, you can still recycle the whole test and check the number of positive results, as expected, at the end ... well, not all the code we are writing should work cross platform, but even in this case, wru gonna make you familiar with tests and tests logic so it's a win win in any case.

Pluggable UT Libraries

You must admit the name of this framework is absolutely crap. I didn't even know how to call it in a manner that no other frameworks would have been affected, so I sticked with my blog initials, WebReflection, and the one out of Unit in it, until I introduced this tiny library in one of those amazing BerlinJS events where someone suggested Where Are You acronym, and I simply loved it ... uh wait, let's go back in the topic ...
Any external library able to mock or stub your code should be easy to integrate in a wru test without problems.
In this case you may need to include this library upfront via script tag, in the Web html template, or inside any server side related template through require() or some other mechanism.
For browsers, you may consider JSMock, as example, but others which aim is to provide mocks or stubs functionality should be all supported without problems.

About Asynchronous Logic

Let's face reality, asynchronous tests are created exclusively to test the condition after the asynchronous callback has been executed, and this is exactly the wru expectation, you call for async? you wait for async.
If you get how async work you'll realize that you don't have to expect() anything, simply do what your test should do and trigger the done() at the end.
This comes from one of the most appreciated asynchronous pattern out there, Promises, where you simply wait for a done() to be called.
wru does the same, except the equivalent of done() is assert() which is the trigger.
If you have truly complex asynchronous logic, here a common pattern you might find useful with wru.

wru.test([{
name: "async",
test: function () {
var expectation = wru.async(function (arg) {
wru.assert("everything went better than expected", arg === "OK");
});
// your whatever async logic you need
var xhr = new XMLHttpRequest;
xhr.onreadystatechange = function () {
// called multiple times during xhr lifecycle
if (xhr.readyState === 4) {
// async, inside async
doSomeStuffOutThere(xhr.responseText, function (e) {
expectation(e.result); // hopefully the string "OK"
});
}
};
}
}]);

in few words, you don't need to expect a thing since once you define a single asynchronous callback in your test logic, you can trigger it once everything has been tested and, if that will never happen, the timeout will automatically flag the test as failed.

wru Output

Things are kept simple in this case as well, with the happy exception for the cursor.
I mean, you don't really need to stare at it, but the cursor is a visual indication that everything is not just stuck, but it's simply waiting for things to happen, if ever.
A classic infinite loop or endless generator is able to freeze the lifecycle of our app, and only a visual feedback will be able to tell you the truth since any other method, specially in browsers where tests are showed only once executed, won't be able to give you a thing ... except a crash in the best case scenario.
The cursor may interfere with the normal output but, at least when it comes to server side tests, whatever external tool will be able to remove cursor noise in the log and analyze anything that happened during test execution, from green to red or black, providing you an instant feedback if something went wrong.

Improve As You Go

wru is not a universal answer to JS tests but hopefully a good start point or most likely everything you need if the project, and your tests, are not that complex.
Being that simple, the best thing about this library is that we could reproduce its API everywhere else in few lines of code, transforming, as example, your tests into another UT framework without much effort.
The fragmentation of JS tests out there is massive, so I don't really want to go deeper into this, just think that this library made asynchronous tests that easy, as well as normal synchronous one and without interferences, thanks to the chosen namespace, out there.
What else about wru ... well, give i a try :)

Thursday, October 20, 2011

My BerlinJS Slides

It was a great event today at @co_up in @berlinjs meet-up and here are my sides about wru which accordingly with today meeting means where are you, directly out of SMS syntax.

Enjoy ;)

Sunday, August 21, 2011

wru, unit tests have ever been that easy

Do you remember my good old wru project? It has been refactored, readapted for both client and server side environment such node.js and Rhino and, most important, it landed in github ;)

Please spend few minutes to read the documentation and you'll realize why I chose this title for this post.

Have fun with JavaScript Unit Tests!

Saturday, October 02, 2010

wru against wru: version 1 ready

This shot has been token on 13th September 1923, when W.H. Murphy demonstrated the efficiency of his bulletproof vest, the one that sold later to NY Police Department.

Above image has been historically used for different topics and the current one is "how much we trust what we sell".

Do You Trust Your UT Framework?

I wasn't kidding that much when I wrote about "test the testing framework" in my precedent wru post. The overall Unit Test Frameworks code coverage is poor, specially those with all the magic behind the scene, magic that does not come for free.

Use The Framework Itself To Test The Framework

This is a common technique that may result in a reliability deadlock. If we trust our UT Framework and we use it to test itself, the moment we have a problem with the framework we'll never know ... or even worst, it will be too late.

Don't Trust "Magic" Too Much

If the framework is simple and it does not pollute each test with any sort of crap, we can surely use it to test the framework itself without problems while if this framework elaborates and transforms our tests, it may become impossible to test it via the framework itself due scope and possibly context conflicts for each executed test.
This may produce a lot of false positives for something in place theoretically to make our code more robust.

The wru KISS approach

With or without async.js, wru does few things and now it's proved that it does these things properly. I don't want to spend any extra time for a library that I should trust 100% and if I know that all things this library should do are working as expected, I can simply "forget to maintain it" (improve, eventually) and use it feeling safer.

99.9% Of Code And Cases Coverage

Loaded on top of whatever test, wru uses few native calls and the assumption is that these are already working as expected (accordingly with ES3 or ES5 specs).
The new wru test against wru covers all possible tests combination, where setup and teardown could fail on wru itself or for each test, and assert should simply work in a test life-cycle. This means we could assert inside setups and teardowns as well, simply because these calls are fundamental for a single test and, if present, must be part of the test result. A problem in a setup could compromise the whole test while a problem in a teardown could compromise other tests. Being sure that nothing went wrong is up to us but, at least, we can do it via wru.

Can you do the same with your UT Framework? Do you have the same coverage? Have fun with wru ;)