Mocha: Первый модульный тест всегда медленнее остальных.

Созданный на 10 нояб. 2017  ·  3Комментарии  ·  Источник: mochajs/mocha

Предпосылки

  • [x] Проверено, что ваша проблема еще не зарегистрирована путем перекрестных ссылок на проблемы с меткой common mistake
  • [x] Проверены проблемы следующего поколения ES и проблемы синтаксиса с использованием той же среды и/или конфигурации транспилятора без Mocha, чтобы убедиться, что это не просто функция, которая на самом деле не поддерживается в рассматриваемой среде, или ошибка в вашем коде. .
  • [x] «Смоук протестировал» код, который необходимо протестировать, запустив его вне реального набора тестов, чтобы лучше понять, связана ли проблема с тестируемым кодом, использованием Mocha или самим Mocha.
  • [x] Устранено несоответствие между локальной и глобальной версиями Mocha. Вы можете найти их с помощью:
    node node_modules/.bin/mocha --version (локальный) и mocha --version (глобальный). Мы рекомендуем избегать использования глобально установленного Mocha.

Описание

По какой-то причине первый модульный тест моего тестового костюма всегда медленнее остальных. При выполнении тестов в моей консоли я получаю что-то вроде:

√ unit test A (483ms)
√ unit test B

Но в коде, если я изменю модульный тест B на выше модульного теста A, я получу следующее:
√ unit test B (470ms)
√ unit test A

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

Тест примерно такой:

let target = require('...');

describe('Module of unit tests', function () {
  this.timeout(1000);
  before(function () {
    ...
    target = proxyquire('...', {
      'node-chartist': sinon.stub().resolves('...'),
      'ws': function(){
        return {
          'close': function(){ /*Do nothing*/ },
          'send': function(){ /*Do nothing*/ },
          'on': function(arg, callback){
            ...
          }
        };
      }
    });
  });

  //Warning happens here
  it('unit test A', function () {
    ...
    target();
    ...
  });

  //If this unit test goes above unit test A, this will be the one to get the warning.
  it('unit test B', function () {
    ...
    target();
    ...
  });
})

Действия по воспроизведению

Я безуспешно пытался воспроизвести в других проектах, поэтому сомневаюсь, что вы сможете это сделать, но я делаю следующее:

1) Выполните тесты с модульным тестом A выше.
2) Выполните тесты с модульным тестом B выше.

Ожидаемое поведение: [Что вы ожидаете]
Не получать никаких предупреждений о времени в обоих случаях.

Фактическое поведение: [Что происходит на самом деле]
Первый модульный тест всегда получает предупреждение о времени.

Как часто воспроизводится: [Какой процент времени он воспроизводится?]
Примерно в 90% случаев.

Версии

узел v6.11.4
нпм 3.10.10
мокко 4.0.1
Синон 4.1.2
чай 3.5.0
прокси 1.8.0

Дополнительная информация

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

Я также отлаживал код, который тестирует модульный тест, и в любом случае я действительно не вижу причин для задержки.

Самый полезный комментарий

Привет СкоттФриКод,

Спасибо за ответ, это было очень полезно. Проблема возникла из-за того, что я делаю несколько заглушек с помощью proxyquire, и по умолчанию модули npm загружаются, даже если они заглушены. В моем случае у меня есть модуль с именем node-chartist, который загружался во время первого модульного теста, и поэтому он был медленнее, чем другие.

Чтобы решить эту проблему, мне пришлось использовать метод noCallThru() из proxyquire, который заставляет proxyquire не загружать исходные зависимости.

Спасибо за помощь.

С уважением,

Даниэль Серрао

Все 3 Комментарий

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

Возможно, что код, даже если в целом он не обязательно медленный, инициализирует что-то в первый раз, а затем каким-то образом сохраняется (например, кеш Node require или кеш данных на уровне файловой системы с диска, или оптимизация повторного использования, встроенная в какой-либо библиотечный код), или что движок JavaScript ищет оптимизации в коде после того, как он запускается один раз, или что-то в этом роде. Вы также можете вообще поместить его за пределы набора тестов, хотя это менее вероятно, что сработает - для нескольких типов кешей у этого будет больше шансов, что кеш закончится где-то между загрузкой тестовых файлов и фактическим выполнением тестов этого конкретного файла ( с другой стороны, если хук before сработал, а за пределами тестового набора — нет, это может сузить круг вопросов, связанных с кэшированием или оптимизацией...).

(И совсем другое примечание: скорее обходной путь, чем решение — для тех, кто просто хочет подавить предупреждение о времени, есть вариант slow можно использовать с параметром timeout .)

Привет СкоттФриКод,

Спасибо за ответ, это было очень полезно. Проблема возникла из-за того, что я делаю несколько заглушек с помощью proxyquire, и по умолчанию модули npm загружаются, даже если они заглушены. В моем случае у меня есть модуль с именем node-chartist, который загружался во время первого модульного теста, и поэтому он был медленнее, чем другие.

Чтобы решить эту проблему, мне пришлось использовать метод noCallThru() из proxyquire, который заставляет proxyquire не загружать исходные зависимости.

Спасибо за помощь.

С уважением,

Даниэль Серрао

Рад, что смог помочь тебе разобраться! Дайте нам знать, если вам нужно что-то еще.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги