Jest.setTimeout tarafından belirtilen 5000 ms zaman aşımı süresi içinde zaman uyumsuz geri çağrı çağrılmadı


238

Bazı ön uç testleri yapmak için kuklacı ve jest kullanıyorum.

Testlerim aşağıdaki gibi görünüyor:

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

Bazen, testleri yaptığımda her şey beklendiği gibi çalışır. Diğer zamanlarda bir hata alıyorum:

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)

Bu garip çünkü:

  1. Zaman aşımını 30000 olarak belirledim

  2. Bu hatayı alıp almamam çok rastgele görünüyor

Herkes bunun neden olduğunu tahmin edebilir mi?


Hangi satır zaman aşımına uğradı?
lloyd

@Asool GitHub repo sunabilir misiniz? Size bir çözüm sunmamız daha kolay ve hızlı olacaktır. :)
Shishir Anshuman

@Asool, gönderdiğim yanıta ilişkin herhangi bir geri bildirim
Tarun Lalwani

1
test aslında 30000ms için başarısız olabilir ama jest hatası sadece geçtiğiniz değeri içermiyor olabilir mi? anlamı, eğer 0ms zaman aşımı koyarsanız, jest hatası değişir mi?
Nirit Levi

Testlerimde hata ayıklarken bu hatayı gördüm. Bir kesme noktasında
durmak

Yanıtlar:


261

Bu nedenle, burada belirttiğiniz zaman aşımının varsayılan zaman aşımından daha kısa olması gerekir.

Varsayılan zaman aşımı 5000ve çerçeve varsayılan olarak jasminegeçerlidir jest. Ekleyerek testin içindeki zaman aşımını belirleyebilirsiniz

jest.setTimeout(30000);

Ancak bu teste özgüdür. Veya çerçeve için yapılandırma dosyasını ayarlayabilirsiniz.

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)

Bu konuya da bakınız

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

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

PS yazım hatası setupFilesAfterEnv(yani setupFileAfterEnv) aynı hatayı atar.


2
Jest belgeleriyle kolayca bulamadığım bir soruyu cevapladığınız için teşekkür ederiz.
HartleySan

21
Bu bana yardım ettiğinden, onun setupTestFrameworkScriptFileyerini aldığını belirtmek faydalı olabilir setupFilesAfterEnv, bu yüzden olursetupFilesAfterEnv: ["./jest.setup.js"]
Maxim Geerinck

1
Ben jest.setTimeout(10000)de tüm bir yapılandırmaya gerek yoktu bu yüzden bir kenar durumda tek bir test eklenebilir bulundu :)
James

Bir şey mi kaçırdım gerekir ama eklerseniz jest.setTimeout(30000);içinde jest.config.jsalıyorum "ReferenceError: jest tanımlanmadı". const jest = require("jest");Eklemeye çalıştım ama sonra "TypeError: jest.setTimeout bir işlev değil" alıyorum.
Jean Paul

Hata! Çok hızlı okudum: içindeki setupFilesAfterEnvargüman seçeneği jest.config.jskoyduğumuz başka bir dosyaya işaret edecek jest.setTimeout(30000). Bunu yapılandırabilmemiz hoş ama bana göre biraz karmaşık görünüyor.
Jean Paul

64

async/awaitTestten zaman uyumsuz olduğu zamanı çağırmalıdır .

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
Neden doneasenkron fonksiyonda olmalıyız ? Biz sadece Promise veya undefined dönmek değil mi?
Charlie Schliesser

2
Hayır, bu doğru değil. Sözlerini beklediğinden ya da geri dönebileceğin için done () öğesini çağırmana gerek yok page.click. done (), en azından benim durumumda, öncelikle geri aramalarla test için kullanılır.
Justin

2
Teşekkürler çocuklar, donegerekli olmayan geri aramayı kaldırdım .
Schrodinger'in kodu

26
bu orijinal sorudaki kodla aynı değil mi?
Joe,

1
Geri aramada bir parametre ( donebu durumda adlandırılır ) bulunması, Jest'in bu parametre çağrılana kadar beklemesine neden olur. Kullanılmasa bile varlığı önemlidir.
vaughan

54

Jest geliştikçe bu sorunun cevabı değişti. Güncel cevap (Mart 2019):

  1. . Öğesine üçüncü bir parametre ekleyerek herhangi bir testin zaman aşımını geçersiz kılabilirsiniz it. yani.it('runs slow', () => {...}, 9999)

  2. Kullanarak varsayılanı değiştirebilirsiniz jest.setTimeout. Bunu yapmak için:

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

ve

// File: src/jest/defaultTimeout.js
/* global jest */
jest.setTimeout(1000)
  1. Diğerlerinin belirttiği gibi ve bununla doğrudan ilişkili doneolmayan asenkron / bekleme yaklaşımı için gerekli değildir.

5
Bu daha modern versiyonu
jonashdown

23

3000Testlerimin zaman aşımı ile bile hala bazen (rastgele) başarısız olacağını eklemek istiyorum (bu bir yorum için biraz uzun )

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

@ Tarun'un harika cevabı sayesinde, birçok testi düzeltmenin en kısa yolunun:

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

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

9
jest.setTimeout()İçeride aramanıza gerek yok beforeEach, bir kez aramak tüm testler için yeterlidir.
Marcos Pereira

19

Bu nispeten yeni bir güncellemedir, ancak çok daha basittir. Jest 24.9.0 veya daha üstünü kullanıyorsanız testTimeout, yapılandırmanıza ekleyebilirsiniz :

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

17

done();Geri aramaları başlattığınızdan emin olun , aksi takdirde testi geçemez.

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

Done () geri çağrısı olan diğer tüm işlevler için geçerlidir.


1
İyi bahsetti, @ZenVentzi. Teşekkürler :)!
ivanleoncz

11

Jest 24.9+ için, komut satırından zaman aşımını ekleyerek --testTimeout

İşte dokümanlarından bir alıntı

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

3

Geçenlerde farklı bir nedenden dolayı bu sorunla karşılaştı: Eşzamanlı olarak kullanarak bazı testler yapıyordum jest -ive sadece zaman aşımı olurdu. Sebep ne olursa olsun, aynı testleri kullanarak jest --runInBand( -ibir takma ad olsa da) zaman aşımına uğramaz.

Belki bu birine yardım eder ¯\_(:/)_/¯


1

Zaman aşımı sorunu, ağ yavaş olduğunda veya çok sayıda ağ çağrısı kullanıldığında oluşur await, bu senaryolar varsayılan zaman aşımını, yani 5000 ms'yi aşar. Zaman aşımı hatasını önlemek için, zaman aşımını destekleyen globallerin zaman aşımını artırmanız yeterlidir. Globallerin bir listesi ve imzaları burada bulunabilir .
Jest 24.9 için


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

Jest'te ise = 23:

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

Jest'te> 23:

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


0

Birinin yukarıdaki sorunu kullanma yöntemlerini çözmemesi durumunda, asenkron fonkun etrafını bir ok fonksiyonu ile çevreleyerek düzelttim. De olduğu gibi:

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
Bana öyle geliyor ki ok işlevini asenkronun etrafına yerleştirmek, testin testin tamamlanmasını beklemesini söylemeyecek, bu yüzden şimdi bir hata alamasanız da, iş parçacığının dışında çalışan bir testiniz olacak ve a) tüm test paketi, bu test yapılmadan önce tamamlanabilir, bu kodu test etmemek ve b) bu ​​testin içindeki gelecekteki hatalar, paketteki farklı bir test sırasında görünebilir, bu da testlerinizi pul pul ve bakımını zorlaştırabilir.
Mary Shaw

0

Benim durumumda, bu hata rastgele görünmeye başladı ve 30000 zaman aşımı ayarladıktan sonra bile gitmeyecek. Sadece terminaldeki işlemi sonlandırmak ve testleri tekrar çalıştırmak benim için sorunu çözdü. Ayrıca zaman aşımını da kaldırdım ve testler yine geçiyor.


-2

Düğümde ... insanların örnek olarak gördükleri aşağıda, 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);
        });
});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.