Comprendre Jasmine en exemples

Vous n’aviez jamais trouvé le temps pour enfin vous y mettre : rendre l’intégralité de votre code testable ! Aujourd’hui, au travers de quelques exemples nous allons voir comment facilement spécifier votre code javascript grâce à la très populaire librairie Jasmine.

On va partir ici sur un exemple simple : nous avons une classe Carnet qui va contenir un ensemble de Contact:

class Carnet {
constructor() {
this.contacts = [];
}
  recupererContact(i) {
return this.contacts[i];
}
  ajouterContact(contact) {
this.contacts.push(contact);
}
  supprimerContact(i) {
this.contacts.splice(i, 1);
}
}
class Contact {
// Rien d'autre ici, cela permettra simplement de remplir le carnet
}

Prélude

Avant d’aller plus loin, il est important pour vous de découvrir la façon de créer un court test avec Jasmine. Vous verrez par la suite un ensemble de fonctions pour structurer vos tests.

La fonction à la base de Jasmine s’appelle expect:

// Ces tests vont passer...
expect(true).toBe(true);
expect(true).not.toBe(false);
var nom = 'nono';
expect(nom).toBe('nono');
// ...mais pas ceux-là !
expect(true).toBe(false);
expect(nom).toBe('joe');

Bien que je pense que la syntaxe parle d’elle-même, faisons un rapide point :

  • expect prend une expression en paramètre qui va être évaluée ;
  • toBe prend une seconde expression qui va être comparée avec celle passée en paramètre pour expect;
  • .not , si renseigné, permet d’inverser le test depuis == vers !=.

Créer un ensemble de tests pour notre classe

Pour créer une suite de tests, on utilisera describe avec Jasmine, afin d’initier cet ensemble associé à tel objet javascript :

describe('Carnet', () => {
// L'ensemble de nos tests pour Carnet
});

Ici, on indique à Jasmine que tous les tests qui se trouveront dans le bloc describe, sont associés à son label. Ici, “Carnet”.

Créer un test

Admettons que pour notre premier test, nous souhaitons vérifier que l’ajout d’un contact dans notre Carnet fonctionne correctement. On utilisera alors la fonction it afin de décrire ce que l’on souhaite vérifier.

Ajouter un contact

describe('Carnet', () => {
it('ajouter un contact', () => {
const carnet = new Carnet();
const contact = new Contact();
    carnet.ajouterContact(contact);

expect(carnet.recupererContact(0)).toBe(contact);
});
});
  • Pour faire simple, nous avons appelé notre test “ajouter un contact”, afin de par la suite savoir de quel test il est question (s’il échoue par exemple).
  • Ensuite, carnet et contact sont instanciés afin de pouvoir les manipuler pour vérifier que tout fonctionne correctement ; tout comme dans un environnement où vous auriez utilisé ces classes pour votre application.
  • On ajoute un contact dans notre carnet.
  • On vérifie que lorsqu’on récupère le premier contact, celui-ci correspond bien à celui ajouté.

Supprimer un contact

describe('Carnet', () => {
it('ajouter un contact', () => {
const carnet = new Carnet();
const contact = new Contact();
carnet.ajouterContact(contact);
expect(carnet.recupererContact(0)).toBe(contact);
});
  it('supprimer un contact', () => {
const carnet = new Carnet();
const contact = new Contact();
    carnet.ajouterContact(contact);
carnet.supprimerContact(0);

expect(carnet.recupererContact(0)).not.toBeDefined();
});
});
  • Même démarche ici d’instanciation dans un premier temps, avec nos constantes carnet et contact.
  • On ajoute, comme dans le test précédent, le contact au carnet.
  • On supprimer le premier contact, tout juste ajouté (d’où l’index 0).
  • On confirme que lorsqu’on récupère le premier contact du carnet, celui-ci est bien non défini ( .not.toBeDefined() va le vérifier).

Simplifier vos tests

Jasmine fournit un ensemble de fonctions qui permettent d’alléger le corps de vos tests. Avant de rentrer dans notre cas concret, voici les 4 fonctions qui vous seront utiles :

beforeEach(() => {});
// Avant chaque test
// ex: réinitialisation de variables nécessaires pour chaque test
afterEach(() => {});
// Après chaque test
beforeAll(() => {});
// Avant tous les tests
// ex: initialisation générale
afterAll(() => {});
// Après tous les tests
// ex: nettoyage complet

Dans le cas de notre Carnet, on se rend compte qu’avant chacun de nos tests — en début de chaque bloc it, nous faisons une même initialisation :

const carnet = new Carnet();
const contact = new Contact();
carnet.ajouterContact(contact);

Grâce à beforeEach, on peut simplifier l’ensemble de nos tests :

beforeEach(() => {
const carnet = new Carnet();
const contact = new Contact();
carnet.ajouterContact(contact);
});
it('ajouter un contact', () => {
expect(carnet.recupererContact(0)).toBe(contact);
});
it('supprimer un contact', () => {
carnet.supprimerContact(0);
expect(carnet.recupererContact(0)).not.toBeDefined();
});

Si vous êtes arrivés jusqu’ici, vous disposez donc de l’ensemble des bases pour utiliser Jasmine. Aussi, je ne pourrais que vous recommander de consulter directement la documentation pour en savoir plus. Si vous souhaitez l’installer avec node.js directement, rendez-vous ici.

Et sinon ?

Sinon…, il y a d’après moi deux autres librairies qui valent le coup d’oeil pour effectuer vos tests avec javascript :

  • Ava, sûrement mon futur favori personnellement. Très simple à aborder, haut-niveau dans sa syntaxe.
  • Mocha, qui ressemble beaucoup à Jasmine syntaxiquement.

Pour ne pas rater nos prochains articles, il suffit simplement de s’abonner ! Merci pour votre temps, et à bientôt. :)

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.