В тестировании на JavaScript с использованием Jasmine часто возникает
необходимость выполнять повторяющиеся действия перед каждым тестом или
после него. Для этих целей предназначены функции beforeEach
и afterEach. Они обеспечивают чистоту тестового окружения,
уменьшают дублирование кода и повышают читаемость тестов.
beforeEachbeforeEach — это функция, которая запускается до
выполнения каждого отдельного it-теста внутри
блока describe. Она используется для подготовки окружения:
инициализации переменных, создания объектов, установки начального
состояния приложения.
Синтаксис:
beforeEach(function() {
// действия, выполняемые перед каждым тестом
});
Пример использования:
describe('Тестирование массива', function() {
let numbers;
beforeEach(function() {
numbers = [1, 2, 3]; // инициализация перед каждым тестом
});
it('должен содержать три элемента', function() {
expect(numbers.length).toBe(3);
});
it('должен содержать число 2', function() {
expect(numbers).toContain(2);
});
});
В этом примере переменная numbers создаётся заново перед
каждым тестом, что предотвращает влияние одного теста на другой.
Особенности beforeEach:
done или промисы.beforeEach(function(done) {
setTimeout(function() {
numbers = [4, 5, 6];
done();
}, 100);
});
describe. В этом
случае выполняются все beforeEach начиная с внешнего блока
к внутреннему.describe('Внешний блок', function() {
beforeEach(function() {
console.log('Внешний beforeEach');
});
describe('Внутренний блок', function() {
beforeEach(function() {
console.log('Внутренний beforeEach');
});
it('тест', function() {
console.log('Тест');
});
});
});
Вывод будет:
Внешний beforeEach
Внутренний beforeEach
Тест
afterEachafterEach запускается после выполнения каждого
теста it. Она используется для очистки состояния,
сброса данных, удаления созданных объектов или отмены шпионов
(spy) и таймеров.
Синтаксис:
afterEach(function() {
// действия после каждого теста
});
Пример использования:
describe('Работа с DOM', function() {
let div;
beforeEach(function() {
div = document.createElement('div');
div.id = 'test-div';
document.body.appendChild(div);
});
afterEach(function() {
document.body.removeChild(div); // очистка после теста
});
it('должен содержать элемент с id "test-div"', function() {
expect(document.getElementById('test-div')).not.toBeNull();
});
});
Использование afterEach гарантирует, что каждый тест
начнется с чистого DOM, независимо от того, что было изменено
предыдущими тестами.
Особенности afterEach:
done или
промисы.describe и
выполняется сначала внутренний afterEach, затем
внешний.describe('Внешний блок', function() {
afterEach(function() {
console.log('Внешний afterEach');
});
describe('Внутренний блок', function() {
afterEach(function() {
console.log('Внутренний afterEach');
});
it('тест', function() {
console.log('Тест');
});
});
});
Вывод:
Тест
Внутренний afterEach
Внешний afterEach
beforeEach и afterEachИспользование обеих функций вместе обеспечивает полный контроль над подготовкой и очисткой тестового окружения.
Пример комплексного сценария:
describe('Работа с объектом пользователя', function() {
let user;
beforeEach(function() {
user = { name: 'Alice', age: 25 };
});
afterEach(function() {
user = null; // очистка
});
it('должен иметь имя Alice', function() {
expect(user.name).toBe('Alice');
});
it('должен иметь возраст 25', function() {
expect(user.age).toBe(25);
});
});
Такой подход гарантирует, что изменения, внесённые одним тестом, не повлияют на остальные, сохраняя изоляцию тестов — ключевой принцип юнит-тестирования.
beforeEach, если
они не нужны для всех тестов — это замедлит выполнение тестов.afterEach для сброса состояний, особенно
при работе с глобальными объектами или DOM.describe-блоки позволяют создавать иерархию
подготовки и очистки, делая код более структурированным и понятным.beforeEach и afterEach являются основой
организации тестов в Jasmine, позволяя минимизировать повторения,
поддерживать чистоту тестового окружения и облегчать сопровождение
большого количества тестов.