← Назад к вопросам
На монолитах или микросервисах написаны тесты
3.0 Senior🔥 141 комментариев
#REST API и микросервисы
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# На монолитах или микросервисах написаны тесты
Ответ: Тесты пишутся и на монолитах, И на микросервисах. Но подходы, техники и инструменты существенно отличаются.
Пирамида тестирования (одинакова везде)
End-to-End
/\\
/ \\
/ \\ (20% - дорого, медленно)
/______\\
Integration
/\\
/ \\
/ \\ (30% - среднее)
/______\\
Unit
/ \\
/ \\ (50% - быстро, дешево)
/__________\\
Эта пирамида применима и к монолитам, и к микросервисам.
Тестирование на монолитах
Характеристики
- Всё в одном процессе - все слои (вебд, бизнес-логика, БД) доступны
- Проще unit тесты - можно инстанцировать классы напрямую
- Integration тесты дешевле - нет сетевых вызовов между сервисами
- End-to-end тесты - от HTTP запроса до БД, все внутри одного приложения
Пример: Монолитное приложение
// Монолитная архитектура
// PaymentService -> OrderService -> DatabaseLayer
// Всё в одном JAR файле
@SpringBootTest
public class OrderServiceTest {
@Autowired
private OrderService orderService;
@Autowired
private PaymentService paymentService;
@Autowired
private OrderRepository orderRepository;
@Test
public void testCreateOrder() {
// Unit + Integration тест
// Тестируем весь путь от сервиса до БД
Order order = orderService.createOrder(1L, "Item");
assertTrue(orderRepository.findById(order.getId()).isPresent());
assertTrue(paymentService.isPaid(order.getId()));
}
}
// Быстро, легко, не нужны моки
Преимущества тестирования на монолитах
- Простота - не нужно управлять сетевыми вызовами
- Скорость - тесты быстрые, всё локально
- Интеграция - легко тестировать взаимодействие модулей
- Отладка - просто отладить в IDE
Недостатки
- Масштабируемость - монолит растёт, тесты становятся медленнее
- Изоляция - сложно тестировать отдельные компоненты
- Зависимости - один баг может сломать множество тестов
Тестирование на микросервисах
Характеристики
- Сервисы независимы - каждый в своем процессе
- Сетевые границы - нужно мокировать другие сервисы
- Unit тесты сложнее - много внешних зависимостей
- Integration тесты дороже - нужно запускать несколько сервисов
- E2E тесты критичны - проверяют взаимодействие сервисов
Пример: Микросервисная архитектура
// Order Service (микросервис)
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@Autowired
private OrderService orderService;
@Autowired
private PaymentServiceClient paymentClient; // REST клиент
@PostMapping
public Order createOrder(@RequestBody OrderRequest request) {
// Вызываем PaymentService по HTTP
boolean paid = paymentClient.pay(request.getAmount());
Order order = orderService.createOrder(request);
order.setPaid(paid);
return order;
}
}
// Unit тест
@Test
public void testCreateOrderUnit() {
// Мокируем внешний сервис
PaymentServiceClient paymentClient = Mockito.mock(PaymentServiceClient.class);
Mockito.when(paymentClient.pay(100)).thenReturn(true);
OrderService orderService = new OrderService();
Order order = orderService.createOrder("Item", paymentClient);
assertNotNull(order);
}
// Integration тест (контейнер)
@SpringBootTest
@Testcontainers
public class OrderServiceIntegrationTest {
@Container
static PostgreSQLContainer<?> postgres =
new PostgreSQLContainer<>("postgres:13");
@Test
public void testCreateOrder() {
// Тестируем Order Service + своя БД
// PaymentService всё ещё замокирован
}
}
// E2E тест (все сервисы)
@Test
public void testFullOrderFlow() {
// docker-compose up (все микросервисы)
// Отправляем HTTP запрос на Order Service
// Order Service вызывает Payment Service
// Проверяем результат в обеих БД
}
Стратегия тестирования микросервисов
| Уровень | Где писать | Инструменты |
|---|---|---|
| Unit | В каждом сервисе | JUnit, Mockito, AssertJ |
| Integration | В каждом сервисе | TestContainers, H2, MockServer |
| E2E | Отдельный проект | Playwright, REST Assured, Testcontainers (compose) |
| Contract | Между сервисами | Pact, Spring Cloud Contract |
Contract Testing - ключевое отличие
В микросервисах критически важны контрактные тесты:
// Payment Service (провайдер)
@SpringBootTest
public class PaymentProviderTest {
@Test
@PactTestFor(providerName = "PaymentService", port = "8080")
public void testPaymentEndpoint(PactVerificationContext context) {
context.verifyInteraction();
}
}
// Order Service (потребитель)
@PactTestFor(providerName = "PaymentService")
public class PaymentConsumerTest {
@Pact(consumer = "OrderService", provider = "PaymentService")
public RequestResponsePact createPact(PactDslWithProvider builder) {
return builder
.given("payment is available")
.uponReceiving("a request to pay")
.path("/api/pay")
.willRespondWith()
.status(200)
.body("amount", 100)
.toPact();
}
}
Сравнение: Монолит vs Микросервисы
| Аспект | Монолит | Микросервисы |
|---|---|---|
| Unit тесты | Простые | Нужны моки внешних сервисов |
| Integration | Всё внутри | Нужна оркестрация сервисов |
| E2E | Один процесс | Распределённые системы |
| Скорость тестов | Быстрые | Медленнее (сеть, контейнеры) |
| Инструменты | Простые (JUnit) | Сложнее (Testcontainers, Pact) |
| Contract Testing | Не нужен | ОБЯЗАТЕЛЕН |
Лучшие практики для обеих архитектур
1. Следуй пирамиде тестирования
Много Unit → Меньше Integration → Мало E2E
2. Отделяй тесты по скорости
# Быстрые (run on every commit)
make test:unit # < 5 сек
# Средние (run on PR)
make test:integration # < 30 сек
# Медленные (run on CI/CD)
make test:e2e # < 5 мин
3. Используй тестовые контейнеры
// Гарантирует одинаковую окружение
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>();
4. Изолируй тесты
// Каждый тест - чистая БД
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
Заключение
Тесты пишутся везде, но:
- На монолитах - проще писать интеграционные тесты
- На микросервисах - нужны контрактные тесты и сложная оркестрация
- Unit тесты - везде критичны и доминируют по количеству
- E2E тесты - на микросервисах сложнее и дороже
Выбор архитектуры серьёзно влияет на стратегию и инструменты тестирования, но сами тесты нужны в обоих случаях.