Асинхронный обратный вызов не был вызван в течение времени ожидания 5000 мс, указанного в jest.setTimeout


238

Я использую кукловодов и шутки для запуска некоторых тестов.

Мои тесты выглядят следующим образом:

describe("Profile Tab Exists and Clickable: /settings/user", () => {
    test(`Assert that you can click the profile tab`, async () => {
      await page.waitForSelector(PROFILE.TAB);
      await page.click(PROFILE.TAB);
    }, 30000);
});

Иногда, когда я запускаю тесты, все работает как положено. В других случаях я получаю сообщение об ошибке:

Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.

      at node_modules/jest-jasmine2/build/queue_runner.js:68:21
      at Timeout.callback [as _onTimeout] (node_modules/jsdom/lib/jsdom/browser/Window.js:633:19)

Это странно, потому что:

  1. Я указал время ожидания 30000

  2. Я получаю эту ошибку, казалось бы, очень случайно

Кто-нибудь может догадаться, почему это происходит?


Какая линия истекает?
— Ллойд

@ Asool Не могли бы вы предоставить репозиторий GitHub? Нам будет проще и быстрее предоставить вам решение. :)
— Шишир Аншуман

@ Asool, любые отзывы о ответе, который я разместил
— Тарун Лалвани

1
может ли быть так, что тест на самом деле не проходит 30000 мс, но ошибка от jest просто не включает в себя значение, которое вы передали? это означает, что если вы установите 0 мс, изменится ли шутка?
— Нирит Леви

Я видел эту ошибку, когда отлаживал свои тесты. Остановка в точке останова привела к получению этой ошибки
— Neets

Ответы:


261

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

Тайм-аут по умолчанию равен, 5000а фреймворк по умолчанию - jasmineв случае jest. Вы можете указать время ожидания внутри теста, добавив

jest.setTimeout(30000);

Но это было бы конкретно для теста. Или вы можете настроить файл конфигурации для фреймворка.

https://facebook.github.io/jest/docs/en/configuration.html#setuptestframeworkscriptfile-string

// jest.config.js
module.exports = {
  // setupTestFrameworkScriptFile has been deprecated in
  // favor of setupFilesAfterEnv in jest 24
  setupFilesAfterEnv: ['./jest.setup.js']
}

// jest.setup.js
jest.setTimeout(30000)

Смотрите эту тему также

https://github.com/facebook/jest/issues/5055

https://github.com/facebook/jest/issues/652

PS орфографическая ошибка setupFilesAfterEnv(то есть setupFileAfterEnv) также выдаст ту же ошибку.


2
Спасибо за ответ на вопрос, который я не мог легко найти в документации Jest.
— HartleySan

21
Поскольку это помогло мне, возможно, стоит отметить, что setupTestFrameworkScriptFileоно было заменено setupFilesAfterEnv, поэтому оно становитсяsetupFilesAfterEnv: ["./jest.setup.js"]
— Максим

1
Я также обнаружил, что это jest.setTimeout(10000)может быть добавлено к одному тесту для граничного случая, поэтому не нужно менять весь конфиг :)
— Джеймс

Я должен что - то упустить , но если добавить jest.setTimeout(30000);в jest.config.jsя получаю «ReferenceError: Шутка не определен». Я пытался добавить, const jest = require("jest");но затем я получаю "TypeError: jest.setTimeout не является функцией".
— Жан Поль

К сожалению, я читаю слишком быстро: setupFilesAfterEnvаргумент в jest.config.jsдолжен указывать на другой файл, в который мы помещаем jest.setTimeout(30000)опцию. Приятно, что мы можем настроить это, но мне это кажется немного сложным.
— Жан Поль

64

Он должен вызывать async/awaitасинхронный тест.

describe("Profile Tab Exists and Clickable: /settings/user", () => {
    test(`Assert that you can click the profile tab`, async (done) => {
        await page.waitForSelector(PROFILE.TAB);
        await page.click(PROFILE.TAB);
        done();
    }, 30000);
});

24
Почему мы должны иметь doneасинхронную функцию? Разве мы просто не возвращаем Promise или undefined?
— Чарли Шлиссер

2
Нет, это не правильно. Вам не нужно вызывать done (), так как вы ожидаете своих обещаний или можете просто вернуться page.click. done () используется, по крайней мере, в моем случае, в основном для тестирования с обратными вызовами.
— Джастин

2
Спасибо, ребята, я удалил doneобратный вызов, который не нужен.
— код

26
Разве это не тот же код, что и в оригинальном вопросе сейчас?
— Джо,

1
Присутствие параметра (названного doneв этом случае) в обратном вызове заставляет Jest ждать, пока этот параметр не будет вызван. Его присутствие значимо, даже если оно не используется.
— Вон

54

Ответ на этот вопрос изменился с развитием Jest. Текущий ответ (март 2019 г.):

  1. Вы можете переопределить тайм-аут любого отдельного теста, добавив третий параметр в it. то есть.it('runs slow', () => {...}, 9999)

  2. Вы можете изменить значение по умолчанию, используя jest.setTimeout. Сделать это:

 // config
   "setupFilesAfterEnv": [  // NOT setupFiles
     "./src/jest/defaultTimeout.js"
   ],

и

// File: src/jest/defaultTimeout.js
/* global jest */
jest.setTimeout(1000)
  1. Как и другие отмечали, и не имеют прямого отношения к этому, doneнет необходимости в подходе async / await.

5
это более современная версия
— jonashdown

23

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

Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.

Благодаря отличному ответу @ Tarun, я думаю, что самый короткий способ исправить множество тестов:

describe('puppeteer tests', () => {
  beforeEach(() => {
    jest.setTimeout(10000);
  });

  test('best jest test fest', async () => {
    // blah
  });
});

9
Вам не нужно звонить jest.setTimeout()изнутри. beforeEachОдного вызова достаточно для всех тестов.
— Маркос Перейра

19

Это относительно новое обновление, но оно гораздо более простое. Если вы используете Jest 24.9.0 или выше, вы можете просто добавить testTimeoutк своей конфигурации:

// in jest.config.js
module.exports = {
  testTimeout: 30000
}

17

Обязательно вызывайте done();обратные вызовы, иначе он просто не пройдет тест.

beforeAll((done /* call it or remove it*/) => {
  done(); // calling it
});

Применяется ко всем другим функциям, которые имеют обратный вызов done ().


1
Хорошо упомянуто, @ZenVentzi. Спасибо :)!
— ivanleoncz

11

Для jest 24.9+ Вы также можете установить тайм-аут из командной строки, добавив --testTimeout

Вот выдержка из его документации

--testTimeout=<number>
Default timeout of a test in milliseconds. Default value: 5000.

3

Недавно я столкнулся с этой проблемой по другой причине: я выполнял некоторые тесты синхронно с использованием jest -iвремени ожидания. По каким-то причинам выполнение одних и тех же тестов с использованием jest --runInBand(даже если -iэто псевдоним) не истекает.

Может быть, это кому-то поможет ¯\_(:/)_/¯


1

Проблема тайм-аута возникает, когда сеть работает медленно или с использованием многих сетевых вызовов await, эти сценарии превышают тайм-аут по умолчанию, т.е. 5000 мс. Чтобы избежать ошибки тайм-аута, просто увеличьте тайм-аут глобалов, которые поддерживают тайм-аут. Список глобалов и их подпись можно найти здесь .
Для шутки 24,9


1
// in jest.setup.js
jest.setTimeout(30000)

Если на Jest <= 23:

// in jest.config.js
module.exports = {
  setupTestFrameworkScriptFile: './jest.setup.js'
}

Если на Jest> 23:

// in jest.config.js
module.exports = {
  setupFilesAfterEnv: ['./jest.setup.js']
}


0

В случае, если кто-то не решит проблему, используйте описанные выше методы, я исправил мой, окружив асинхронную функцию функцией стрелки. Как в:

describe("Profile Tab Exists and Clickable: /settings/user", () => {
    test(`Assert that you can click the profile tab`, (() => {
      async () => {
        await page.waitForSelector(PROFILE.TAB)
        await page.click(PROFILE.TAB)
      }
    })(), 30000);
});

1
Мне кажется, что размещение функции стрелки вокруг асинхронного не скажет тесту ждать его завершения, поэтому, хотя вы можете не получить ошибку сейчас, у вас будет тест, запущенный вне его потока и a) весь набор тестов может быть завершен до того, как этот тест будет выполнен, не тестируя этот код, и б) будущие ошибки внутри этого теста могут появиться во время другого теста в наборе, что сделает ваши тесты нестабильными и сложными в обслуживании.
— Мэри Шоу

0

В моем случае эта ошибка начала появляться случайным образом и не исчезнет даже после установки времени ожидания 30000. Простое завершение процесса в терминале и повторный запуск тестов решили эту проблему для меня. Я также удалил тайм-аут, и тесты все еще проходят снова.


-2

В Node ... то, что я вижу, люди сделали в качестве примера ниже, используя fakeEventEmitter

import { EventEmitter } from 'events';
describe('your case', () => {
 let fakeEventEmitter: EventEmitter;
 beforeEach(async () => {
   fakeEventEmitter = new EventEmitter();
   (fakeEventEmitter as any).pid = 123;
 }),
 it('should do something you want to do', done => {
            anAsynchronouseFunction(testOptions, context).subscribe({
                complete: () => {
                    expect(something).toBeTruthy();
                    done();
                }
            });
            fakeEventEmitter.emit('exit', 0);
        });
});
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.