Exécution dynamic de tests Mocha

J’essaie d’exécuter une série de tests de manière dynamic. J’ai la configuration suivante mais elle ne semble pas fonctionner et je ne reçois aucune erreur:

import Mocha from 'mocha'; const Test = Mocha.Test; const Suite = Mocha.Suite; const mocha = new Mocha(); for (let s in tests) { let suite = Suite.create(mocha.suite, s); tests[s].forEach((test) => { console.log('add test', test.name) suite.addTest(new Test(test.name), () => { expect(1+1).to.equal(2); }); }); } mocha.run(); 

Les tests je fais ressemblent à ceci:

 { todo: [ { name: 'POST /todos', should: 'create a new todo', method: 'POST', endpoint: '/todos', body: [Object] } ] } 

(bien qu’à ce stade mon test essaye juste de vérifier une attente de base)

Sur la base des fichiers console.log, l’itération semble correcte et l’ajout des tests apparaît. Je suis donc confiant dans le déroulement des opérations. Je ne peux tout simplement pas obtenir d’exécution ni d’erreur.

Vous devez transmettre la fonction de Test constructeur de Test , et non à suite.addTest . Alors changez votre code pour append vos tests comme ceci:

 suite.addTest(new Test(test.name, () => { expect(1+1).to.equal(2); })); 

Voici le code complet que je lance, adapté de votre question:

 import Mocha from 'mocha'; import { expect } from 'chai'; const Test = Mocha.Test; const Suite = Mocha.Suite; const mocha = new Mocha(); var tests = { todo: [ { name: 'POST /todos', should: 'create a new todo', method: 'POST', endpoint: '/todos', body: [Object] } ] }; for (let s in tests) { let suite = Suite.create(mocha.suite, s); tests[s].forEach((test) => { console.log('add test', test.name); suite.addTest(new Test(test.name, () => { expect(1+1).to.equal(2); })); }); } mocha.run(); 

Lorsque node_modules/.bin/babel-node test.es6 ce qui précède avec node_modules/.bin/babel-node test.es6 , je reçois le résultat:

  todo ✓ POST /todos 1 passing (5ms) 

Il est essentiel de tester votre système de test et de vous assurer qu’il traite les tests avec succès et les échecs et les exceptions levées. Puisque les gens comptent sur un processus de construction pour les avertir des erreurs, vous devez également définir le code de sortie sur une valeur non nulle si quelque chose a échoué. Vous trouverez ci-dessous un script de test (que vous devez appeler avec le node test.js plutôt que mocha test.js ), qui exerce tous les chemins dans votre suite de tests:

 const Mocha = require('mocha') const expect = require('chai').expect var testRunner = new Mocha() var testSuite = Mocha.Suite.create(testRunner.suite, 'Dynamic tests') var tests = [ // Define some tasks to add to test suite. { name: 'POST /todos', f: () => true }, // Pass a test. { name: 'GET /nonos', f: () => false }, // Fail a test. { name: 'HEAD /hahas', f: () => { throw Error(0) } } // Throw an error. ] tests.forEach( test => // Create a test which value errors and caught exceptions. testSuite.addTest(new Mocha.Test(test.name, function () { expect(test.f()).to.be.true })) ) var suiteRun = testRunner.run() // Run the tests process.on('exit', (code) => { // and set exit code. process.exit(suiteRun.stats.failures > 0) // Non-zero exit indicates errors. }) // Falling off end waits for Mocha events to finish. 

Étant donné que cela est particulièrement important dans les recherches Web pour les tests asynchrones de moka, je vais fournir quelques modèles supplémentaires utiles à copier.

Exécution intégrée: Le premier ajoute directement des tests qui invoquent un faux appel réseau asynchrone et vérifient le résultat dans un .then :

 const Mocha = require('mocha') const expect = require('chai').expect var testRunner = new Mocha() var testSuite = Mocha.Suite.create(testRunner.suite, 'Network tests') var tests = [ // Define some long async tasks. { name: 'POST /todos', pass: true, wait: 3500, exception: null }, { name: 'GET /nonos', pass: false, wait: 2500, exception: null }, { name: 'HEAD /hahas', pass: true, wait: 1500, exception: 'no route to host' } ] tests.forEach( test => // Create a test which value errors and caught exceptions. testSuite.addTest(new Mocha.Test(test.name, function () { this.timeout(test.wait + 100) // so we can set waits above 2000ms return asynchStuff(test).then(asyncResult => { expect(asyncResult.pass).to.be.true }) // No .catch() needed because Mocha.Test() handles them. })) ) var suiteRun = testRunner.run() // Run the tests process.on('exit', (code) => { // and set exit code. process.exit(suiteRun.stats.failures > 0) // Non-zero exit indicates errors. }) // Falling off end waits for Mocha events to finish. function asynchStuff (test) { return new Promise(function(resolve, reject) { setTimeout(() => { // console.log(test.name + ' on ' + test.endpoint + ': ' + test.wait + 'ms') if (test.exception) reject(Error(test.exception)) resolve({name: test.name, pass: test.pass}) // only need name and pass }, test.wait) }) } 

Ce code gère la transmission et l’échec des données, signale les exceptions et quitte avec un statut différent de zéro s’il y avait des erreurs. La sortie indique tous les problèmes attendus et signale en outre que le test prend un temps similaire (3,5 secondes):

  Network tests ✓ POST /todos (3504ms) 1) GET /nonos 2) HEAD /hahas 1 passing (8s) 2 failing 1) Network tests GET /nonos: AssertionError: expected false to be true + expected - actual -false +true 2) Network tests HEAD /hahas: Error: no route to host 

Exécution différée : cette approche appelle toutes les tâches lentes avant de renseigner et de démarrer la suite de tests mocha:

 const Mocha = require('mocha') const expect = require('chai').expect var testRunner = new Mocha() var testSuite = Mocha.Suite.create(testRunner.suite, 'Network tests') var tests = [ // Define some long async tasks. { name: 'POST /todos', pass: true, wait: 3500, exception: null }, { name: 'GET /nonos', pass: false, wait: 2500, exception: null }, { name: 'HEAD /hahas', pass: true, wait: 1500, exception: 'no route to host' } ] Promise.all(tests.map( // Wait for all async operations to finish. test => asynchStuff(test) .catch(e => { // Resolve caught errors so Promise.all() finishes. return {name: test.name, caughtError: e} }) )).then(testList => // When all are done, testList.map( // for each result, asyncResult => // test value errors and exceptions. testSuite.addTest(new Mocha.Test(asyncResult.name, function () { if (asyncResult.caughtError) { // Check test object for caught errors throw asyncResult.caughtError } expect(asyncResult.pass).to.be.true })) ) ).then(x => { // When all tests are created, var suiteRun = testRunner.run() // run the tests process.on('exit', (code) => { // and set exit code. process.exit(suiteRun.stats.failures > 0) // Non-zero exit indicates errors. }) }) function asynchStuff (test) { return new Promise(function(resolve, reject) { setTimeout(() => { // console.log(test.name + ' on ' + test.endpoint + ': ' + test.wait + 'ms') if (test.exception) reject(Error(test.exception)) resolve({name: test.name, pass: test.pass}) // only need name and pass }, test.wait) }) } 

La sortie est la même, sauf que mocha ne se plaint pas du test lent et croit que l’outil de test est inférieur à 10 ms. Promise.all attend que toutes les promesses Promise.all puis crée les tests pour valider les résultats ou signaler les exceptions. Cela fait quelques lignes de plus que l’ exécution Embedded car il faut:

  1. Résoudre les exceptions afin que Promise.all() résolu.
  2. Exécutez les tests dans une version finale de Promise.all().then()

Des commentaires décrivant comment les gens choisissent le style à utiliser pourraient guider les autres. Partagez votre sagesse!