"
All the world's a stage,
And all the men and women merely players;
They have their exits and their entrances,
And one man in his time plays many parts"
-- Shakespeare, As You Like It
Act II, Scene VII, Lines 140.2 - 143
Prelude
Places, places, the show is about to begin. Javascript has hit the big time! Javascript has gone from a way to annoy, to a full blown language and we have
Node.js to thank (well maybe AJAX, but Node.js helped pushed me over the edge). If you are like me, you had written off Javascript as an annoyance that Web Programmers had to deal with, but now thanks to Node.js we can all find a use for Javascript.
Now do not get me wrong Javascript has more than its fair share of bad parts, but the more I use it, the more I like it. It has just enough of functional elements to make me happy and yet it has enough object oriented elements to allow for any C#, Java, or Ruby programmer to feel at home. Plus Node.js' package management system (npm) is simply wonderful.
Installing Node.js
To install Node.js head over to
http://www.nodejs.org/ and install the correct installation for your system.
I just stuck with the default install options and have had no problems.
Hello World
The default installation gave me a Node.js folder on my start menu, launch the Node.js command prompt.
This will bring up a command prompt.
Run Node.js by typing,
node at the prompt. This will bring up a REPL (
read evaluate print loop), you can use the REPL to try things out. I normally have a REPL open along with a
mocha --watch when I am programming with Node.js.
To write a Hello World in Node.js simply enter
console.log("Hello World!); on the REPL. Boom, you now have done Hello World using Node.js!
Hit Ctrl+c twice to exit. O-if you are wondering, the
undefined you see after
Hello World! is the value of the result of the call to
console.log.
TDD using Mocha
With Hello World out of the way, we can legally do something more interesting. Lets download
Mocha, which is the best testing framework I've found for working with Node.js. To download and install Mocha use the Node package by running the Node Package Manager you installed when you installed Node.js by running the following at the command prompt:
npm install -g mocha
npm install -g mocha, will download and install globally (that is what the -g means) the Mocha testing framework.
Mocha is a testing framework which allows for either the
should BDD style or the assert Unit test style, personally I am starting to prefer the BDD style, but to each their own.
Let's create our first Node.js project!
In order for Mocha to be able to work you
need a test directory. Personally I like this structure for my Node.js projects.
Nothing that I know of will force you to have a src directory, but I find it cleaner to have it (maybe because I am an old Java programmer). Let's make the project structure, run the follow commands (assuming you are using Windows or an Unix based machine (I believe this will work on a Mac)):
mkdir kata
cd kata
mkdir helloer
cd helloer
mkdir src
mkdir test
This will give you a kata directory and your first kata helloer.
Fire up your favorite text editor, I have really taken to
Sublime Text lately, so that is what I will be using.
In the src directory create a file called
helloer.js leave it empty for now. In the test directory we'll create a file called helloerSpec.js with the following line of code.
var sut = require("../src/helloer");
This line will create a variable called
sut (system under test) which will use to test the helloer code. Not the syntax on the require, you need to use a
.. to say go down a directory and the
/src/helloer says where to find the helloer functions.
Let's run this with Mocha from the command prompt type mocha
You should see output like the following (if not you may have the directory structure different than what I have or you have something typed wrong).
Now let's actually do something!
First add should to your system by using the following in the helloer directory:
npm install should
This will install the should module which we'll us in our test file.
In the helloerSpec.js file add the following and save:
var sut = require("../src/helloer"),
should = require("should");
describe("helloer will say hello to whatever you pass in", function(){
it("Nothing will just say hello", function(){
sut.helloer().should.equal("Hello ");
});
});
The
describe is a high level grouping for our tests, the
it is our test case, in this case we are saying we want a function that when given nothing will produce the string "Hello ".
From the command line run mocha --watch
This will start a continuous testing environment (if this is your first time using one, it will change the way you write your code).
Congratulations you have your first failing test in a continuous testing environment with Mocha! Now let's make the failing test pass.
Add the following lines to the helloer.js file to get the failing test to pass.
var helloer = function(){
return "Hello ";
};
exports.helloer = helloer;
As soon as you save the continuous testing environment with Mocha will pick up on the changes and rerun the tests.
The
exports gives a list of things (variables, functions, objects, ...) to expose. In this case we are exposing helloer, note that the name on
exports is will the caller sees not the local name.
When I do TDD I like to use as little amount of code as I can to get the test to pass (like playing golf). I find that this leads to better code. As the old saying goes, the code that you
do not write has zero bugs.
Let's write our next failing test.
We'll say hello to Mike using the following code (in
bold) to our helloerSpec.js file:
var sut = require("../src/helloer"),
should = require("should");
describe("helloer will say hello to whatever you pass in", function(){
it("Nothing will just say hello", function(){
sut.helloer().should.equal("Hello ");
});
it("Given Mike, hello will hello Mike", function(){
sut.helloer("Mike").should.equal("Hello Mike");
});
});
Mocha will tells us that we have one failing test and that it is failing because it is receiving "Hello " and is expecting "Hello Mike".
Let's make this pass.
Add the following (in
bold) to helloer.js:
var helloer = function(name){
return "Hello " + (name ? name : "");
};
exports.helloer = helloer;
The line (name ? name : "") may seem odd, but remember in Javascript the string value of undefined is "undefined" when found on the other side of a concatenation (+ with two strings), yeah odd.
Well, believe it or not we are done, but let's add in some more tests to make sure.
var sut = require("../src/helloer"),
should = require("should");
describe("helloer will say hello to whatever you pass in", function(){
it("Nothing will just say hello", function(){
sut.helloer().should.equal("Hello ");
});
it("Given Mike, hello will hello Mike", function(){
sut.helloer("Mike").should.equal("Hello Mike");
});
it("Given 5, hello will hello 5", function(){
sut.helloer(5).should.equal("Hello 5");
});
});
Congratulations, we have just finished some TDD with Node.js and Mocha.
In case you missed it, full files
src\helloer.js
var helloer = function(name){
return "Hello " + (name ? name : "");
};
exports.helloer = helloer;
test\helloerSpec.js
var sut = require("../src/helloer"),
should = require("should");
describe("helloer will say hello to whatever you pass in", function(){
it("Nothing will just say hello", function(){
sut.helloer().should.equal("Hello ");
});
it("Given Mike, hello will hello Mike", function(){
sut.helloer("Mike").should.equal("Hello Mike");
});
it("Given 5, hello will hello 5", function(){
sut.helloer(5).should.equal("Hello 5");
});
});