Comment puis-je exécuter des tests asynchrones Mocha (NodeJS) dans l’ordre?

Cette question concerne le framework de test Mocha pour NodeJS.

Le comportement par défaut semble être de démarrer tous les tests, puis de traiter les rappels asynchrones au fur et à mesure qu’ils entrent.

Lors de l’exécution de tests asynchrones, je souhaiterais exécuter chaque test après l’appel de la partie asynchrone de la précédente.

Comment puis-je faire ceci?

Le point n’est pas tant que “le code structuré s’exécute dans l’ordre dans lequel vous l’avez structuré” (stupéfiez-vous!) Pour réitérer le problème – les tests plus bas dans la chaîne (exécution synchrone) ne peuvent pas garantir que les conditions requirejses, définies par les tests asynchrones, seront prêtes au moment de leur exécution.

Donc, si vous exigez que certaines conditions soient définies dans les premiers tests (comme un jeton de connexion ou similaire), vous devez utiliser des hooks comme before() pour tester ces conditions avant de continuer.

Emballez les tests dépendants dans un bloc et lancez une async before accrocher (notez le ‘fait’ dans le bloc avant):

 var someCondition = false // ... your Async tests setting conditions go up here... describe('is dependent on someCondition', function(){ // Polls `someCondition` every 1s var check = function(done) { if (someCondition) done(); else setTimeout( function(){ check(done) }, 1000 ); } before(function( done ){ check( done ); }); it('should get here ONLY once someCondition is true', function(){ // Only gets here once `someCondition` is satisfied }); }) 

Je suis surpris par ce que vous avez écrit comme je l’utilise. J’utilise mocha avec les tests de style bdd (decris / it), et je viens d’append quelques consoles.log à mes tests pour voir si tes affirmations tiennent à mon cas, mais apparemment pas.

Voici le fragment de code que j’ai utilisé pour voir l’ordre “end1” et “start1”. Ils ont été correctement commandés.

 describe('Characters start a work', function(){ before(function(){ sinon.stub(statusapp, 'create_message'); }); after(function(){ statusapp.create_message.restore(); }); it('creates the events and sends out a message', function(done){ draftwork.start_job(function(err, work){ statusapp.create_message.callCount.should.equal(1); draftwork.get('events').length.should.equal( statusapp.module('jobs').Jobs.get(draftwork.get('job_id')).get('nbr_events') ); console.log('end1'); done(); }); }); it('sortingggers work:start event', function(done){ console.log('start2'); statusapp.app.bind('work:start', function(work){ work.id.should.equal(draftwork.id); statusapp.app.off('work:start'); done(); }); 

Bien sûr, cela aurait pu se produire par accident, mais j’ai beaucoup de tests et s’ils couraient en parallèle, j’aurais certainement des conditions de course que je n’ai pas.

S’il vous plaît, référez-vous aussi à ce problème à partir du tracker de problème moka. Selon lui, les tests sont exécutés de manière synchrone.

Je voulais résoudre ce problème avec notre application, mais la réponse acceptée ne nous convenait pas. Surtout dans someCondition ce ne serait jamais vrai.

Nous utilisons des promesses dans notre application et celles-ci ont facilité la structuration des tests en conséquence. La clé rest cependant de retarder l’exécution via le hook before :

 var assert = require( "assert" ); describe( "Application", function() { var application = require( __dirname + "/../app.js" ); var bootPromise = application.boot(); describe( "#boot()", function() { it( "should start without errors", function() { return bootPromise; } ); } ); describe( "#shutdown()", function() { before( function() { return bootPromise; } ); it( "should be able to shut down cleanly", function() { return application.shutdown(); } ); } ); } ); 

utiliser mocha-steps

Il garde les tests séquentiels indépendamment du fait qu’ils soient asynchrones ou non (c.-à-d. que vos fonctions done fonctionnent toujours exactement comme elles l’ont fait). C’est un remplacement direct pour it et vous utilisez plutôt step