web-dev-qa-db-fra.com

Quel est le rôle de describe () dans Mocha?

La documentation sur le site officiel de Mocha contient cet exemple:

describe('User', function(){
  describe('#save()', function(){
    it('should save without error', function(done){
      var user = new User('Luna');
      user.save(function(err){
        if (err) throw err;
        done();
      });
    })
  })
})

Je veux savoir quand je dois imbriquer mes tests dans la fonction describe et quel est l'objectif principal de describe. Puis-je comparer le premier argument passé à describe à des commentaires dans un langage de programmation? Rien n'est montré de describe dans la sortie sur la console. Est-ce uniquement à des fins de lisibilité ou existe-t-il une autre utilisation de cette fonction?

Y a-t-il un problème si je l'utilise comme ça?

describe('User', function(){
    describe('#save()', function(){
        var user = new User('Luna');
        user.save(function(err){
            if (err) throw err;
            done();
        })
    })
})

Si je le fais de cette façon, le test réussit toujours.

63

L'appel it identifie chaque test individuel mais en lui-même it ne dit rien à Mocha sur la façon dont votre suite de tests est structurée. La façon dont vous utilisez l'appel describe est ce qui donne la structure à votre suite de tests. Voici certaines des choses que l'utilisation de describe pour structurer votre suite de tests fait pour vous. Voici un exemple de suite de tests, simplifiée aux fins de discussion:

function Foo() {
}

describe("Foo", function () {
    var foo;
    beforeEach(function () {
        foo = new Foo();
    });
    describe("#clone", function () {
        beforeEach(function () {
            // Some other hook
        });
        it("clones the object", function () {
        });
    });
    describe("#equals", function () {
        it("returns true when the object passed is the same", function () {
        });
        it("returns false, when...", function () {
        });
    });
    afterEach(function () {
        // Destroy the foo that was created.
        // foo.destroy();
    });
});

function Bar() {
}

describe("Bar", function () {
    describe("#clone", function () {
        it("clones the object", function () {
        });
    });
});

Imaginez que Foo et Bar sont des classes à part entière. Foo possède les méthodes clone et equals. Bar a clone. La structure que j'ai ci-dessus est une façon possible de structurer les tests pour ces classes.

(La notation # Est utilisée par certains systèmes (comme par exemple, jsdoc) pour indiquer un champ d'instance. Ainsi, lorsqu'elle est utilisée avec un nom de méthode, elle indique une méthode appelée sur une instance de la classe (plutôt qu'un méthode de classe, qui est appelée sur la classe elle-même.) La suite de tests fonctionnerait tout aussi bien sans la présence de #.)

Fournir des bannières

Certains des reporters de Mocha montrent les noms que vous donnez à describe dans les rapports qu'ils produisent. Par exemple, le journaliste spec (que vous pouvez utiliser en exécutant $ mocha -R spec), Signalera:

  Foo
    #clone
      ✓ clones the object 
    #equals
      ✓ returns true when the object passed is the same 
      ✓ returns false, when... 

  Bar
    #clone
      ✓ clones the object 


  4 passing (4ms)

Aide à sélectionner les pièces à exécuter

Si vous ne souhaitez exécuter que certains des tests, vous pouvez utiliser l'option --grep. Donc, si vous ne vous souciez que de la classe Bar, vous pouvez faire $ mocha -R spec --grep Bar Et obtenir la sortie:

  Bar
    #clone
      ✓ clones the object 


  1 passing (4ms)

Ou si vous vous souciez uniquement des méthodes clone de toutes les classes, alors $ mocha -R spec --grep '\bclone\b' Et obtenez la sortie:

  Foo
    #clone
      ✓ clones the object 

  Bar
    #clone
      ✓ clones the object 


  2 passing (5ms)

La valeur donnée à --grep Est interprétée comme une expression régulière, donc quand je passe \bclone\b Je ne demande que le mot clone, et pas des choses comme clones ou cloned.

Fournir des crochets

Dans l'exemple ci-dessus, les appels beforeEach et afterEach sont des hooks. Chaque hook affecte les appels it qui se trouvent dans l'appel describe qui est le parent du hook. Les différents crochets sont:

  • beforeEach qui s'exécute avant chaque individu it à l'intérieur de l'appel describe.

  • afterEach qui s'exécute après chaque individu it dans l'appel describe.

  • before qui s'exécute une fois avant l'exécution de l'un des it de l'appel describe.

  • after qui s'exécute une fois que tous les it individuels dans l'appel describe sont exécutés.

Ces crochets peuvent être utilisés pour acquérir des ressources ou créer des structures de données nécessaires aux tests, puis libérer des ressources ou détruire ces structures (si nécessaire) une fois les tests terminés.

L'extrait que vous montrez à la fin de votre question ne générera pas d'erreur, mais il ne contient en fait aucun test, car les tests sont définis par it.

71
Louis

À ma connaissance, décrire est vraiment juste là pour les humains ... Nous pouvons donc voir différents domaines de l'application. Vous pouvez imbriquer décrire n niveaux en profondeur.

describe('user',function(){
    describe('create',function(){}
});

Il est difficile d'ajouter à l'excellente réponse de Louis. Il y a quelques avantages du bloc décrit qu'il n'a pas mentionnés, à savoir les fonctions skip et only.

describe.skip(...) {
...
}

sautera cette description et toutes ses descriptions imbriquées et elle fonctionnera pendant que:

describe.only(...) {
...
}

exécutera uniquement cette description et sa description imbriquée et elle fonctionnera. Les modificateurs skip() et only() peuvent également être appliqués aux fonctions it ().

5
Guy

Décrire n'est utilisé que pour comprendre l'objectif des tests, il est également utilisé pour regrouper logiquement les tests. Disons que vous testez les API de base de données, tous les tests de base de données peuvent relever de la description externe, de sorte que la description externe regroupe logiquement toutes les bases de données liées. Disons qu'il y a 10 API liées à la base de données à tester, chacune des fonctions de description internes définit ce que sont ces tests ....

2
Karthic Rao

Le rôle particulier de decrire est d'indiquer quel composant est testé et quelle méthode de ce composant est également testée.

par exemple, disons que nous avons un prototype d'utilisateur

var User = function() {
    const self = this;

    function setName(name) {
        self.name = name
    }

    function getName(name) {
        return self.name;
    }


    return{setName, getName};
}

module.exports = User;

Et il doit être testé, donc un fichier de spécifications est créé pour le test unitaire

var assert = require('assert');
var User = require("../controllers/user.controller");

describe("User", function() {
    describe('setName', function() {
        it("should set the name on user", function() {
            const pedro = new User();

            name = "Pedro"
            pedro.setName(name);
            assert(pedro.getName(), name);
        });
    });
});

Il est facile de voir que le but de decrire indique le composant à tester et les méthodes de description imbriquées indiquent quelles méthodes doivent être testées

0
Pedro Machado