• 15 hours
  • Easy

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 4/2/20

Testez qu'une fonction fait ce qu'elle dit

Log in or subscribe for free to enjoy all this course has to offer!

Comprenez l'importance des tests

Il y a environ un an, j'ai été appelé dans une start-up pour les aider à terminer un développement à temps pour leur date de déploiement. Le produit de cette société traite un grand nombre de petites transactions, donc l'exactitude était essentielle.

Je travaillais sur l'interface, mais j'ai immédiatement remarqué un problème : les calculs ne correspondaient pas. En lançant quelques centaines de transactions, les totaux étaient faux de plusieurs dizaines d'euros. Quelque chose allait sérieusement de travers.

Ce projet était grand, complexe et très ambitieux (l'interface elle-même avait plus de 600 000 lignes de code !), mais cette start-up n'avait pas mis en place d'architecture de test. Pour localiser le problème, il nous a fallu plus d'une semaine avec de plus en plus de frustration et de panique. Il y avait un quart de million d'euros en jeu, et cela seulement pour un client.

L'histoire s'est bien terminée, mais il a fallu une semaine entière pour rechercher une erreur, qui aurait été décelée s'il y avait eu un système décent de test. Nous aurions pu perdre tellement d'argent que la société aurait mis la clé sous la porte.

Qu'est-ce que le test?

Et bien, cela dépend ! Il y en a trois types essentiels.

Créez des tests unitaires

Le test unitaire vérifie des unités individuelles (en général des fonctions uniques ou des classes) en leur fournissant une entrée et en s'assurant qu'elles donnent la sortie attendue.

En général, chaque unité est testée sur un cas simple, puis sur un ou plusieurs cas limites.

Si par exemple, vous prenez quelques fonctions du chapitre précédent :

const getWordCount = (stringToTest) => {
  const wordArray = stringToTest.split(' ');
  return wordArray.length;
}

const getLetterCount = (stringToTest) => {
  const wordArray = stringToTest.split(' ');
  let totalLetters = 0;
  for (let word of wordArray) {
    word.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g, "");
    totalLetters += word.length;
  }
  return totalLetters;
}

Quels cas testeriez-vous pour chaque fonction ici ?

  • getWordCount  — Vous pourriez vérifier une chaîne dont vous connaissez le nombre de mots (cas simple), puis peut-être une chaîne vide, et une chaîne qui ne contiendrait que des espaces (cas limite).

  • getLetterCount  — Vous pourriez vérifier une chaîne dont vous connaissez le nombre de lettres (cas simple), puis essayer une chaîne ne contenant que des ponctuations (cas limite).

Vous pourriez écrire ces tests comme code accessoire :

const testSimpleWordCount = () => {
    const testString = 'I have four words!';
    if (getWordCount(testString) !== 4) {
        console.error('Simple getWordCount failed!');
    }
}

const testEdgeWordCount = () => {
    const testString = '             ';
    if (getWordCount(testString) !== 0) {
        console.error('Edge getWordCount failed!');
    }
}

const testSimpleLetterCount = () => {
    const testString = 'I have twenty one letters!';
    if (getLetterCount(testString) !== 21) {
        console.error('Simple getLetterCount failed!');
    }
}

const testEdgeLetterCount = () => {
    const testString = '")(&;//!!';
    if (getLetterCount(testString) !== 0) {
        console.error('Edge getLetterCount failed!');
    }
}

Ce sont des tests simples, et il peuvent convenir pour des vérifications rapides, mais il est généralement préférable d'utiliser une architecture de test.

Les architectures et bibliothèques de test permettent d'écrire automatiquement des suites de tests complètes de votre code, à l'aide de fonctions et de syntaxe spécifiques. Voici à quoi pourraient ressembler les deux tests ci-dessus dans certaines architectures :

describe('getWordCount()', function() {
    it('should find four words', function() {
        expect(getWordCount('I have four words!').to.equal(4));
    });
    it('should find no words', function() {
        expect(getWordCount('      ').to.equal(0));
    });
});

Les tests unitaires constituent généralement entre 60 et 80 % de l'ensemble des tests des projets JavaScript. Mais il existe d'autres tests, comme les tests d'intégration.

Découvrez les tests d'intégration

Integration tests are important
"Pas de tests d'intégration"

Les tests d'intégration vérifient les multiples fonctions ou classes pour s'assurer qu'elles travaillent ensemble comme elles sont censées le faire. L'image ci-dessus montre ce qui se passe quand les unités individuelles fonctionnent correctement (les deux tiroirs s'ouvrent correctement séparément), mais que leur intégration dans le système qui les entoure cause un problème de fonctionnement.

Appréhendez les tests fonctionnels

Les tests fonctionnels, aussi appelés de bout en bout (E2E), vérifient des scénarios complets en contexte. Par exemple, un utilisateur se connecte à votre application, ouvre ses notifications et les marque toutes comme lues. Ces tests vérifient aussi les ressources externes que votre projet peut utiliser, par exemple un système de paiement tiers.

En résumé

Dans ce chapitre, nous vous avons présenté les trois types de tests :

  • les tests unitaires ;

  • les tests d'intégration ;

  • les tests fonctionnels (E2E).

Vous avez aussi vu que, bien que des tests manuels sur du code accessoire puissent fonctionner, il existe des architectures automatisées qui rendent plus faciles et fiables les tests.

Dans le chapitre suivant, nous allons voir comment corriger du code quand tout va mal : le débogage !

Example of certificate of achievement
Example of certificate of achievement