Ответ
BeforeAll (или beforeAll, @BeforeAll) и BeforeEach (или beforeEach, @BeforeEach) — это хуки настройки в тестовых фреймворках, которые выполняются в разные моменты жизненного цикла тестового набора (test suite).
BeforeAll
- Выполняется: Один раз перед запуском всех тестов в данном тестовом классе или файле.
- Область видимости: Общее состояние, созданное здесь, доступно для всех тестов и сохраняется между ними.
- Типичное использование:
- Установка дорогостоящих соединений (БД, внешние API).
- Загрузка общих конфигурационных данных.
- Инициализация глобальных ресурсов (например, тестового сервера).
BeforeEach
- Выполняется: Перед каждым отдельным тестовым случаем (
@Test). - Область видимости: Состояние должно быть изолированным для каждого теста.
- Типичное использование:
- Сброс или очистка состояния (например, очистка таблиц БД).
- Создание свежего экземпляра тестируемого объекта.
- Настройка моков (mocks) или заглушек (stubs) для каждого теста.
Пример на Jest (JavaScript/TypeScript):
describe('User Service', () => {
let dbConnection;
// Выполнится 1 РАЗ для всех тестов ниже
beforeAll(async () => {
dbConnection = await connectToDatabase(); // Дорогая операция
console.log('Database connected');
});
// Выполнится перед КАЖДЫМ тестом
beforeEach(() => {
console.log('Preparing fresh test state...');
// Очищаем таблицу пользователей перед каждым тестом
dbConnection.query('DELETE FROM users');
});
test('should create a user', () => {
// Здесь чистая БД
});
test('should find a user', () => {
// И здесь тоже чистая БД
});
afterAll(() => {
dbConnection.close();
});
});
Ключевое правило: Используйте BeforeAll для настройки общих, неизменяемых ресурсов. Используйте BeforeEach для обеспечения изоляции тестов, подготавливая чистую среду для каждого случая, чтобы тесты не влияли друг на друга.
Ответ 18+ 🔞
А, слушай, вот эта тема с хуками в тестах — она же постоянно всех пиздюлей накрывает, пока не разберёшься! Ёпта, сейчас объясню на пальцах, без этой вашей заумной документации.
Представь себе, что ты на кухне готовишь. У тебя есть BeforeAll — это как один раз, блядь, достать с верхней полки тяжёлую сковородку, поставить её на плиту и включить огонь. Операция долгая, муторная, делать её перед каждым яичком — это же пиздец, да? Один раз сделал — и она греется, готова к работе для всех блинов и яиц.
А BeforeEach — это вот перед каждым, сука, новым яйцом, которое ты жаришь, ты сковородку-то быстро протёр тряпкой, масла свежего капнул. Чтобы от прошлого яйца пригорелая хуйня не мешала. Изоляция, блядь! Каждое яйцо должно жариться на чистой сковороде, иначе они все в одну кашу слипутся, и ты не поймёшь, какое из них протухло.
Вот смотри на примере, тут всё чётко:
describe('User Service', () => {
let dbConnection; // Это наша сковорода
// beforeAll - ДОСТАЛИ СКОВОРОДУ ОДИН РАЗ. Подключились к базе.
beforeAll(async () => {
dbConnection = await connectToDatabase(); // Дорогая операция, ебать
console.log('Database connected');
});
// beforeEach - ПРОТИРАЕМ СКОВОРОДУ ПЕРЕД КАЖДЫМ ЯЙЦОМ. Чистим таблицу.
beforeEach(() => {
console.log('Preparing fresh test state...');
dbConnection.query('DELETE FROM users'); // Вжух, и чисто!
});
test('should create a user', () => {
// Тестим на чистой базе
});
test('should find a user', () => {
// И здесь база тоже чистая, потому что beforeEach отработал снова
});
afterAll(() => {
dbConnection.close(); // Погасили огонь, помыли сковороду
});
});
Короче, главное правило, чтобы не облажаться: Если ресурс тяжёлый и общий для всех (типа соединения с базой, поднятия тестового сервера) — это BeforeAll, ёпта. Сделал один раз и забыл. Если нужно каждый тест запускать в чистой песочнице, чтобы они друг другу не насрали в состояние — это BeforeEach, блядь. Чистка, сброс, подготовка свежего объекта.
Запомни это, и у тебя тесты перестанут вести себя как непредсказуемая манда с ушами, которая то падает, то работает. Всё просто, как три копейки!