Apps, suites, and examples for Backbone.js test development.
This site provides materials and resources for developing and testing Backbone.js web applications. All of the application and test examples for the book Backbone.js Testing can be found here, grouped by chapter. We also provide a reference Backbone.js application - Notes - for creating and viewing notes, which we use throughout the examples in the book.
The core set of Backbone.js application technologies we cover includes:
We write a test infrastructure built on the following (fantastic) test libraries.
The source code for everything is available from the project's GitHub repository. If you find any errors or issues in content or code, please file a bug report and we'll fix things up in short order. For those interested in extending our testing examples or helping out, please see our contribution and development guide.
Backbone.js Testing by Ryan Roemer walks through the fundamentals of test-driven development for Backbone.js applications. All of the code samples are directly used in the book - it is essentially your narrative guide to this repository.
A short description of the book from the Packt Publishing website:
Frontend web applications are soaring in popularity and the Backbone.js library is leading this charge with a modular, lightweight approach for organizing JavaScript web applications. At the same time, testing client-side JavaScript and Backbone.js programs remains a difficult and tedious undertaking.
Backbone.js Testing brings sensible practices and current techniques to the challenges of Backbone.js test development. The book introduces fundamental testing concepts, comprehensive test infrastructure design, and practical exercises to easily and systematically test modern JavaScript web applications.
The book progresses from Mocha test suites and Chai assertions to advanced test mocks and stubs with Sinon.JS. The requisite libraries and utilities are introduced with in-depth examples and best practices for integration with your applications. The book guides you through the test planning and implementation processes for your application models, views, routers, and other Backbone.js components.
Backbone.js Testing gives you the tools, examples, and assistance to test your Backbone.js web applications thoroughly, quickly, and with confidence.
The application and test samples should work for the following browser / version combinations:
- Chrome: 7+
- Safari: 5+
- Firefox: 4+
- Internet Explorer: 9+
See the Chai installation notes for
more compatibility information. Note that the Chai should
object
prototype extension is not compatible with IE 9 and lower.
Notes is a simple personal note manager, written in
Backbone.js. We provide two versions - a "quick and easy" localStorage
based
application that works in your browser with no additional setup, and a
"classic" application with a full REST backend.
The Notes application home page lists existing notes (by creation date), and provides a form field to create a new note with a title. A filter field is available in the menu bar to limit the list of displayed notes by title.
Clicking on the edit icon brings us to the single note view, with a simple form editor for the title and text body fields of the note. The body of a note is written using Markdown formatting.
Clicking on the view menu tab switches us to the viewing pane, which renders the note's Markdown and produces our displayed note.
The Notes application is written using Bootstrap's responsive libraries and should render fine on mobile devices, tablets, and pretty much anything else.
The directory "notes/app
" contains the standalone application, which uses
HTML5 localStorage as a backing store. Some useful links to get you
started:
- App demo: Online demo for you to try out. Because the app saves to local storage, your notes will be preserved across browser sessions (for the same browser).
- Test Suite: The full Mocha / Chai / Sinon.JS test suite run in a single driver page.
- Code Coverage: Runs the above test suite with full browser-side code coverage thanks to the awesome Blanket.js coverage library.
An alternative version of the application uses
MongoDB instead of localStorage
for notes data and
can be found in the "notes-rest
" directory. The application is
served via a Node.js/Express
application located in "notes-rest/server.js".
Although we don't provide an online demo application, the full application
test suite is available online using Sinon.JS
fake servers to fake out the requirement
of having a real backend MongoDB server for the App.Collections.Notes
tests. The test suite is nearly identical to the localStorage application tests
for all of the other tests.
The server requires Node.js and MongoDB installations. Once you have these installed, you can change into the root of this repository and install all of the project libraries:
$ npm install
To run the sample server application, you will need two terminal windows. In the first window, start up MongoDB:
$ npm run-script mongo-start
In the second window, start up the Express server:
$ npm start
And from there you can navigate a browser to: http://127.0.0.1:4321/app/ and see the application running. Note that you can control several application options by setting console environment variables:
MONGO_ADDR
: MongoDB host address (default127.0.0.1
).MONGO_PORT
: MongoDB port (default27027
).ADDR
: Express server host address (default127.0.0.1
).PORT
: Express server port (default4321
).
For example:
$ export PORT=4323; npm start
runs the server on port 4323 instead of 4321 (the default).
The examples for each chapter are provided in the "chapters" directory, separated by number. We also provide a driver page for (nearly) all of the non-application tests.
-
Trying out the test libraries: Some first basic unit tests using Mocha, Chai, and SinonJS.
-
Test Failures: Different types of test failures.
-
Test Timing: Tests that take different times, which Mocha annotates for "medium" and "slow" tests. Also has one test timeout failure.
- Tests:
Initial simple tests for a Backbone.js application.
- namespace.spec.js: Verifies namespace objects are correctly setup.
- models/note.spec.js:
Tests the application model
App.Models.Note
.
-
BDD Interface: Tests using Mocha and Chai BDD styles.
-
TDD Interface: Tests using Mocha TDD and Chai
assert
styles. -
Chai Assertions: Tests using a variety of Chai BDD assertions.
- chai-chains.spec.js: Language chains.
- chai-values.spec.js: Value properties.
- chai-comparisons.spec.js: Comparison functions.
- chai-objects.spec.js: Object and array assertions.
- chai-errors.spec.js: Exception handling.
-
Mocha
only
: Tests using the Mochaonly
test modifier to run a single spec. -
Mocha
skip
: Tests using the Mochaskip
test modifier to skip one or more specs. -
Mocha Pending Tests: A basic skeleton suite with empty specs (e.g., no test callback), which are all in "pending" state during a test run. A great test development practice is to declare specs describing behavior without functions during the initial design phanse. The specs can later be implemented in parallel with the underlying application components, ensuring that the desired behavior is correctly implemented.
-
Tests: Continue tests for the Notes Backbone.js application.
- collections/notes.spec.js:
Tests the collection
App.Collections.Notes
. - views/note-view.spec.js:
Tests the view
App.Views.NoteView
, which renders model Markdown data into HTML.
- collections/notes.spec.js:
Tests the collection
-
Sinon.JS Spies: Various test uses for Sinon.JS spies.
-
Tests: Tests for the Notes Backbone.js application that use Sinon.JS spies.
- views/note-nav.spec.js:
Tests the
App.Views.NoteNav
view, which mediates events for the single page navigation menu bar. - views/note.spec.js:
Tests the
App.Views.Note
view, which wraps all of the other single note views and model.
- views/note-nav.spec.js:
Tests the
-
Sinon.JS Stubs: Tests using Sinon.JS stubs.
-
Sinon.JS Mocks: Tests using Sinon.JS mocks.
-
Tests: Tests for the Notes Backbone.js application with Sinon.JS stubs and mocks.
- views/notes-item.spec.js:
Tests the
App.Views.NotesItem
view, which displays a table row for a single note in the "all notes" list. - routers/router.spec.js:
Tests an abbreviated version of the
App.Routers.Router
router, implementing the route matching logic, but omitting the actual view creation and display. The tests that we create a good starting point for testing routers, but please see the Notes application source for the realApp.Routers.Router
source and full "routers/router.spec.js" file.
- views/notes-item.spec.js:
Tests the
We don't introduce any new tests in Chapter 6, instead focusing on automating all of the application and chapter tests we have provided in this respository. See the next section for a discussion of test automation with PhantomJS.
All of the tests for the Notes application and the chapter samples can be run in the PhantomJS headless WebKit engine. Simply install the Node.js dependencies:
$ npm install
and install PhantomJS on your development machine.
Note that as of v3.0.0, mocha-phantomjs
requires PhantomJS v1.9.1 or above.
From there, you can use the mocha-phantomjs
binary to run any HTML test
driver page from the command line, e.g.:
$ mocha-phantomjs notes/test/test.html
As a helper, the following script command will run nearly all of the Notes application and chapter unit tests:
$ npm test
We run all of these tests automatically using (the awesome) Travis CI continuous integration service. Travis watches the GitHub repository containing this project and when it detects the code has changed, launches new builds and invokes the PhantomJS tests above.
Travis even provides a convenient image status indicator, that we display below, so that we can display the always current build status of our code:
Setting all of this up is as simple as adding a Travis configuration file ".travis.yml" as follows:
language: node_js
node_js:
- 0.8
- 0.10
This instructs Travis to test out the latest Node.js versions for v0.8 and
v0.10. By default, Travis already has PhantomJS installed and will run
npm install
and npm test
on any Node.js project, which conveniently
sets up and invokes all of our PhantomJS tests.
Our actual ".travis.yml" file runs different commands than
the default npm test
to add things like style checking. But, the overall
Travis configuration is essentially the same.
There are many additional testing libraries and plugins specifically suited to testing Backbone.js applications beyond the core test stack we use in the application and chapter examples above.
Chai has a rich plugin ecosystem, with libraries that enhance the core Chai assertion statement library, provide more specific failure messages, and make application behavior easier to express.
Plugins that are used in some examples:
- sinon-chai: Allows Chai to make
Sinon.JS assertions like
expect(spy).to.have.been.calledWith(42)
instead of the Sinon.JS nativesinon.assert.calledWith(spy, 42)
.
Additional plugins not used in the examples:
- chai-jquery: Adds
assertions for jQuery functions and attributes like
data()
,class()
,id()
, andhidden()
. - chai-backbone: Adds
Backbone.js specific assertions such as
expect(model).to.trigger()
andexpect("hash/fragment").to.route.to()
.
All frontend libraries used in this repository for the sample apps and chapter examples are provided in the "vendor" directory.
Note that this repository has been updated since the publication of Backbone.js Testing on July 12, 2013. The enumerated versions of all third party libraries are indicated by the most current version in the repository with the published version optionally provided in parenthesis when different.
The core Backbone.js components used are:
- jQuery:
2.0.3
(2.0.2) - Underscore.js:
1.5.1
(1.4.4) - Backbone.js:
1.0.0
- Backbone.localStorage:
1.1.6
(1.1.5) - JSON: For older browsers
The sample Notes application also uses:
- Twitter Bootstrap:
2.3.2
- Showdown:
0.3.1
The frontend test libraries we use are:
The test plugins include:
- Sinon-Chai:
2.4.0
- Mocha-PhantomJS:
3.1.0
(2.0.3)
The repository was tagged with git as published-1.0
for the code samples
that are shipped with the book as it went to press. To check out the published
version in this repository, type:
$ git checkout tags/published-1.0
This will switch all libraries, application code, and tests to the version that directly matches the book.
As of v3.x.x and higher, Mocha-PhantomJS requires PhantomJS v1.9.1 or higher.
Mocha version 1.10.0 and 1.11.0 introduced incompatibilities with Mocha-PhantomJS. Modern versions of both libraries are now compatible, e.g., Mocha v1.12.0+ and Mocha-PhantomJS v3.1.0+.
For this historically minded, the evolution of this issue is documented in the following tickets:
Backbone.js Testing shipped with Mocha v1.9.0 and Mocha-PhantomJS v2.0.3 to avoid the issue.
All code not otherwise specified is Copyright 2013 Ryan Roemer. Released under the MIT License.
This repository contains various libraries from other folks, and are licensed as follows:
-
Backbone.js is Copyright Jeremy Ashkenas and licensed under the MIT license.
-
Underscore.js is Copyright Jeremy Ashkenas and licensed under the MIT license.
-
jQuery is Copyright jQuery Foundation and licensed under the MIT license.
-
Backbone.localStorage is Copyright Jerome Gravel-Niquet and licensed under the MIT license.
-
JSON is Public Domain software created by Douglas Crockford.
-
Mocha is Copyright TJ Holowaychuk and licensed under the MIT license.
-
Chai is Copyright Jake Luer and licensed under the BSD license.
-
Sinon-Chai is Copyright Domenic Denicola and licensed under what we will politely approximate to a "public domain" license.
-
Sinon.JS is Copyright Christian Johansen and licensed under the BSD license.
-
Twitter Bootstrap is Copyright Twitter, Inc. and licensed under the Apache v2.0 license.
-
jQuery Backstretch is Copyright Scott Robbin and licensed under the MIT license.
-
Showdown is Copyright Corey Innis and licensed under the BSD license.
-
Mocha-PhantomJS is Copyright Ken Collins and licensed under the MIT license.
-
Blanket.js is Copyright Alex Seville and licensed under the MIT license.
For those who would like to get under the hood, or help out with the application or test examples.
For pretty much everything, you will need to install PhantomJS, a Node.js environment, and the development NPM dependencies:
$ npm install
From there, there are various Grunt script helpers for style checking and tests:
# Run style checks for server, client, and both.
$ ./node_modules/.bin/grunt jshint:server
$ ./node_modules/.bin/grunt jshint:client
$ ./node_modules/.bin/grunt jshint
# Run headless tests for the application, individual chapters, all chapters
# as one big test, and all of these together.
$ ./node_modules/.bin/grunt test:app
$ ./node_modules/.bin/grunt test:rest
$ ./node_modules/.bin/grunt test:chaps
$ ./node_modules/.bin/grunt test:chaps-all
$ ./node_modules/.bin/grunt test
# Run all style checks and headless tests.
$ ./node_modules/.bin/grunt check
The file "README.md" is transformed from markdown into the HTML page "index.html", and can be compiled once, or watched for changes with the following commands.
$ ./node_modules/.bin/grunt jade:docs
$ ./node_modules/.bin/grunt watch:docs
Bugs, issues and fixes for any of the application or test code examples are most welcome. Please file a GitHub issue or pull request for any changes. Pull requests should be able to pass
$ ./node_modules/.bin/grunt check
without any errors.