Как выполнить асинхронные тесты Mocha (NodeJS) по порядку? - PullRequest
49 голосов
/ 16 марта 2012

Этот вопрос относится к инфраструктуре тестирования Mocha для NodeJS.

Кажется, что стандартным поведением является запуск всех тестов, а затем обработка асинхронных обратных вызовов по мере их поступления.

При запускеасинхронные тесты, я хотел бы запускать каждый тест после асинхронной части предыдущей.

Как я могу это сделать?

Ответы [ 4 ]

35 голосов
/ 20 октября 2012

Дело не столько в том, что «структурированный код выполняется в том порядке, в котором вы его структурировали» (удивительно!), А в том, что, как подсказывает @chrisdew, порядок возврата для асинхронных тестов не может быть гарантирован. Чтобы переформулировать проблему - тесты, которые находятся ниже по цепочке (синхронного выполнения) , не могут гарантировать , что требуемые условия, установленные асинхронными тестами, будут готовы к тому времени, когда они будут выполняться.

Таким образом, если вы хотите, чтобы в первых тестах были заданы определенные условия (например, токен для входа в систему или аналогичный), вы должны использовать такие хуки, как before(), которые проверяют эти условия перед продолжением.

Оберните зависимые тесты в блок и запустите на них async before (обратите внимание на 'done' в блоке before):

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
  });

})
9 голосов
/ 17 марта 2012

Я удивлен тем, что вы написали, когда я пользуюсь. Я использую mocha с тестами в стиле bdd (описать / it) и просто добавил в мои тесты несколько console.logs, чтобы проверить, соответствуют ли ваши претензии моему случаю, но, по-видимому, они не соответствуют.

Вот фрагмент кода, который я использовал, чтобы увидеть порядок «end1» и «start1». Они были правильно заказаны.

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('triggers 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();
      });

Конечно, это могло произойти и случайно, но у меня много тестов, и если бы они работали параллельно, у меня наверняка были бы условия гонки, которых у меня нет.

Пожалуйста, обратитесь к этой проблеме также из системы отслеживания проблем Мокко. Согласно ему, тесты запускаются синхронно.

6 голосов
/ 21 сентября 2016

use mocha-steps

он сохраняет тесты последовательными независимо от того, являются они асинхронными или нет (т.е. ваши done функции по-прежнему работают точно так же, как и они).Это прямая замена для it, и вместо этого вы используете step

5 голосов
/ 23 апреля 2014

Я хотел решить эту же проблему с нашим приложением, но принятый ответ не сработал для нас.Тем более что someCondition никогда не будет правдой.

Мы используем обещания в нашем приложении, и это позволило очень легко структурировать тесты соответствующим образом.Однако ключ по-прежнему заключается в задержке выполнения через хук 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();
    } );
  } );
} );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...