Когда запускается Jest
, он ищет все тестовые файлы и запускает каждый из них.
Каждый тестовый файл выполняется в среде, предоставляемой Jest
, которая включает глобальные переменные, такие как describe
, it
, beforeAll
и т. Д. Все эти глобальные переменные имеют параметр обратного вызова, который определяет их поведение.
Когда запускается тестовый файл, выполняется код верхнего уровня ... включая любые вызовы describe
верхнего уровня.
Когда describe
запускает его, регистрирует набор тестов , а затем его обратный вызов вызывается немедленно .
Это отличается от it
, beforeAll
, beforeEach
и т. Д., Где обратный вызов записывается, но не сразу вызывается .
Это означает, что все функции обратного вызова describe
вызываются в глубину в порядке их появления в тестовом файле, как видно из этого простого примера:
describe('1', () => {
console.log('1');
describe('2', () => { console.log('2'); });
describe('3', () => {
console.log('3');
describe('4', () => { console.log('4'); })
describe('5', () => { console.log('5'); })
})
describe('6', () => { console.log('6'); })
})
describe('7', () => {
console.log('7');
it('(since there has to be at least one test)', () => { });
})
... который регистрирует 1
- 7
по порядку.
Этот начальный запуск всех обратных вызовов describe
называется этапом сбора , в течение которого определяются наборы тестов и все обратные вызовы для любых beforeAll
, beforeEach
, it
, test
и т. Д. Собираются
После завершения этапа сбора, Jest
...
запускает все тесты последовательно в порядке, в котором они встречались на этапе сбора, ожидая, пока каждый из них завершится и будет приведен в порядок, прежде чем двигаться дальше.
Для каждого теста (каждая функция обратного вызова, зарегистрированная с помощью глобальных функций it
или test
) Jest
связывает воедино все перед обратными вызовами, сам тестовый обратный вызов и любые последующие обратные вызовы и запускает Результирующие функции в порядке.
Должны ли мы избегать выполнения каких-либо действий в этой части кода и предпочитать использовать beforeAll()
, когда нам нужно совместно использовать данные в этом блоке описания?
Для простых вещей, которые не передаются, хорошо иметь их в describe
:
describe('val', () => {
const val = '1';
it('should be 1', () => {
expect(val).toBe('1'); // Success!
});
});
... но код в describe
может вызвать проблемы с общими данными:
describe('val', () => {
let val;
describe('1', () => {
val = '1';
it('should be 1', () => {
expect(val).toBe('1'); // FAIL! (val gets set to 2 in the second describe)
})
})
describe('2', () => {
val = '2';
it('should be 2', () => {
expect(val).toBe('2'); // Success!
})
})
});
... это можно исправить с помощью before
вызовов:
describe('val', () => {
let val;
describe('1', () => {
beforeEach(() => {
val = '1';
});
it('should be 1', () => {
expect(val).toBe('1'); // Success!
})
})
describe('2', () => {
beforeEach(() => {
val = '2';
});
it('should be 2', () => {
expect(val).toBe('2'); // Success!
})
})
});
... или просто определить область данных до describe
:
describe('val', () => {
describe('1', () => {
const val = '1';
it('should be 1', () => {
expect(val).toBe('1'); // Success!
})
})
describe('2', () => {
const val = '2';
it('should be 2', () => {
expect(val).toBe('2'); // Success!
})
})
});
В вашем примере вы используете window.innerWidth
, который является общим глобальным, так что вы захотите использовать before
функции, так как он не может быть ограничен до describe
.
Также обратите внимание, что вы не можете ничего вернуть из describe
, поэтому, если ваши тесты требуют какой-либо асинхронной настройки, вам нужно будет использовать функцию before
, где вы можете вернуть Promise
для Jest
ждать:
const somethingAsync = () => Promise.resolve('1');
describe('val', () => {
let val;
beforeAll(async () => {
val = await somethingAsync();
});
it('should be 1', () => {
expect(val).toBe('1'); // Success!
});
});