At PyCon Canada 2013 I had the pleasure of seeing Kenneth Reitz, author of Python Requests. Kenneth described how he writes readmes before coding. By starting out answering what the project does, how, and why, you give the rest of your work a clear vision. This enables you to focus on building features your project needs, and crafting interfaces that prioritize how people will use it.

Unlike Kenneth, though, I write tests before implementing a project’s guts. Those tests are a chance to use the project’s interface like the readme describes it, even though they’ll fail, to give you a sense of how the interface you’ve designed feels and handles. If it feels weird, you can go back and change the readme. Beginning development like this, you can concentrate on the user, since there’s no code to refactor yet.

Lastly, I write code. Since I’ve already addressed all my interface design concerns, I can focus on making the best implementation possible.

Hey Internet! Let’s build a thing.

Project Skeleton

To follow along, let’s start a Node.js project. This is the skeleton I use for most of my projects:

    // your project’s code
    // your tests
    // t~he file that `require` imports
    // your project’s readme, of course
    // ‘.md’ means markdown:
    // dependencies and package data

To create those files is pretty straightforward:

mkdir your_project
cd $_
mkdir lib test
touch index.js
npm init

That last command, npm init, creates a package.json file and asks you a series of questions about what you’re building, including name, description, author, and license. You can always change those values later, so when I’m feeling lazy, I just hit enter until it goes away. :P

Now that we have a project skeleton, let’s put a project in it!


The Internet loves cats, so let’s build make-a-cat. Here’s how it works:

# make-a-cat
Create cat objects or add cat-like properties to objects in JavaScript, using Node.js.

## Install

    npm install make-a-cat

## Usage

    var make_a_cat = require(‘make-a-cat’);

    var cat = make_a_cat.create();
    // prints “meow~”
    // prints “purr~”

    var dog = {
        woof: function () {
    var catdog = make_a_cat.merge(dog);
    // prints “woof!”
    // prints “meow~”
    // program exits :O

Oh look, our! It’s not very thorough, but you can see it outlines the methods that make-a-cat exposes, what properties the cats it makes have, and what each of those methods does. Namely:

  • make_a_cat.create: Creates a cat object.
  • make_a_cat.merge: Adds cat properties to an existing object.
  • cat.meow: prints “meow~”.
  • cat.purr: prints “purr~”.
  • cat.sit_on_keyboard: causes the program to exit.

That wasn’t so hard. And, now that we have a list of methods and what they do, we can start writing tests!

Test (with Mocha!)

For testing, let’s use Mocha. To use Mocha’s terminal commands to test your code, let’s install it like this:

sudo npm install -g mocha

Now if you run mocha in your project directory, you should see something like this:

0 passing (2ms)

That’s because Mocha didn’t find any tests to run, but it also didn’t find any reason to break. Let’s give it some.

Let’s create a test/index.js file, which is where we’ll put our tests. Then, let’s put this in it:

// since make_a_cat uses `util.print` to print stuff
// we'll overwrite it to test its output
var util = require('util');
util.print = function () { return arguments; };

// since cat.sit_on_keyboard uses `process.exit` to exit
// we'll overwrite it to test its output
process.exit = function (status) { return status; };

var make_a_cat = require('../lib');
var assert = require('assert');

describe('make-a-cat', function () {
  before(function () { = {
      woof: function () {

  it('should make a cat', function () {
    var cat = make_a_cat.create();

  it('should merge cats onto other objects', function () {
    var catdog = make_a_cat.merge(;

describe('cats', function () {
  before(function () { = make_a_cat.create();

  it('should purr', function () {
    var args =;
    assert.equal(args[0], 'purr~');

  it('should meow', function () {
    var args =;
    assert.equal(args[0], 'meow~');

  it('should sit on the keyboard', function () {
    var status =;
    assert.equal(status, 1);

We’re using Mocha’s describe, before, and it functions to structure our tests. it and before share the same this object, so we can use before to set properties we want our it tests to have.

Since make-a-cat prints things and cat.sit_on_keyboard tries to kill the program, we’ll want to intercept those behaviors so we know they’re working. We do that before we import make-a-cat so that it uses our overridden functions.

Now that we have documentation and a test suite, let’s run it with mocha and see what happens:

Error: Cannot find module ‘../lib’

Of course our tests can’t find any code in our lib folder, because it’s empty. See how we wrote the tests the same way we’d write any code using this project? That demonstrates what it’s like to use the code, and can help us spot ways the project’s interface might be confusing or counter-intuitive for users.

Now that we’ve written our tests suite, let’s write the project code itself.


Create a lib/index.js file. We’ll put the project code in there, like this:

var util = require('util');
var _ = require('underscore');

var cat = {
  meow: function () {
    return util.print('meow~');
  purr: function () {
    return util.print('purr~');
  sit_on_keyboard: function () {
    return process.exit(1);

var make_a_cat = {
  create: function () {
    return _.extend({}, cat);
  merge: function (obj) {
    return _.extend({}, obj, cat);

module.exports = make_a_cat;

Our make-a-cat functions use underscore‘s extend method to create distinct copies of cats, so altering one cat doesn’t change every cat. To install underscore in your project, do this:

npm install –save underscore

This will add underscore as a dependency to your package.json file.

Now when we try mocha, it’s much happier:

  ✓ should make a cat
  ✓ should merge cats onto other objects

  ✓ should purr
  ✓ should meow
  ✓ should sit on the keyboard

5 passing (5ms)

Wahoo! Our code passes our tests! Now we know whether what we built works the moment we finish it.


How you imagine features, and how they end up working, will rarely align completely. I first wrote make-a-cat using console.log to print things, rather than util.print. I found that overwriting console.log for testing caused problems, so I switched to util.print.

Changes like that will pop up all through a project’s lifetime, changes which ask us to examine our assumptions going into the project. Just like adapting the readme to what you learn during testing, it’s great to adjust your tests and documentation based on your experience implementing the project.

See some of our past articles for more information on writing better readmes, documentation, and tests:

Happy coding!