Test-driven Development of a Backbone.js App. Part 3.


Please note that you will find all 3 parts of this article as well as the source code of the tutorial in the project’s GitHub repository.


Creating Backbone.js View

In the previous part of the series, we have created our first Backbone.js model using TDD principles.

The third and last part of the article is going to show you a process of developing a Backbone.js view, that will render the markup, handle the user input and reflect model’s state in the UI. Of course, this time we will use the test-driven development principles as well.

Just as it was with the ControlColor model, we will first write some tests in tests/views/control-color.js to make sure our view is defined and possesses Backbone-specific functions in its prototype:

QUnit.module( 'views/control-color.js', function() {
  QUnit.test( 'Color control view exists and is Backbone view', function( assert ) {
     var View = window.ControlColorView;

     assert.ok( ! _.isUndefined( View ), 'View is defined' );
     assert.ok( _.isFunction( View.prototype.setElement ) && _.isFunction( View.prototype.delegateEvents ), 'View is Backbone view' );
  } );
} );

The tests are failing, so we’ll define the ControlColorView in the src/views/control-color.js file like:

window.ControlColorView = Backbone.View.extend( {} );

From the red phase we rapidly moved to the green phase. There’s nothing to refactor so far, so we’ll now take care of rendering the markup based on model’s state.

Continue reading Test-driven Development of a Backbone.js App. Part 3.

Test-driven Development of a Backbone.js App. Part 2.


Please note that you will find all 3 parts of this article as well as the source code of the tutorial in the project’s GitHub repository.


Implementing Backbone.js Model

In the first part of the series I walked you through the test-driven development concepts. Then we have set up the project workspace, including a QUnit test runner and an empty source files accompanied with test files.

In the second part of the article, we will create our first Backbone.js model using TDD principles.

Early on in the project I decided to use the Backbone.js library and build our ControlColor component on top of it. In this case, first, we have to make sure that we’re dealing with a Backbone model.

To do so, we can look into object’s prototype and search for e.g. fetch and sync methods, which are pretty specific to Backbone models:

QUnit.module( 'models/control-color.js', function() {
  QUnit.test( 'Color control exists and is Backbone model', function( assert ) {
     var Model = window.ControlColor;

     assert.ok( ! _.isUndefined( Model ), 'model is defined' );
     assert.ok( _.isFunction( Model.prototype.fetch ) && _.isFunction( Model.prototype.sync ), 'model is Backbone model' );
  } );
} );

If we run unit tests now (refresh the browser), we will get one failing test:

Tests completed in 10 milliseconds.
1 assertions of 2 passed, 1 failed.

To fix it, we have to make ControlColor a real Backbone model:

window.ControlColor = Backbone.Model.extend( {} );

Now both tests are passing, so we have successfully gone through the green phase. There is nothing to refactor at this point, so we’re skipping this step.

Our new Backbone model has to store an array of available options and an array of currently selected options. So let’s write some tests to describe those requirements:

QUnit.module( 'models/control-color.js', function() {
  ...
  QUnit.test( 'Model has required properties', function( assert ) {
    var model = new window.ControlColor();

    assert.ok( model.has( 'options' ), 'model has "options" property' );
    assert.ok( _.isArray( model.get( 'options' ) ), '"options" is array' );

    assert.ok( model.has( 'checked' ), 'model has "checked" options property' );
    assert.ok( _.isArray( model.get( 'checked' ) ), '"checked" options is array' );
  } );
} );

All 4 tests are failing, so we’re good to proceed to green phase. Note that in this set of tests, we’ve already initialized the ControlColor model so that we can use Backbone methods like has() or get().

To make tests pass, let’s define defaults property in the ControlColor model:

window.ControlColor = Backbone.Model.extend( {
  defaults: {
     options: [],
     checked: []
  }
} );

Tests are green now. Again we won’t refactor neither implementation nor testing code.

Continue reading Test-driven Development of a Backbone.js App. Part 2.

Test-driven Development of a Backbone.js App. Part 1.


Please note that you will find all 3 parts of this article as well as the source code of the tutorial in the project’s GitHub repository.


Implementing test-driven development (TDD) principles based on a QUnit testing suite.

In one of the projects I worked on recently, there was a requirement to accompany our JavaScript code with unit tests. That is when I thought to myself that it would be a good idea to give test-driven development a try. But right then, a voice in my head said:

Nah! Writing unit tests first having no implementation seems unreasonable. Plus – in TDD I have to write unit tests for each and every module, not only the crucial ones. This means more code, and more time needed.

Luckily, at the time I stumbled upon an excellent series of articles by James Sinclair (for me a must-read for anyone wanting to step into TDD). The author shows test-driven development in a very interesting way. James Sinclair states that in TDD the programmer is more confident in his code while the development process is both efficient and enjoyable to the coder!

How is it so? Boring unit testing being fun to the developer? Now I just had to give TDD a try!

TDD Fundamentals

As you probably already know from James Sinclair’s post, each step in test-driven development is split into 3 phases:

  1. Red – write always-failing test.
  2. Green – write the simplest-possible implementation for the failing test.
  3. Refactor – rewrite implementation code in order to optimise and simplify the solution.

Always start with writing a failing test in the red phase. It will prevent your unit test from being erroneous (e.g. having always-passing test or trying to implement functionality that is already there).

Then write the simplest solution (even if it seems dumb) in green phase. Your aim is to write code that just passes the test. This way your implementation will stay lean, without any unnecessary code left here and there “just in case”.

Having the green light, you should go back to the implementation and refactor each snippet you feel could be written better. Please keep in mind your testing code is nothing you should be ashamed of. It deserves refactoring too!

Everything seems to be working well now? Rinse and repeat those 3 steps until you feel all requirements are satisfied for that particular module.

Sounds fairly simple? Let’s try to illustrate the process with an example then.

Continue reading Test-driven Development of a Backbone.js App. Part 1.