Зворотний виклик Async не викликався протягом 5000 мс, визначеного ji.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 мс, але помилка від жарту просто не включає значення, яке ви пройшли? значить, якщо ви поставите 0 мс тайм-аут, чи змінюється помилка помилок?
Ніріт Леві

Я бачив цю помилку, коли налагоджував свої тести. Зупинка на
точці перерви

Відповіді:


259

Отже час очікування, який ви вказали тут, повинен бути меншим, ніж час очікування за замовчуванням.

Час очікування за замовчуванням є, 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/isissue/5055

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

Неправильне написання PS setupFilesAfterEnv(тобто setupFileAfterEnv) також призведе до тієї ж помилки.


2
Дякую за відповідь на запитання, яке я не міг легко знайти через документацію Jest.
HartleySan

21
Оскільки це допомогло мені, можливо, варто зауважити, що його setupTestFrameworkScriptFileзамінили setupFilesAfterEnv, так це стаєsetupFilesAfterEnv: ["./jest.setup.js"]
Maxim Geerinck

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функцію асинхронізації? Чи не просто ми повернемо Обіцянку чи невизначено?
Чарлі Шліссер

2
Ні, це не правильно. Вам не потрібно дзвонити виконано (), оскільки ви чекаєте своїх обіцянок або можете просто повернутися 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 / очікувати.

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

Це відносно нове оновлення, але воно набагато прямо вперед. Якщо ви використовуєте jer 24.9.0 або вище, ви можете просто додати його testTimeoutдо конфігурації:

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

17

Переконайтесь, що викликати done();зворотні дзвінки, інакше це не просто пройде тест.

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

Застосовується до всіх інших функцій, які мають завершений () зворотний виклик.


1
Добре згадується, @ZenVentzi. Дякую :)!
ivanleoncz

11

Для жарту 24,9+, Ви також можете встановити тайм-аут із командного рядка, додавши --testTimeout

Ось уривок із його документів

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

3

Нещодавно я зіткнувся з цим питанням з іншої причини: я виконував деякі тести синхронно, використовуючи jest -i, і це був би просто час. З будь-яких міркувань, запускайте ті ж тести, використовуючи jest --runInBand(хоча-i це і має бути псевдонім), не закінчується.

Можливо, це комусь допоможе ¯\_(:/)_/¯


1

Проблема з тимчасовим очікуванням виникає, коли будь-яка мережа повільна або використовується багато мережевих дзвінків await, ці сценарії перевищують час очікування за замовчуванням, тобто 5000 мс. Щоб уникнути помилки тайм-ауту, просто збільште тайм-аут глобалістів, які підтримують тайм-аут. Перелік глобалів та їх підпис можна знайти тут .
Для Jest 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
Мені здається, що розміщення функції стрілки навколо асинхронізу не дасть тесту зачекати, коли тест завершиться, тому, якщо ви зараз не отримаєте помилку, у вас буде тест, що працює поза його потоком, і а) Весь набір тестів може завершитися до цього тесту, не тестуючи цей код і б) майбутні помилки всередині цього тесту можуть з’явитися під час іншого тесту в наборі, що зробить ваші тести розмитими і важкими у обслуговуванні.
Мері Шоу

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.