Установить ограничение по времени на тест Jest?

Я запускаю набор тестов с Jest, чтобы продемонстрировать Big O, используя два разных метода для Фибоначчи.

const fastFib = require('./../fastFib');
const slowFib = require('./../slowFib');

test('Fast way of getting Fibonacci of 44', () => {
  expect(fastFib(44)).toBe(701408733);
});

test('Slow way of getting Fibonacci of 44', () => {
  expect(slowFib(44)).toBe(701408733);
});

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

test('Slow way of getting Fibonacci of 44', () => {
  expect(slowFib(44)).toBe(701408733);
}, 5000);

Есть ли способ указать максимальное время выполнения функции с помощью Jest?


Поделюсь slowFib.js для справки:

function fib(n) {
  return (n<=1) ? n : fib(n - 1) + fib(n - 2);
}

module.exports = fib;

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

Andrea Franchini 28.05.2019 17:53
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
1
2 526
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Я думаю, вам нужно будет реализовать свой собственный таймер (с setTimeout или с помощью Promises). Одной из альтернатив может быть использование ключевого слова async для вашей функции, чтобы она работала со встроенным параметром:

test('Slow way of getting Fibonacci of 44', async () => {
  expect(slowFib(44)).toBe(701408733);
}, 5000);

спасибо, но тест все еще проходит, хотя это занимает больше 5 секунд.

Philip Kirkbride 28.05.2019 17:20
Ответ принят как подходящий

поэтому ваш тест приостанавливается из-за выполнения синхронизации - нет возможности прервать это по тайм-ауту. Вам нужно «разделить исполнение». Следующая версия не работает для меня:

test('Slow way of getting Fibonacci of 44', (done) => {
  expect(slowFib(44)).toBe(701408733);
  setTimeout(done, 10); // smallest timeout possible to make different macrotask
}, 5000);

PS Я также считаю, что это должно быть достигнуто путем оценки теста async, но пока не понял, как именно.

[UPD] вы действительно можете достичь своей цели, не используя тайм-аут теста:

test('Slow way of getting Fibonacci of 44', () => {
  const start = new Date();
  expect(slowFib(44)).toBe(701408733);
  expect(new Date() - start).toBeLessThan(5000);
});

У меня до сих пор проходит. Я обновил свой вопрос содержанием slowFib.js, может быть, это имеет значение?

Philip Kirkbride 29.05.2019 20:09

мне это не удается. не уверен, как отлаживать. какой версией Jest пользуетесь?

skyboyer 29.05.2019 20:48

package.json говорит «шутка»: «^ 24.8.0»

Philip Kirkbride 29.05.2019 21:10

Какую версию ты используешь?

Philip Kirkbride 31.05.2019 16:37

Я использую "23.6.0"

skyboyer 31.05.2019 16:44

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

Philip Kirkbride 05.06.2019 18:59

рад помочь! в любом случае на самом деле понятия не имею, почему тайм-аут в it() не работает для вас

skyboyer 05.06.2019 20:08

В вашем тестовом файле вы можете установить jest.setTimeout(5000); который переопределяет время ожидания по умолчанию для тестового примера в шутку

Вот функции (удобные для машинописи), вдохновленные предложением @skyboyer.
(протестировано с использованием Jest 24.8.0, но должно быть актуально для любой версии)

// Takes a threshold and a callback.
// if the callback didn't run within the threshold, the returned function will evaluate to a rejected promise.
// else, the returned function will evaluate to a resolved promise with the value returned by 'cb' (T)
const resolveWithin = <T>(threshold: number, cb: () => T): () => Promise<T> => {
  return () => {
    const start = Date.now();

    return Promise.resolve(cb()).then((t: T) => {
      const elapsed = Date.now() - start;

      if (elapsed > threshold) {
        return Promise.reject(elapsed);
      }

      return Promise.resolve(t);
    });
  }
};

// Uses "resolveWithin" to ensure a test has run within the threshold.
const withIn = <T>(threshold: number, fn: () => T): () => Promise<T> => {
  const cb = resolveWithin(threshold, fn);

  // @ts-ignore
  return () => {
    return cb().catch((elapsed) => {
      expect(elapsed).toBeLessThanOrEqual(threshold);
    })
  }
};

it("example", withIn(1000, () => { ... }));

it("example", withIn(1000, async () => { ... }));

Примечание относительно ответов @Khaled Osman / @HRK44.

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

Другие вопросы по теме