Я люблю и Mocha, и BechmarkJS. Я также считаю, что инструменты анализа производительности Chrome великолепны. Тем не менее, с акцентом на разработку через тестирование на одном из моих более крупных усилий; Я обнаружил, что трачу все больше и больше времени на управление двумя наборами тестовых наборов с использованием разных API и очень много времени копаюсь в консоли производительности Chrome. В результате я начал пренебрегать созданием новых тестов и избегал настройки производительности в пользу добавления функциональности… что еще больше усугубляло мое пренебрежение созданием тестов! Чтобы сохранить свою мотивацию, я хотел сократить работу, необходимую для управления наборами тестов, чтобы не сталкиваться с отрицательным стимулом, связанным с разработкой через тестирование, и быстрее сосредоточиться на влиянии усилий по настройке производительности.

Первоначально я начал с создания оболочки вокруг BenchmarkJS для поддержки некоторых возможностей модульного тестирования. Но я обнаружил, что архитектура Benchmark плохо подходит для этой задачи. (Обратите внимание, что авторов нельзя винить в этом, поскольку это не входило в их функциональные задачи). Я попытался инвертировать свой подход и построил оболочку вокруг Mocha. Мне повезло, это оказалось намного проще и идеально соответствовало моим потребностям.

С помощью Benchtest тестирование производительности можно добавить к тестированию Mocha на основе браузера всего одной строкой кода и изменением названий тестов. Просто оберните вызов mocha.run() внутри вызова бенчтеста! Затем добавьте знак # в конце всех тестовых заголовков, которые вы хотите сравнить.

benchtest(mocha.run());

и

it("sleep 100ms #", function(done) {
  const startTime = Date.now();
  while (Date.now() < startTime + 100) { ; };
  done();
});

против

it("sleep 100ms", function(done) {
  const startTime = Date.now();
  while (Date.now() < startTime + 100) { ; };
  done();
});

С Node.js требуется всего три строки кода.

const benchtest = require("benchtest");
afterEach(function () { benchtest.test(this.currentTest); });
after(() => benchtest.run());

Как только ваши тесты будут улучшены, результаты на основе браузера будут дополнены количеством операций в секунду, +/- числом операций и используемым размером выборки.

no-op # Infinity sec +/- 0 100 samples
sleep 100ms # 10 sec +/- 2 11 samples 108ms
sleep 100ms Promise # 10 sec +/- 2 11 samples 101ms
sleep random ms # 21 sec +/- 99 100 samples 45ms
loop 10000 # Infinity sec +/- 0 95 samples
use heap # Infinity sec +/- 0 95 samples

На Node.js или в консоли браузера можно создать таблицу Markdown:

| Name                  | Ops/Sec  | +/- | Sample Size |
| --------------------- | -------- | --- | ----------- |
| no-op #               | Infinity | 0   | 99          |
| sleep 100ms #         | 10       | 7   | 21          |
| sleep 100ms Promise # | 10       | 26  | 21          |
| sleep random ms #     | 21       | 96  | 35          |
| loop 10000 #          | Infinity | 0   | 85          |
| use heap #            | Infinity | 0   | 96          |

Benchtest использует ряд параметров запуска, аналогичных Bechmark.js, для контроля минимального и максимального количества циклов тестирования. Вы также можете указать чувствительность, которая сообщит Benchtest о прекращении тестирования, если результаты находятся в пределах заданного процента друг от друга. См. документацию для получения дополнительной информации.

Есть много людей, которые утверждают, что тестирование производительности и функциональное модульное тестирование — это две разные вещи, и их не следует связывать вместе. Я склонен не согласиться. Я считаю полезным сначала сосредоточиться на функциональном тестировании, а затем просто добавить # в конец имен моих тестовых случаев, чтобы получить некоторые данные о производительности. Затем я могу использовать это для быстрого тестирования попыток настройки. Я также нахожу это полезным для проведения кросс-браузерных сравнений, например:

Оптимизация аналитики массивов в JavaScript: часть первая — итерация функций

Оптимизация аналитики массивов в JavaScript: часть вторая — поиск, пересечение и кросс-продукты

Если вы считаете, что функциональное тестирование и тестирование производительности должны быть полностью разделены, ничто не мешает вам продолжать поддерживать отдельные файлы, а использовать единый инструмент тестирования, Mocha, с облегченной оболочкой, предоставляемой Benchtest.

Поддержите эту статью, чтобы распространить информацию, если вы найдете концепцию Benchtest полезной!