web-dev-qa-db-fra.com

Comment puis-je faire en sorte que Mocha charge un fichier helper.js qui définit les points d'ancrage ou les utilitaires globaux?

J'ai un fichier nommé test/helper.js que j'utilise pour exécuter des tests Mocha sur mes applications Node.js. La structure de mes tests ressemble à:

test/
test/helper.js    # global before/after
test/api/sometest.spec.js
test/models/somemodel.spec.js
... more here

Le fichier helper.js doit être chargé car il contient des points d'ancrage globaux pour ma suite de tests. Quand je lance Mocha pour exécuter la suite de tests complète comme ceci:

mocha --recursive test/

le fichier helper.js est chargé avant mes tests et mon hook before est exécuté comme prévu.

Cependant, lorsque je lance un seul test spécifique, helper.js n'est pas chargé avant le test. Voici comment je le lance:

mocha test/api/sometest.spec.js

Pas de before global appelé, pas même une console.log('I WAS HERE');.

Alors, comment puis-je obtenir Mocha pour toujours charger mon fichier helper.js?

33
Zlatko

Mocha n'a aucune notion d'un fichier spécial nommé helper.js qu'il se chargerait avant d'autres fichiers. 

Ce que vous essayez de faire fonctionne lorsque vous exécutez mocha --recursive en raison de l'ordre dans lequel Mocha arrive pour charger vos fichiers. Étant donné que helper.js est supérieur d'un niveau aux autres fichiers, il est chargé en premier. Lorsque vous spécifiez un fichier individuel dans Mocha, celui-ci charge simplement ce fichier et, comme vous l'avez découvert, votre fichier helper.js n'est pas chargé du tout.

Donc, ce que vous voulez faire est de charger un fichier tel qu’il définira les points d’accroché (globaux) (par exemple, before, after, etc.). Options: 

  1. Vous pouvez utiliser Mocha par programme et lui donner les fichiers dans l’ordre que vous souhaitez. 

  2. Vous pouvez vous forcer à toujours spécifier votre fichier d'assistance sur la ligne de commande first avant de répertorier un autre fichier. (Je ne ferais pas cela, mais c'est possible.)

  3. Une autre option serait d'organiser votre suite comme je l'ai détaillé dans cette réponse . Fondamentalement, vous avez un fichier "de niveau supérieur" qui charge le reste de la suite. Avec cette méthode, vous perdez la possibilité d'exécuter Mocha sur des fichiers individuels, mais vous pouvez utiliser --grep pour sélectionner ce qui est en cours d'exécution.

Vous ne pouvez pas utiliser l'option -r. Il charge un module avant d'exécuter la suite mais, malheureusement, le module chargé n'a accès à aucune des interfaces de test que Mocha met à la disposition de vos tests, il ne peut donc pas définir de points d'ancrage.

23
Louis

Ce que je fais est de créer un fichier test/test_helper.js, qui exporte toutes les aides que je crée:

// test/test_helper.js    
module.exports = {
    MyHelper: require('./helpers/MyHelper')
}

Ensuite, je require l'assistant pour tout test dont j'ai besoin pour l'utiliser:

// test/spec/MySpec.js
var helper = require('../test_helper');

// Or if you need just "MyHelper"
var myHelper = require('../test_helper').MyHelper;

describe('MySpec', function () {
   // Tests here...
});

Je préfère l'approche ci-dessus parce que c'est facile à comprendre et flexible. Vous pouvez le voir en action ici dans ma démo: https://github.com/paulredmond/karma-browserify-demo/tree/master/test

15
Paul Redmond

Premièrement, j'utiliserais certainement mocha.opts afin que vous n'ayez pas à inclure les options souhaitées à chaque fois. Comme indiqué, une option consiste à utiliser --grep, mais je ne suis pas un grand fan de cela personnellement. Il vous fallait tout nommer d'une manière trop simpliste. Si le hook before n'est PAS asynchrone, vous pouvez utiliser --require dans votre mocha.opts. par exemple.

#mocha.opts
--recursive
--require test/helpers.js

Il semble que cela ne fonctionnerait pas pour vous parce que vous voulez aussi un hook after global. Ce que j’ai fait, c’est que j’appelle la suite de tests complète à chaque fois, mais si je suis en train de développer et que je ne veux tester qu’une suite, voire un test spécifique, j’utilise la fonction d’exclusivité, onlyhttps://mochajs.org/#exclusive-tests . Vous pouvez le rendre it.only('... ou describe.only('.... Si vous procédez ainsi, il examine tous les tests et se configure exactement comme le ferait votre harnais de test complet, mais n'exécutera que le test ou la suite que vous avez spécifiés. 

Maintenant, vous pouvez inclure ces crochets globaux sans problème. @Louis mentionne que vos helpers.js se chargent dans le bon ordre seulement par hasard. Ce n'est pas vrai. Si vous placez des crochets en dehors d'un bloc describe, il devient automatiquement un crochet global. Ceci peut être accompli soit en le plaçant dans son propre fichier 

// helpers.js
before(function() { console.log('testing...'); });

ou dans un fichier de test

// some.spec.js
before(function() { console.log('testing...'); });

describe('Something', function() {
  it('will be tested', function() {
  ...
  });
});

De toute évidence, je pense que le placer dans son propre fichier est plus propre. (Je l'ai appelé hooks.js). Le fait est que cela ne résulte pas de l'ordre dans lequel les fichiers ont été chargés. 

Un seul casse-tête qui pourrait être évident pour un autre, mais je me suis battu avec brièvement - les crochets non placés dans un bloc describe sont TOUS globaux. Ils ne sont pas spécifiques à un répertoire. Donc, si vous copiez helpers.js dans un sous-répertoire de tests, les hooks before et after seront maintenant déclenchés deux fois. De plus, si vous placez un hook beforeEach dans celui-ci, il se déclenchera avant chaque test, et pas uniquement dans le répertoire. 

Quoi qu'il en soit, je sais que ce message est un peu vieux, mais j'espère que cela aidera d'autres personnes ayant des problèmes similaires. 

12
aray12

Je suis venu à cette question après avoir essayé toutes sortes de choses pour que mes tests se connectent une fois à une base de données avant d'exécuter par la suite une série de tests crud sur ma models.

Puis j'ai trouvé moka-prepare qui a résolu mes problèmes.

Dans votre fichier helper.js, vous pouvez simplement définir une fonction prepare.

prepare(done => {
  console.log('do something asynchronously here')
  done()
}, done => {
  console.log('asynchronously clean up after here')
  done()
})

fonctionne un régal.

3
Dave Sag

Dans notre projet, nous utilisons des aides un peu comme ceci:

clientHelper = require("../../../utils/clientHelper")

Vous devez configurer correctement le chemin relatif de votre assistant.

Et en l'appelant comme ça:

clientHelper.setCompanyId(clientId)
0
Divjot Singh