Cet article montre comment écrire des tests unitaires JS en prenant comme application exemple la todo liste backbone codée avec le framework Backbone.js et le chargeur de modules RequireJS.
On se focalise ici sur les tests des composants Backbone de type Model et Collection.
Mocha est le framework de test que l’on utilise, complété par Chai pour les assertions.
L’environnement d’exécution nécessite seulement Node.js, il n’y a donc pas besoin de browser pour lancer les tests unitaires.
L’exemple complet est disponible sur Github sur la branche webdriverio-it-tests (voir le README pour exécuter les tests unitaires).
Configuration
La configuration des tests est faite par grunt et la task grunt-mocha-test pour exécuter les tests mocha dans Node.js, lance notamment le helper global main.js.
Extrait du Gruntfile.js
...
mochaTest: {
test: {
options: {
reporter: 'spec',
timeout: 1000,
require: 'test/spec/helpers/main.js'
},
src: ['test/spec/*.js']
}
}
...
Mise en place de Chai et des dépendances de modules dans le helper main.js
var chai = require('chai');
global.expect = chai.expect;
...
Tests unitaires du composant Model Todo
describe('Todo', function() { | |
var Todo = requirejs('models/todo'); | |
var todo; | |
beforeEach(function() { | |
todo = new Todo(); | |
}); | |
it('defaults are empty title and not completed', function() { | |
expect(todo.get('title')).to.be.a('string').and.to.be.empty; | |
expect(todo.get('completed')).to.be.false; | |
}); | |
it('when toggle then completed', function() { | |
todo.toggle(); | |
expect(todo.get('completed')).to.be.true; | |
}); | |
}); |
- Les méthodes Mocha describe et it décrivent le comportement attendu du composant Todo comme s’il s’agissait d’une spécification
- La méthode beforeEach de Mocha fournit une nouvelle instance de Todo à chaque test
- Les assertions sont exécutées avec Chai dans le style expect
Tests unitaires du composant Collection Todos
describe('Todos', function() { | |
var Todo = requirejs('models/todo'); | |
var todos = requirejs('collections/todos'); | |
beforeEach(function() { | |
todos.reset(); | |
}); | |
it('filtering completed', function() { | |
todos.set([{title: 'todo1', completed: true}, {title: 'todo2', completed: false}, {completed: true}]); | |
var todosCompleted = todos.completed(); | |
expect(todosCompleted).to.have.length(2); | |
expect(todosCompleted[0].get('completed')).to.be.true; | |
expect(todosCompleted[1].get('completed')).to.be.true; | |
}); | |
it('filtering remaining', function() { | |
var todo1 = new Todo(); | |
todo1.toggle(); | |
var todo2 = new Todo(); | |
todos.set([todo1, todo2]); | |
var todosRemaining = todos.remaining(); | |
expect(todosRemaining).to.have.length(1); | |
expect(todosRemaining[0]).to.eql(todo2); | |
}); | |
}); |
- Une seule instance de la collection est ré initialisée à chaque test par la méthode beforeEach
- Chaque méthode de test contient des sauts de ligne pour séparer
- le setup particulier au test
- l’action testée
- et les assertions
Et voila, le modèle de l’application est couvert par les tests indépendamment du code des Backbone Views.
Nous allons justement voir dans cet article comment implémenter les tests unitaires des Views.