← Назад к вопросам
К какому уровню тестовой пирамиды относятся unit тесты
2.2 Middle🔥 111 комментариев
#Основы Java
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Unit тесты в пирамиде тестирования
Пирамида тестирования (Test Pyramid)
Пирамида тестирования — это структура, которая показывает, в каком соотношении должны быть разные типы тестов:
/\
/E2E\
/-----\
/ UI \
/-------\
/Integration\
/-----------\
/ Unit \
/_______________\
Unit тесты — это основание пирамиды
Unit тесты расположены в самом низу, потому что они:
// Unit тест — быстрый, изолированный, дешёвый
@Test
public void testCalculateDiscount() {
// Arrange
DiscountCalculator calculator = new DiscountCalculator();
// Act
double discount = calculator.apply(100, 0.1);
// Assert
assertEquals(10, discount, 0.01);
}
// Выполняется за миллисекунды
Характеристики Unit тестов
1. Быстрота Unit тесты выполняются за миллисекунды:
// Быстро
@Test
public void testStringUtils() {
String result = StringUtils.truncate("hello", 2);
assertEquals("he", result);
}
// Медленно — это уже не unit тест
@Test
public void testWithDatabaseCall() {
database.connect(); // медленно
userRepository.save(user); // медленно
// это интеграционный тест
}
2. Изолированность Unit тесты проверяют одну функцию/класс в изоляции:
public class OrderService {
private final PaymentProcessor paymentProcessor;
private final NotificationService notificationService;
public OrderService(PaymentProcessor paymentProcessor,
NotificationService notificationService) {
this.paymentProcessor = paymentProcessor;
this.notificationService = notificationService;
}
public void processOrder(Order order) {
paymentProcessor.charge(order);
notificationService.notifyCustomer(order);
}
}
// Unit тест — мокируем зависимости
@Test
public void testProcessOrder() {
// Arrange
PaymentProcessor mockPaymentProcessor = mock(PaymentProcessor.class);
NotificationService mockNotificationService = mock(NotificationService.class);
OrderService service = new OrderService(mockPaymentProcessor, mockNotificationService);
Order order = new Order(100);
// Act
service.processOrder(order);
// Assert — проверяем, что методы вызваны, но не реально
verify(mockPaymentProcessor).charge(order);
verify(mockNotificationService).notifyCustomer(order);
}
3. Независимость Unit тесты не зависят друг от друга:
@Test
public void testAdd() {
Calculator calc = new Calculator();
assertEquals(5, calc.add(2, 3));
}
@Test
public void testSubtract() { // этот тест работает независимо
Calculator calc = new Calculator();
assertEquals(1, calc.subtract(3, 2));
}
Сравнение с другими уровнями пирамиды
Unit тесты (основание)
@Test
public void testUserValidator() {
// Only logic, no dependencies
UserValidator validator = new UserValidator();
assertTrue(validator.isValidEmail("test@example.com"));
assertFalse(validator.isValidEmail("invalid"));
}
Характеристики:
- Количество: много (70-80%)
- Скорость: очень быстрые (< 1ms)
- Стоимость: дешевые
- Фокус: бизнес-логика
- Инструменты: JUnit, Mockito, AssertJ
Integration тесты (средний уровень)
@SpringBootTest
public class UserRepositoryIntegrationTest {
@Autowired
private UserRepository userRepository;
@Test
public void testSaveAndFindUser() {
// Реально используем БД
User user = new User("John", "john@example.com");
userRepository.save(user);
// Проверяем что в БД
Optional<User> found = userRepository.findByEmail("john@example.com");
assertTrue(found.isPresent());
}
}
Характеристики:
- Количество: меньше (15-20%)
- Скорость: медленнее (100-500ms)
- Стоимость: дороже
- Фокус: интеграция компонентов
- Инструменты: @SpringBootTest, TestContainers
E2E / UI тесты (вершина)
public class UserSignupE2ETest {
@Test
public void testCompleteSignupFlow() {
// Открываем браузер, заполняем форму и т.д.
driver.get("https://example.com");
driver.findElement(By.id("email")).sendKeys("test@example.com");
driver.findElement(By.id("signup")).click();
// Проверяем финальный результат
assertEquals("Success", driver.findElement(By.id("message")).getText());
}
}
Характеристики:
- Количество: мало (5-10%)
- Скорость: медленные (секунды-минуты)
- Стоимость: очень дорогие
- Фокус: пользовательский сценарий
- Инструменты: Selenium, Playwright
Почему unit тесты в основании?
Скорость выполнения:
Unit: 0-1ms ████ быстро
Integration: 100-500ms ███████████ медленнее
E2E: 5-30s ██████████████████████████ очень медленно
Стоимость:
Unit: дешевые ███
Integration: дороже ██████
E2E: очень дорогие ████████████
Одновременное выполнение:
Unit: 100+ тестов за секунды
Integration: 20 тестов за минуту
E2E: 10 тестов за 10 минут
Правильное соотношение в пирамиде
🏆 E2E (5-10%) — только критичные сценарии
Integration (15-20%) — интеграция компонентов
Unit (70-80%) — всё остальное
Плохо:
E2E (40%) — медленные тесты, долгий feedback
Integration (40%) — дорого и медленно
Unit (20%) — недостаточно
Практический пример иерархии
// 1. Unit тест — логика платежа
@Test
public void testDiscountCalculation() {
Order order = new Order();
assertEquals(10, order.calculateDiscount(100, 0.1));
}
// 2. Integration тест — платёж + БД
@SpringBootTest
public class PaymentIntegrationTest {
@Test
public void testSavePayment() {
paymentRepository.save(payment);
assertTrue(paymentRepository.exists(payment.getId()));
}
}
// 3. E2E тест — весь процесс
@Test
public void testCompletePaymentFlow() {
driver.get("https://shop.com/checkout");
driver.findElement(By.id("amount")).sendKeys("100");
driver.findElement(By.id("pay")).click();
assertEquals("Payment successful", driver.findElement(By.id("message")).getText());
}
Почему unit тесты важны?
- Быстрый feedback — узнаёшь об ошибке за 1 секунду
- Дешевы в разработке — не нужно настраивать БД, браузер и т.д.
- Высокая скорость выполнения — можешь запустить их 100 раз
- Простота отладки — легко найти проблему в 10 строк кода
- Тестируют бизнес-логику — самая важная часть
Антипаттерн: тестовая пирамида вверх ногами
Плохо: Хорошо:
E2E 50% E2E 10%
Integration 40% Integration 20%
Unit 10% Unit 70%
Вывод
Unit тесты — это основание пирамиды тестирования:
- Их должно быть 70-80% от всех тестов
- Они выполняются быстро (мс)
- Они дешевы в разработке
- Они тестируют бизнес-логику в изоляции
- Они дают быстрый feedback на ошибки
Структура пирамиды гарантирует:
- Быстрый feedback при разработке
- Покрытие всех слоёв приложения
- Баланс между скоростью и надёжностью
- Дешевизну поддержки автотестов