Thursday, May 31, 2012
Geta
Geta
© 2010 Darren DeRidder. Originally uploaded by soto voce
Sandals for guests in the entryway of a ryokan. Kinosaki, Japan.
Wednesday, May 23, 2012
A Simple Introduction to Behavior Driven Development in NodeJS with Mocha
I recently had a chance to use the Mocha test framework for NodeJS on a large-ish project and wanted to provide a really simple introduction to it. Mocha is a unit testing framework for NodeJS apps from TJ Holowaychuk. As the successor to the popular Expresso test framework, it adds a number of new features. It supports both Test-Driven and Behavior-Driven development styles and can report test results in a variety of formats.
Mocha can be installed easily using npm. Assuming you have node and npm installed, you can install mocha as a global module using the -g flag to it will be available everywhere on the system.
or perhaps
or, if you prefer a local install instead of a global install
npm install mocha
export PATH=./node_modules/.bin:$PATH
You're also going to want should.js, which you can install in your local project folder.
Mocha, in addition to being a test framework, is a command-line utility that you run when you want to test things. You should be able to type `mocha -h` on the command line now and get some usage info.
Before we can use mocha to test stuff we should have a little bit of code to test. I'm going to borrow from Attila Domokos' blog http://www.adomokos.com/2012/01/javascript-testing-with-mocha.html but try to simplify it just a bit. We're going to create two files in two different directories:
dog.js is our source code that we want to test. Normally this would be a module that you have written. Since this is a super-simple introduction, it just exports one function called "speak". We can use this to invoke the "speak" method, which will return "woof!".
Now we can write something to test our code: dog_test.js. Remember this file goes under the test/ directory and dog.js is under the src/ directory. So here is how we would write a test case for Dog.
var dog = require(__dirname + "/../src/dog");
describe('dog', function() {
it('should be able to speak', function() {
var doggysound = dog.speak();
doggysound.should.equal('woof!');
});
});
Now there should be a src/ and a test/ directory with these two files in them.
src/dog.js
test/dog_test.js
Mocha will automatically run every .js file under the test/ directory. To run the tests you can simple type 'mocha' on the command line:
and it should give you the following output:
or if you want a little more detail use:
and it should give you this output:
✓ Dog should be able to speak: 0ms
✔ 1 test complete (2ms)
Mocha can generate several different styles of test reports. To see a list of the types of reports it can generate, type mocha --reporters.
Let's take a quick look at the test case definition. A group of tests starts with "describe". You provide some title for the thing you're testing. You can choose whatever title you want, but it should be descriptive. Our test suite is called 'dog'.
describe("dog", function () {
// your test cases go in here
}
You can describe more than one group of tests in the file.
describe("dog", function () {
// your doggy tests
}
describe("puppy", function () {
// your puppy tests
}
Test descriptions can be nested, which is often convenient.
describe("dog", function () {
describe("old tricks", function () {
// your old doggy tricks
}
describe("new tricks", function () {
// your new doggy tricks
}
}
Individual tests themselves start out like "it('should do such-and-so...". You can give the test whatever description you want, but generally you give it a brief explanation of what it should or shouldn't do. If you added more methods to Dog, you would add more tests within the "Dog" test description to test them.
describe("dog", function () {
it('should be able to speak', function () {
// the body of the speak test goes here
}
it('should be able to wag its tail', function () {
// the body of the wag test goes here
}
}
Our examples use should.js for writing test cases in Behavior Driven Development style. Should.js provides a bunch of cool assertions like foo.should.be.above(10) or baz.should.include('bar'), and so on. Check out the documentation for should.js here: https://github.com/visionmedia/should.js
it('should be able to speak', function () {
var doggysound = dog.speak();
doggysound.should.equal('woof!');
}
it('should be able to wag its tail', function () {
var wags = dog.wag(5);
wags.should.be.above(4)
}
These examples show an asynchronous testing approach. It's quite easy to run your tests in a synchronous way, though, by using the "done" callback which Mocha provides.
it('should be able to speak', function (done) {
var doggysound = dog.speak();
doggysound.should.equal('woof!');
done();
}
Using the "done" callback means the test will complete before moving on to the next one.
For a slightly more advanced tutorial check out http://dailyjs.com/2011/12/08/mocha/. It has some great tips about setting up a package.json and Makefile to help with test automation, as well as writing synchronous and asynchronous tests.
Mocha can be installed easily using npm. Assuming you have node and npm installed, you can install mocha as a global module using the -g flag to it will be available everywhere on the system.
npm -g install mocha
or perhaps
sudo npm -g install mocha
or, if you prefer a local install instead of a global install
npm install mocha
export PATH=./node_modules/.bin:$PATH
You're also going to want should.js, which you can install in your local project folder.
npm install should
Mocha, in addition to being a test framework, is a command-line utility that you run when you want to test things. You should be able to type `mocha -h` on the command line now and get some usage info.
Example
src/dog.js
test/dog_test.js
dog.js is our source code that we want to test. Normally this would be a module that you have written. Since this is a super-simple introduction, it just exports one function called "speak". We can use this to invoke the "speak" method, which will return "woof!".
// dog.js
function speak() {
return 'woof!';
}
exports.speak = speak;
function speak() {
return 'woof!';
}
exports.speak = speak;
Now we can write something to test our code: dog_test.js. Remember this file goes under the test/ directory and dog.js is under the src/ directory. So here is how we would write a test case for Dog.
// dog_test.js
var should = require('should'); var dog = require(__dirname + "/../src/dog");
describe('dog', function() {
it('should be able to speak', function() {
var doggysound = dog.speak();
doggysound.should.equal('woof!');
});
});
Now there should be a src/ and a test/ directory with these two files in them.
src/dog.js
test/dog_test.js
Mocha will automatically run every .js file under the test/ directory. To run the tests you can simple type 'mocha' on the command line:
mocha
and it should give you the following output:
✔ 1 test complete (3ms)
or if you want a little more detail use:
mocha -R list
and it should give you this output:
✓ Dog should be able to speak: 0ms
✔ 1 test complete (2ms)
Mocha can generate several different styles of test reports. To see a list of the types of reports it can generate, type mocha --reporters.
Explanation
Let's take a quick look at the test case definition. A group of tests starts with "describe". You provide some title for the thing you're testing. You can choose whatever title you want, but it should be descriptive. Our test suite is called 'dog'.
describe("dog", function () {
// your test cases go in here
}
You can describe more than one group of tests in the file.
describe("dog", function () {
// your doggy tests
}
describe("puppy", function () {
// your puppy tests
}
Test descriptions can be nested, which is often convenient.
describe("dog", function () {
describe("old tricks", function () {
// your old doggy tricks
}
describe("new tricks", function () {
// your new doggy tricks
}
}
Individual tests themselves start out like "it('should do such-and-so...". You can give the test whatever description you want, but generally you give it a brief explanation of what it should or shouldn't do. If you added more methods to Dog, you would add more tests within the "Dog" test description to test them.
describe("dog", function () {
it('should be able to speak', function () {
// the body of the speak test goes here
}
it('should be able to wag its tail', function () {
// the body of the wag test goes here
}
}
Our examples use should.js for writing test cases in Behavior Driven Development style. Should.js provides a bunch of cool assertions like foo.should.be.above(10) or baz.should.include('bar'), and so on. Check out the documentation for should.js here: https://github.com/visionmedia/should.js
it('should be able to speak', function () {
var doggysound = dog.speak();
doggysound.should.equal('woof!');
}
it('should be able to wag its tail', function () {
var wags = dog.wag(5);
wags.should.be.above(4)
}
Synch and Asynch Tests
These examples show an asynchronous testing approach. It's quite easy to run your tests in a synchronous way, though, by using the "done" callback which Mocha provides.
it('should be able to speak', function (done) {
var doggysound = dog.speak();
doggysound.should.equal('woof!');
done();
}
Using the "done" callback means the test will complete before moving on to the next one.
For a slightly more advanced tutorial check out http://dailyjs.com/2011/12/08/mocha/. It has some great tips about setting up a package.json and Makefile to help with test automation, as well as writing synchronous and asynchronous tests.
Subscribe to:
Posts (Atom)
Productivity and Note-taking
I told a friend of mine that I wasn't really happy with the amount of time that gets taken up by Slack and "communication and sched...
-
Update : Here are slides for this talk at OttawaJS: " Node.JS Module Patterns Using Simple Examples ". Update 2 : More Node.JS M...
-
tldr; https://github.com/73rhodes/sideflow This extension provides goto, gotoIf and while loop functionality in Selenium IDE. Selenium ...
-
Other articles in this series: REST API Best Practices: A REST Cheat Sheet REST API Best Practices: HTTP and CRUD REST API Best Practice...