← Назад к вопросам

Что такое интеграционное тестирование?

2.0 Middle🔥 171 комментариев
#Тестирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Интеграционное тестирование

Интеграционное тестирование (integration testing) — это тестирование взаимодействия между несколькими компонентами системы или между системой и внешними сервисами. Это уровень тестирования, который находится между модульным (unit) и системным (end-to-end) тестированием.

Пирамида тестирования

        E2E Tests (5-10%)
     System Tests (15-20%)
  Integration Tests (20-30%)
Unit Tests (50-60%)

Интеграционные тесты проверяют, как разные части системы работают вместе.

Различие: Unit vs Integration vs E2E

Unit Test — тестирует один метод/класс изолированно:

@Test
public void testAddUser() {
    UserService service = new UserService(mock(UserRepository.class));
    User user = service.createUser("test@test.com", "password");
    assertEquals("test@test.com", user.getEmail());
}

Integration Test — тестирует несколько компонентов вместе:

@SpringBootTest
@AutoConfigureMockMvc
public class UserIntegrationTest {
    @Autowired
    private MockMvc mockMvc;
    
    @Autowired
    private UserRepository userRepository;
    
    @Test
    public void testCreateUserEndToEndFlow() throws Exception {
        // 1. Отправить HTTP запрос
        // 2. Контроллер вызовет Service
        // 3. Service вызовет Repository
        // 4. Repository сохранит в базу
        // 5. Проверить, что всё прошло успешно
        
        mockMvc.perform(post("/api/users")
            .contentType(MediaType.APPLICATION_JSON)
            .content("{\"email\":\"test@test.com\"}")
        ).andExpect(status().isCreated());
        
        // Проверить, что пользователь действительно сохранён в БД
        User user = userRepository.findByEmail("test@test.com");
        assertNotNull(user);
    }
}

E2E Test — тестирует через UI (Playwright, Selenium):

test('Create user through web UI', async ({ page }) => {
    await page.goto('http://localhost:3000');
    await page.fill('input[name="email"]', 'test@test.com');
    await page.click('button[type="submit"]');
    await expect(page).toHaveURL('http://localhost:3000/users/success');
});

Типы интеграционного тестирования

1. API Integration Testing

Тестирование контроллеров и их взаимодействия с сервисами:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserApiIntegrationTest {
    @Autowired
    private TestRestTemplate restTemplate;
    
    @Autowired
    private UserService userService;
    
    @Test
    public void testGetUserByIdApi() {
        // Подготовка: создать пользователя через сервис
        User savedUser = userService.createUser("John", "john@example.com");
        
        // Тест: получить через API
        ResponseEntity<User> response = restTemplate.getForEntity(
            "/api/users/" + savedUser.getId(),
            User.class
        );
        
        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertEquals("John", response.getBody().getName());
    }
}

2. Database Integration Testing

Тестирование взаимодействия между приложением и БД:

@DataJpaTest
public class UserRepositoryIntegrationTest {
    @Autowired
    private UserRepository userRepository;
    
    @Test
    public void testSaveAndRetrieveUser() {
        // Сохранить в реальную БД
        User user = new User();
        user.setName("Alice");
        user.setEmail("alice@example.com");
        userRepository.save(user);
        
        // Получить из БД и проверить
        User retrieved = userRepository.findByEmail("alice@example.com");
        assertNotNull(retrieved);
        assertEquals("Alice", retrieved.getName());
    }
}

3. External Service Integration Testing

Тестирование взаимодействия с внешними API:

@Test
public void testPaymentGatewayIntegration() throws Exception {
    // Используем VCR.py или MockWebServer для записи HTTP ответов
    PaymentService paymentService = new PaymentService(httpClient);
    
    PaymentResponse response = paymentService.processPayment(
        new PaymentRequest(100.0, "USD")
    );
    
    assertEquals("SUCCESS", response.getStatus());
    assertNotNull(response.getTransactionId());
}

С использованием MockWebServer:

@Test
public void testExternalApiIntegration() throws Exception {
    MockWebServer mockWebServer = new MockWebServer();
    mockWebServer.enqueue(new MockResponse()
        .setBody("{\"status\":\"success\"}")
        .addHeader("Content-Type", "application/json")
    );
    mockWebServer.start();
    
    ExternalService service = new ExternalService(
        mockWebServer.url("/").toString()
    );
    
    ApiResponse response = service.callApi();
    assertEquals("success", response.getStatus());
    
    mockWebServer.shutdown();
}

4. Cache Integration Testing

Тестирование взаимодействия с кешем:

@SpringBootTest
@EnableCaching
public class CacheIntegrationTest {
    @Autowired
    private UserService userService;
    
    @Autowired
    private CacheManager cacheManager;
    
    @Test
    public void testUserCaching() {
        // Первый вызов — идёт в БД
        User user1 = userService.getUserById(1L);
        
        // Второй вызов — из кеша
        User user2 = userService.getUserById(1L);
        
        // Проверить, что данные в кеше
        Cache cache = cacheManager.getCache("users");
        assertNotNull(cache.get(1L));
        
        // Очистить кеш
        cache.clear();
        assertNull(cache.get(1L));
    }
}

Инструменты интеграционного тестирования

1. Spring Boot Test

@SpringBootTest
@AutoConfigureMockMvc
public class IntegrationTest { }

2. MockMvc для тестирования контроллеров

mockMvc.perform(post("/api/users")
    .contentType(MediaType.APPLICATION_JSON)
    .content(json)
).andExpect(status().isCreated());

3. TestRestTemplate для REST API

ResponseEntity<User> response = restTemplate.getForEntity(
    "/api/users/1", User.class
);

4. TestContainers для реальных зависимостей (БД, Kafka)

@Testcontainers
public class DockerIntegrationTest {
    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>()
        .withDatabaseName("testdb")
        .withUsername("user")
        .withPassword("password");
    
    @Test
    public void testWithRealDatabase() {
        // Тест использует реальную БД в Docker контейнере
        userRepository.save(new User("Alice"));
        User found = userRepository.findByName("Alice");
        assertNotNull(found);
    }
}

5. WireMock для мокирования внешних сервисов

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@AutoConfigureWireMock(port = 0)
public class ExternalServiceIntegrationTest {
    @Test
    public void testExternalServiceCall() {
        stubFor(get(urlEqualTo("/api/external"))
            .willReturn(aResponse()
                .withStatus(200)
                .withBody("{\"result\":\"mocked\"}"))
        );
        
        ApiResponse response = externalService.callApi();
        assertEquals("mocked", response.getResult());
    }
}

Особенности интеграционных тестов

Плюсы:

  • Тестируют реальное взаимодействие компонентов
  • Ловят проблемы, которые unit тесты пропустят
  • Проверяют конкретные бизнес-сценарии
  • Дают уверенность в качестве

Минусы:

  • Медленнее, чем unit тесты (требуют реальной БД, HTTP запросов)
  • Более сложные в настройке
  • Требуют больше ресурсов
  • Может быть нестабильны (если внешние сервисы недоступны)

Лучшие практики

  1. Изолируй внешние зависимости

    • Используй MockWebServer вместо реальных API
    • Используй TestContainers для БД
  2. Используй фикстуры для подготовки данных

    @Before
    public void setUp() {
        User testUser = new User("Test", "test@example.com");
        userRepository.save(testUser);
    }
    
  3. Тестируй happy path и error cases

    @Test
    public void testSuccessfulPayment() { }
    
    @Test
    public void testPaymentFailure() { }
    
  4. Переиспользуй тестовые контексты

    @SpringBootTest
    public class BaseIntegrationTest { }
    
  5. Группируй интеграционные тесты отдельно

    @Tag("integration")
    public class UserIntegrationTest { }
    

Интеграционное тестирование — это критичный уровень тестирования, который гарантирует, что компоненты работают вместе корректно и приложение выполняет свои бизнес-функции.