Timeout настройки для асинхронных тестов

В Jasmine асинхронные тесты требуют особого подхода к управлению временем выполнения. По умолчанию Jasmine накладывает лимит на продолжительность выполнения каждого it блока. Если асинхронная операция не завершилась в пределах этого времени, тест помечается как failed с ошибкой о превышении таймаута.

Настройка глобального таймаута

Глобальный таймаут для всех асинхронных тестов задаётся через свойство jasmine.DEFAULT_TIMEOUT_INTERVAL. Оно определяет максимальное время в миллисекундах, которое Jasmine будет ждать завершения асинхронного кода:

jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; // 10 секунд

Это полезно, когда большинство асинхронных операций требует больше стандартного времени (по умолчанию 5 секунд).

Таймаут для отдельного теста

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

it("асинхронный тест с большим таймаутом", function(done) {
    setTimeout(function() {
        expect(true).toBe(true);
        done();
    }, 7000);
}, 8000); // таймаут 8 секунд

Здесь Jasmine будет ожидать завершения теста до 8 секунд, даже если глобальный таймаут меньше.

Работа с промисами и async/await

С современным синтаксисом async/await таймауты обрабатываются так же, но через стандартный механизм Jasmine:

it("асинхронный тест с промисом", async function() {
    const result = await fetchData(); // функция возвращает промис
    expect(result).toEqual({status: "ok"});
}, 15000); // таймаут 15 секунд

Использование async/await упрощает чтение и поддержку тестов, позволяя избежать явного вызова done().

Проблемы с слишком коротким таймаутом

Слишком короткий таймаут может привести к ложным падениям тестов, особенно если асинхронная операция зависит от сети или внешних сервисов. Для тестов, использующих HTTP-запросы или взаимодействие с базой данных, рекомендуется устанавливать индивидуальные таймауты, превышающие среднее время отклика.

Изменение таймаута внутри beforeEach и afterEach

Асинхронные настройки в хуках beforeEach и afterEach также подчиняются таймаутам Jasmine. Можно задавать глобальный таймаут или переопределять его локально:

beforeEach(function(done) {
    setTimeout(function() {
        setupDatabase();
        done();
    }, 4000);
}, 5000); // таймаут 5 секунд для этого beforeEach

Если таймаут превышен, тест не выполнится, а ошибка будет отображена в отчёте Jasmine.

Советы по использованию таймаутов

  • Всегда устанавливать глобальный таймаут, достаточный для большинства тестов.
  • Для длительных асинхронных операций использовать локальный таймаут на конкретном тесте.
  • Не использовать чрезмерно длинные таймауты без необходимости — это замедляет тестирование.
  • Для тестов с сетевыми запросами рекомендуется имитировать ответы с помощью моков, чтобы избежать зависания из-за внешних факторов.
  • В сочетании с async/await таймауты Jasmine остаются эффективным механизмом контроля долгих операций, предотвращая бесконечное ожидание.

Примеры комбинаций

describe("Тесты с разными таймаутами", function() {
    beforeEach(function(done) {
        initializeHeavySetup(done);
    }, 10000);

    it("короткий асинхронный тест", async function() {
        const data = await quickFetch();
        expect(data).toBeDefined();
    }, 3000);

    it("длительный асинхронный тест", function(done) {
        setTimeout(function() {
            expect(true).toBe(true);
            done();
        }, 12000);
    }, 15000);
});

В этом примере для каждого теста и beforeEach задаются индивидуальные таймауты, обеспечивая точное управление временем выполнения и предотвращая ложные ошибки из-за превышения времени.


Контроль таймаутов является критически важным инструментом при тестировании асинхронного кода в Jasmine. Правильная настройка позволяет избегать неожиданных падений тестов и делает тестовый процесс стабильным и предсказуемым.