В тестировании на JavaScript с использованием Jasmine крайне важно
управлять подготовкой и очисткой окружения для тестов.
beforeAll и afterAll предоставляют возможность
выполнять код один раз до всех тестов в блоке describe и
один раз после всех тестов соответственно. Эти функции помогают
оптимизировать тестирование, уменьшая дублирование кода и улучшая
читаемость тестов.
beforeAll вызывается один раз
перед выполнением всех тестов внутри блока
describe.
describe('Пример beforeAll', () => {
let data;
beforeAll(() => {
data = { message: 'Инициализация' };
console.log('Выполняется один раз перед всеми тестами');
});
it('тест 1', () => {
expect(data.message).toBe('Инициализация');
});
it('тест 2', () => {
expect(data.message).toBe('Инициализация');
});
});
afterAll вызывается один раз
после выполнения всех тестов внутри блока
describe.
describe('Пример afterAll', () => {
let resource;
beforeAll(() => {
resource = { connected: true };
});
it('тест с использованием ресурса', () => {
expect(resource.connected).toBeTrue();
});
afterAll(() => {
resource.connected = false;
console.log('Очистка ресурсов после всех тестов');
});
});
beforeEach и afterEachbeforeEach выполняется перед каждым
тестом в блоке describe.afterEach выполняется после каждого
теста.beforeAll и afterAll выполняются
только один раз вне зависимости от количества
тестов.Использование beforeAll и afterAll снижает
нагрузку на систему, когда подготовка или очистка ресурсов требует
значительных затрат.
describe('Сравнение beforeAll и beforeEach', () => {
let counter = 0;
beforeAll(() => {
counter += 10;
});
beforeEach(() => {
counter += 1;
});
it('тест 1', () => {
expect(counter).toBe(11); // 10 + 1
});
it('тест 2', () => {
expect(counter).toBe(12); // 11 + 1
});
});
beforeAll и afterAll поддерживают
асинхронный код через Promise или
async/await. Это полезно для работы с базами данных,
внешними API или таймерами.
describe('Асинхронные beforeAll и afterAll', () => {
let data;
beforeAll(async () => {
data = await fetchDataFromServer(); // пример асинхронного вызова
});
it('тест с асинхронными данными', () => {
expect(data).toBeDefined();
});
afterAll(async () => {
await cleanUpServerData(data.id);
});
});
Если beforeAll не завершится успешно, тесты не
будут выполняться, а Jasmine выдаст ошибку. Аналогично, ошибки
в afterAll влияют на отчёт о завершении тестов.
describebeforeAll и afterAll могут использоваться в
вложенных блоках describe, при этом
порядок выполнения строго подчинён иерархии:
beforeAll внешнего блока.beforeAll вложенного блока.afterAll вложенного блока.afterAll внешнего блока.describe('Внешний блок', () => {
beforeAll(() => console.log('Внешний beforeAll'));
describe('Внутренний блок', () => {
beforeAll(() => console.log('Внутренний beforeAll'));
it('тест', () => console.log('Тест'));
afterAll(() => console.log('Внутренний afterAll'));
});
afterAll(() => console.log('Внешний afterAll'));
});
Результат консоли:
Внешний beforeAll
Внутренний beforeAll
Тест
Внутренний afterAll
Внешний afterAll
beforeAll для тяжёлой
инициализации, которую не нужно повторять перед каждым
тестом.afterAll для освобождения
ресурсов, например закрытия соединений или очистки тестовой
базы данных.beforeAll с beforeEach, а
afterAll с afterEach.describe('Тесты с базой данных', () => {
let db;
beforeAll(async () => {
db = await connectToDatabase();
});
it('получение данных', async () => {
const users = await db.getUsers();
expect(users.length).toBeGreaterThan(0);
});
afterAll(async () => {
await db.disconnect();
});
});
describe('Глобальная конфигурация', () => {
let config;
beforeAll(() => {
config = loadGlobalConfig();
});
it('конфигурация содержит API ключ', () => {
expect(config.apiKey).toBeDefined();
});
afterAll(() => {
config = null; // очистка
});
});
Использование beforeAll и afterAll делает
тесты быстрее, чище и предсказуемее, особенно при
работе с дорогими или глобальными ресурсами.