nodespec v0.4.2
========
nodespec
http://glenjamin.github.com/nodespec
.. image:: https://secure.travis-ci.org/glenjamin/nodespec.png
A light-weight RSpec_-esque testing framework designed and built specifically for NodeJS.
.. _RSpec: http://relishapp.com/rspec
.. contents:: :local:
Features
Ground-up support for NodeJS convention callbacks
Only one test running at a time
No global variables
RSpec style syntactic sugar
- Nested contexts
- Easy to use setup/teardown
- Subject helpers
Pluggable mocking support
Native assertions
Easy to extend or replace the default assertions
Multiple output formatters on the same test run (not yet implemented)
Development
README Driven Development
_
Any and all features will be outlined in this readme file before the tests
are written.
BEHAVIOUR Driven Development
Integration tests which treat the executable as a black-box will be written
using cucumber
& aruba
(yes, using Ruby)
before any implementation.
Lots and lots of Unit Tests All code will be fully unit tested using NodeSpec itself before release.
.. README Driven Development
: http://tom.preston-werner.com/2010/08/23/readme-driven-development.html
.. cucumber
: http://cukes.info/
.. _aruba
: https://github.com/cucumber/aruba
If you'd like to contribute
- Fork the repository on github
- Make your changes
- Run the unit tests
- Run the cucumber tests with
cucumber -p all
- Push back to github and send me a pull request
If you're fixing a bug, please add a testcase to prove it was broken and is fixed, if you're adding a new feature, please add cucumber feature file for it.
To be able to run cucumber, you'll need Ruby and Bundler installed, then do bundle install
.
Installation
Via npm::
npm install nodespec
Or clone directly from github::
git clone git://github.com/glenjamin/nodespec
cd nodespec
npm link
Usage
Require the module into test files to use it::
var nodespec = require('nodespec');
And then at the end of each test file::
nodespec.exec();
Simple spec::
nodespec.describe("Addition", function() {
this.example("1 + 1 = 2", function() {
this.assert.equal(1 + 1, 2);
});
});
Simple async spec::
nodespec.describe("nextTick", function() {
// Accept 1 argument in the definition for an async test
this.example("fires the callback", function(test) {
this.expect(2);
this.assert.strictEqual(this, test);
process.nextTick(function() {
this.assert.strictNotEqual(this, test);
// async tests must call test.done()
test.done();
});
});
});
Before/After Hooks::
// Hooks share `this` with tests, but it's rebuilt each time
nodespec.describe("Some databasey test", function() {
this.before(function(hook) {
this.assert.strictEqual(this, hook);
db_connect(function (err, conn) {
hook.db = conn;
hook.db.start_transaction(function(err, tx) {
hook.tx = tx;
hook.done();
});
});
});
this.after(function() {
this.tx.rollback();
});
this.example("database interaction", function(test) {
test.expect(2);
test.db.insert({field: 1}, function(err, result) {
test.assert.strictEqual(result.affected, 1);
test.db.get(function(err, result) {
test.assert.strictEqual(result.field, 1);
test.done();
});
});
});
});
Nested contexts with subject::
nodespec.describe("My Server", function() {
// This function is executed once when `this.server` is accessed
this.subject('server', function() {
return new Server(1337);
});
this.context("Strict Mode", function() {
this.before(function() {
this.server.use_strict_mode();
});
this.example("invalid request fails", function(test) {
test.expect(1);
test.server.request('invalid', function(err, result) {
test.assert.notEqual(err, null);
test.done();
});
});
});
this.context("Not Strict Mode", function() {
this.before(function() {
this.server.dont_use_strict_mode();
});
this.example("invalid request fails silently", function(test) {
test.expect(2);
test.server.request('invalid', function(err, result) {
test.assert.equal(err, null);
test.assert.equal(result, null);
test.done();
});
});
});
});
Copyright
Copyright © 2011 The NodeSpec Authors. See LICENSE and AUTHORS for details.