Stubbornly, I continue tonight trying to get started with testing my fab.js application. I found out last night that there is no easy way to run the fab.js test suite (and a @fabjs tweet this morning confirmed it). Still, I need to be able to test if I am going to seriously use fab.js.
Last night was not a complete waste. I did learn a thing or two about fab.js test strategies. I think that I will start with them tonight. I create my own
test.js
test suite and pull in the commonjs assert
and puts
(print):#!/usr/bin/env nodeI then manually copy in the contents of fab.js's utils/test.js and pull in a function from my (fab) game to test:
var assert = require("assert")
, puts = require( "sys" ).puts;
#!/usr/bin/env nodeIn
var assert = require("assert")
, puts = require( "sys" ).puts;
// utils/test.js from fab.js
var target_module = require('./lib/player_from_querystring');
test(target_module);
lib/player_from_querystring.js
, I paste the contents of the function that I wrote by hand last week to add a new player to the fab.js game and export it (using the commonjs exports
):function player_from_querystring() {To use that in the test framework, this library also needs to export a list of tests. For now, I just want to test that this is a unary app (which it is by virtue of receiving no arguments:
var out = this;
return function(head) {
if (head.url.search) {
var search = head.url.search.substring(1);
var q = require('querystring').parse(search);
var app = out({ body: {id: q.player, x: q.x || 0, y: q.y || 0} });
if ( app ) app();
}
else {
out();
}
};
}
exports.app = player_from_querystring;
exports.tests = ( function() {When I run the test framework, however, I get:
var app = player_from_querystring( );
return [
function
statusReturnsUnaryApp() {
this( app.length === 1 );
}
];
});
cstrom@whitefall:~/repos/my_fab_game$ node ./test.jsHrm... I thought the tests being exported returned a list of things to test. What gives?
Running 0 tests...
TypeError: Object function () {
var app = player_from_querystring( );
return [
function
statusReturnsUnaryApp() {
this( app.length === 1 );
}
];
} has no method 'forEach'
at test (/home/cstrom/repos/my_fab_game/test.js:13:15)
at Object.<anonymous> (/home/cstrom/repos/my_fab_game/test.js:33:1)
at Module._compile (node.js:639:23)
at node.js:667:20
at fs:52:23
at node.js:748:9
Ah, I am assigning
exports.tests
to a function, not the return value of that function. For the lack of an empty parens, my test fail. Adding the parens evaluates that function, returning the list of tests:exports.tests = ( function() {With that, I get my first fab.js test to pass:
var app = player_from_querystring( );
return [
function
statusReturnsUnaryApp() {
this( app.length === 1 );
}
];
})();
cstrom@whitefall:~/repos/my_fab_game$ node ./test.jsIt is not much. But it is a start. Up tomorrow, a retrospective (and B'more on Rails opensource hack night!). After that, perhaps more work with this or moving onto testing some of this with Cucumber.
Running 1 tests...
statusReturnsUnaryApp: true
Done. 1 passed, 0 failed.
Day #113
Oh, that's how to run the tests. Thanks for digging into this Chris, your articles and a lot of trial and error have helped me get a better grasp on fabjs. I wish fabjs had a little better documentation, but I also realize the fab team is busy doing a rewrite for v0.5.
ReplyDeleteI hope to get some time later on in the week to get vowsjs working fabjs.
Thanks,
Graeme
Glad it could help :)
ReplyDeleteI'm not sure if fab.js needs more documentation or if I need to understand JS apply/call semantics better. When I'm struggling most, it feels like the latter.
BTW what is vowsjs? Google doesn't seem to know and now I'm curious :)
-Chris
Hey Chris -
ReplyDeleteI agree that fabjs is pushing my javascript understanding to a higher level. vowsjs is a async BDD testing framework for node:
http://github.com/cloudhead/vows
I haven't a chance to play with it yet, trying to limit myself to one new framework at a time ;)
~ graeme