Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Жизненный цикл Unit теста в JUnit
Это фундаментальный вопрос о структуре и порядке выполнения Unit тестов. Понимание жизненного цикла критично для написания правильных тестов.
Основные этапы жизненного цикла
Для каждого тестового метода JUnit выполняет следующие этапы:
1. Инстанцирование класса теста
2. @BeforeClass (один раз для всего класса) — JUnit 4
3. Для каждого тестового метода:
a) @Before (@BeforeEach в JUnit 5)
b) @Test метод
c) @After (@AfterEach в JUnit 5)
4. @AfterClass (один раз после всех тестов) — JUnit 4
JUnit 4 пример
import org.junit.BeforeClass;
import org.junit.Before;
import org.junit.Test;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.*;
public class CalculatorTest {
private Calculator calculator;
private static DatabaseConnection connection;
// Выполняется один раз перед всеми тестами класса
@BeforeClass
public static void setUpBeforeClass() {
System.out.println("1. @BeforeClass - инициализация общих ресурсов");
connection = new DatabaseConnection();
connection.connect();
}
// Выполняется перед каждым тестовым методом
@Before
public void setUp() {
System.out.println("2. @Before - инициализация перед каждым тестом");
calculator = new Calculator();
}
// Первый тест
@Test
public void testAdd() {
System.out.println("3. @Test - выполнение первого теста");
int result = calculator.add(2, 3);
assertEquals(5, result);
}
// Выполняется после первого теста
@After
public void tearDown() {
System.out.println("4. @After - очистка после первого теста");
calculator = null;
}
// Второй тест
@Test
public void testSubtract() {
System.out.println("3. @Test - выполнение второго теста");
System.out.println("2. @Before - инициализация перед вторым тестом");
int result = calculator.subtract(5, 3);
assertEquals(2, result);
}
// Выполняется после второго теста
// (снова @After)
// Выполняется один раз после всех тестов
@AfterClass
public static void tearDownAfterClass() {
System.out.println("5. @AfterClass - очистка общих ресурсов");
connection.disconnect();
}
}
Порядок вывода:
1. @BeforeClass - инициализация общих ресурсов
2. @Before - инициализация перед каждым тестом
3. @Test - выполнение первого теста
4. @After - очистка после первого теста
2. @Before - инициализация перед вторым тестом
3. @Test - выполнение второго теста
4. @After - очистка после второго теста
5. @AfterClass - очистка общих ресурсов
JUnit 5 пример (современный подход)
В JUnit 5 именование изменилось для большей ясности:
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.AfterAll;
import static org.junit.jupiter.api.Assertions.*;
public class CalculatorTest {
private Calculator calculator;
private static DatabaseConnection connection;
// Один раз перед всеми тестами (статический метод)
@BeforeAll
public static void setUp() {
System.out.println("@BeforeAll - один раз перед всеми тестами");
connection = new DatabaseConnection();
connection.connect();
}
// Перед каждым тестом (экземплярный метод)
@BeforeEach
public void setUpEach() {
System.out.println("@BeforeEach - перед каждым тестом");
calculator = new Calculator();
}
@Test
public void testAdd() {
System.out.println("@Test - выполнение теста");
assertEquals(5, calculator.add(2, 3));
}
@Test
public void testSubtract() {
System.out.println("@Test - выполнение теста");
assertEquals(2, calculator.subtract(5, 3));
}
// После каждого теста
@AfterEach
public void tearDownEach() {
System.out.println("@AfterEach - после каждого теста");
calculator = null;
}
// Один раз после всех тестов (статический метод)
@AfterAll
public static void tearDown() {
System.out.println("@AfterAll - один раз после всех тестов");
connection.disconnect();
}
}
Соответствие между JUnit 4 и JUnit 5
| JUnit 4 | JUnit 5 | Применяется |
|---|---|---|
| @BeforeClass | @BeforeAll | Один раз, перед всеми тестами |
| @Before | @BeforeEach | Перед каждым тестом |
| @Test | @Test | Тестовый метод |
| @After | @AfterEach | После каждого теста |
| @AfterClass | @AfterAll | Один раз, после всех тестов |
Практический пример: Database Connection
public class UserRepositoryTest {
private static Database db;
private UserRepository userRepository;
@BeforeAll
public static void initDatabase() {
// Очень дорогая операция - подключение к БД
// Выполняется один раз
db = new Database();
db.connect();
db.migrateSchema();
}
@BeforeEach
public void setup() {
// Очищаем данные перед каждым тестом
db.clearData();
userRepository = new UserRepository(db);
}
@Test
public void testCreateUser() {
User user = userRepository.create("John");
assertNotNull(user.getId());
}
@Test
public void testFindUser() {
userRepository.create("Jane");
User found = userRepository.findByName("Jane");
assertEquals("Jane", found.getName());
}
@AfterEach
public void cleanup() {
// Может быть дополнительная очистка
userRepository = null;
}
@AfterAll
public static void closeDatabase() {
// Закрываем соединение один раз
db.disconnect();
}
}
Важные моменты
1. @BeforeClass / @BeforeAll ДОЛЖНЫ быть static
@BeforeAll
public static void staticSetup() { // STATIC!
// инициализация
}
2. @Before / @BeforeEach могут быть обычные методы
@BeforeEach
public void instanceSetup() { // обычный метод
calculator = new Calculator();
}
3. Исключения в @Before пропускают тест
@BeforeEach
public void setup() throws IOException {
// Если здесь исключение, @Test не выполнится
fileReader = new FileReader("data.txt");
}
4. @After выполняется ВСЕГДА, даже при ошибке
@AfterEach
public void cleanup() {
// Выполнится даже если @Test упал!
if (fileReader != null) {
fileReader.close(); // гарантированная очистка
}
}
Резюме
- Жизненный цикл: инициализация → тест → очистка
- @BeforeAll / @BeforeClass: один раз перед всеми (статический)
- @BeforeEach / @Before: перед каждым тестом (экземплярный)
- @Test: сам тест
- @AfterEach / @After: после каждого теста (экземплярный)
- @AfterAll / @AfterClass: один раз после всех (статический)
- Используй этот цикл для инициализации и очистки ресурсов
- JUnit 5 более современный и гибкий для сложных сценариев