Gọi lại Async không được gọi trong khoảng thời gian chờ 5000ms được chỉ định bởi jest.setTimeout


238

Tôi đang sử dụng con rối và trò hề để chạy một số bài kiểm tra mặt trước.

Các xét nghiệm của tôi trông như sau:

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);
});

Đôi khi, khi tôi chạy thử nghiệm, mọi thứ hoạt động như mong đợi. Lần khác, tôi gặp lỗi:

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)

Điều này là lạ bởi vì:

  1. Tôi đã chỉ định thời gian chờ là 30000

  2. Có hay không tôi nhận được lỗi này có vẻ rất ngẫu nhiên

Có ai có thể đoán tại sao điều này lại xảy ra không?


Dòng nào là thời gian ra?
lloyd

@Asool Bạn có thể cung cấp repo GitHub không? Chúng tôi sẽ dễ dàng hơn và nhanh hơn để chúng tôi cung cấp cho bạn một giải pháp. :)
Shishir Anshuman

@Asool, mọi phản hồi về câu trả lời tôi đã đăng
Tarun Lalwani

1
có thể là thử nghiệm thực sự thất bại trong 30000ms nhưng lỗi từ jest đơn giản là không bao gồm giá trị bạn đã vượt qua? có nghĩa là, nếu bạn hết thời gian 0ms, lỗi jest có thay đổi không?
Nirit Levi

Tôi đã thấy lỗi này khi tôi gỡ lỗi các bài kiểm tra của mình. Dừng lại ở một điểm dừng gây ra lỗi này
Neets

Câu trả lời:


259

Vì vậy, thời gian chờ bạn chỉ định ở đây cần phải ngắn hơn thời gian chờ mặc định.

Thời gian chờ mặc định là 5000và khung theo mặc định là jasminetrong trường hợp jest. Bạn có thể chỉ định thời gian chờ bên trong bài kiểm tra bằng cách thêm

jest.setTimeout(30000);

Nhưng điều này sẽ được cụ thể để kiểm tra. Hoặc bạn có thể thiết lập tập tin cấu hình cho khung.

https://facebook.github.io/jest/docs/en/configuration.html#setuptestframeworkscriptfile- chuỗi

// 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)

Xem chủ đề này cũng

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

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

Lỗi chính tả PS setupFilesAfterEnv(nghĩa là setupFileAfterEnv) cũng sẽ đưa ra lỗi tương tự.


2
Cảm ơn vì đã trả lời một câu hỏi mà tôi không thể dễ dàng tìm thấy qua tài liệu của Jest.
HartleySan

21
Vì điều này đã giúp tôi, có thể đáng chú ý rằng nó setupTestFrameworkScriptFileđã được thay thế setupFilesAfterEnv, vì vậy nó trở thànhsetupFilesAfterEnv: ["./jest.setup.js"]
Maxim Geerinck

1
Tôi cũng thấy rằng jest.setTimeout(10000)có thể được thêm vào một thử nghiệm duy nhất cho trường hợp cạnh nên toàn bộ cấu hình không cần thay đổi :)
James

Tôi nên bỏ lỡ điều gì đó nhưng nếu tôi thêm jest.setTimeout(30000);vào, jest.config.jstôi nhận được "ReferenceError: jest không được xác định". Tôi đã cố gắng thêm const jest = require("jest");nhưng sau đó tôi nhận được "TypeError: jest.setTimeout không phải là một chức năng".
Jean Paul

Rất tiếc, tôi đọc quá nhanh: setupFilesAfterEnv đối số jest.config.jssẽ trỏ đến một tệp khác nơi chúng tôi đặt jest.setTimeout(30000)tùy chọn. Thật tuyệt khi chúng ta có thể cấu hình cái này nhưng có vẻ như tôi hơi phức tạp.
Jean Paul

64

Nó sẽ gọi async/awaitkhi nó không đồng bộ từ kiểm tra.

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
Tại sao chúng ta nên có donechức năng async? Chúng ta không đơn giản trả lại Promise hay không xác định?
Charlie Schliesser

2
Không, điều này không chính xác. Bạn không cần phải gọi xong () vì bạn đang chờ đợi lời hứa hoặc bạn có thể quay lại page.click. xong () được sử dụng, ít nhất là trong trường hợp của tôi, chủ yếu để thử nghiệm với các cuộc gọi lại.
Justin

2
Cảm ơn các bạn, tôi đã loại bỏ các donecuộc gọi lại không cần thiết.

26
Bây giờ đây không phải là mã giống như trong câu hỏi ban đầu sao?
Joe

1
Sự hiện diện của một tham số (được đặt tên donetrong trường hợp này) trong cuộc gọi lại khiến Jest phải đợi cho đến khi tham số này được gọi. Sự hiện diện của nó rất có ý nghĩa ngay cả khi nó không được sử dụng.
vaughan

54

Câu trả lời cho câu hỏi này đã thay đổi khi Jest đã phát triển. Câu trả lời hiện tại (Tháng 3 năm 2019):

  1. Bạn có thể ghi đè thời gian chờ của bất kỳ thử nghiệm riêng lẻ nào bằng cách thêm tham số thứ ba vào it . I E.it('runs slow', () => {...}, 9999)

  2. Bạn có thể thay đổi mặc định bằng cách sử dụng jest.setTimeout. Để làm điều này:

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

// File: src/jest/defaultTimeout.js
/* global jest */
jest.setTimeout(1000)
  1. Giống như những người khác đã lưu ý, và không liên quan trực tiếp đến điều này, donekhông cần thiết với phương pháp async / await.

5
đây là phiên bản hiện đại hơn
jonashdown

23

Tôi muốn thêm (điều này hơi dài cho một nhận xét) rằng ngay cả khi hết thời gian 3000thử nghiệm, đôi khi tôi vẫn ngẫu nhiên (ngẫu nhiên) thất bại với

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

Nhờ câu trả lời tuyệt vời của @ Tarun, tôi nghĩ cách ngắn nhất để khắc phục rất nhiều bài kiểm tra là:

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

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

9
Bạn không cần phải gọi jest.setTimeout()bên trong beforeEach, gọi nó một lần là đủ cho tất cả các bài kiểm tra.
Marcos Pereira

19

Đây là một bản cập nhật tương đối mới nhưng nó thẳng hơn nhiều. Nếu bạn đang sử dụng jest 24.9.0 trở lên, bạn chỉ cần thêm testTimeoutvào cấu hình của mình:

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

17

Hãy chắc chắn để gọi done();lại các cuộc gọi lại hoặc nó sẽ không vượt qua bài kiểm tra.

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

Áp dụng cho tất cả các hàm khác có hàm gọi lại được thực hiện ().


1
Được đề cập tốt, @ZenVentzi. Cảm ơn :)!
ivanleoncz

11

Đối với jest 24.9+, Bạn cũng có thể đặt thời gian chờ từ dòng lệnh bằng cách thêm --testTimeout

Đây là một đoạn trích từ tài liệu của nó

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

3

Gần đây tôi gặp vấn đề này vì một lý do khác: tôi đang chạy một số thử nghiệm đồng bộ bằng cách sử dụng jest -ivà nó sẽ chỉ là thời gian chờ. Vì bất kỳ lý do gì, việc chạy các bài kiểm tra tương tự bằng cách sử dụng jest --runInBand(mặc dù -icó nghĩa là bí danh) không hết thời gian.

Có lẽ điều này sẽ giúp ai đó ¯\_(:/)_/¯


1

Sự cố hết thời gian xảy ra khi một trong hai mạng bị chậm hoặc nhiều cuộc gọi mạng được thực hiện bằng cách sử dụng await, các tình huống này vượt quá thời gian chờ mặc định tức là 5000ms. Để tránh lỗi hết thời gian, chỉ cần tăng thời gian chờ của các quả cầu hỗ trợ thời gian chờ. Một danh sách toàn cầu và chữ ký của họ có thể được tìm thấy ở đây .
Dành cho ngày 24.9


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

Nếu trên Jest <= 23:

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

Nếu trên Jest> 23:

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


0

Trong trường hợp ai đó không khắc phục sự cố sử dụng các phương pháp ở trên, tôi đã sửa lỗi của tôi bằng cách bao quanh func async bằng một hàm mũi tên. Như trong:

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
Dường như với tôi, việc đặt chức năng mũi tên xung quanh async sẽ không cho phép kiểm tra chờ đợi bài kiểm tra hoàn tất, vì vậy trong khi bạn có thể không gặp lỗi ngay bây giờ, bạn sẽ có một bài kiểm tra chạy bên ngoài luồng của nó và a) toàn bộ bộ kiểm tra có thể hoàn thành trước khi thử nghiệm này được thực hiện, không kiểm tra mã này và b) các lỗi trong tương lai trong thử nghiệm này có thể xuất hiện trong một thử nghiệm khác trong bộ thử nghiệm, khiến cho các thử nghiệm của bạn không ổn định và khó bảo trì.
Mary Shaw

0

Trong trường hợp của tôi, lỗi này bắt đầu xuất hiện ngẫu nhiên và sẽ không biến mất ngay cả sau khi đặt thời gian chờ là 30000. Chỉ cần kết thúc quá trình trong thiết bị đầu cuối và chạy lại các thử nghiệm đã giải quyết vấn đề cho tôi. Tôi cũng đã loại bỏ thời gian chờ và các bài kiểm tra vẫn tiếp tục trôi qua.


-2

Trong Node ... những gì tôi thấy mọi người đã làm như một ví dụ bên dưới, sử dụng 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);
        });
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.