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

Для чего нужно регрессионное тестирование?

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

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

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

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

# Регрессионное тестирование

Определение

Регрессионное тестирование — это проверка того, что новые изменения в коде не сломали существующий функционал. Это повторное выполнение ранее пройденных тестов после внесения изменений.

Почему это важно

1. Защита от неожиданных побочных эффектов

Когда разработчик вносит изменения в один модуль, это может повлиять на другие части системы, которые от него зависят:

// Был класс PaymentValidator
public class PaymentValidator {
    public static boolean isValidAmount(BigDecimal amount) {
        return amount.compareTo(BigDecimal.ZERO) > 0;
    }
}

// Разработчик добавил валидацию максимальной суммы
public class PaymentValidator {
    public static boolean isValidAmount(BigDecimal amount) {
        return amount.compareTo(BigDecimal.ZERO) > 0 
            && amount.compareTo(new BigDecimal("10000")) <= 0;
    }
}

// Но это может сломать старый функционал, который предполагал платежи свыше 10000!

Регрессионное тестирование поймает эту проблему.

2. Уверенность при рефакторинге

Если код покрыт тестами, можно безопасно рефакторить:

// Исходный код
public class OrderService {
    public BigDecimal calculateTotal(List<Item> items) {
        BigDecimal total = BigDecimal.ZERO;
        for (Item item : items) {
            total = total.add(item.getPrice().multiply(new BigDecimal(item.getQuantity())));
        }
        return total;
    }
}

// Рефакторим — используем stream API
public class OrderService {
    public BigDecimal calculateTotal(List<Item> items) {
        return items.stream()
            .map(item -> item.getPrice().multiply(new BigDecimal(item.getQuantity())))
            .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
}

// Регрессионные тесты гарантируют, что поведение не изменилось

3. Поймать bugs на ранней стадии

Чем раньше обнаружена ошибка, тем дешевле её исправить:

Цена исправления bug:
- На локальной машине: $1
- После commit: $10
- В staging: $100
- В production: $1000+

Регрессионное тестирование (CI/CD) ловит bugs до попадания в production.

4. Документация кода

Тесты служат живой документацией — показывают, как должен работать код:

@Test
public void testDiscountCalculation() {
    // Это документирует поведение: скидка 10% для заказов > 1000
    OrderService service = new OrderService();
    BigDecimal total = service.calculateTotalWithDiscount(new BigDecimal("1500"));
    assertEquals(new BigDecimal("1350"), total); // 1500 * 0.9
}

5. Снижение затрат на ручное тестирование

Автоматические тесты дешевле и быстрее, чем ручные:

Ручное тестирование:
- 50 test cases × 5 минут = 250 минут ≈ 4 часа на каждый релиз

Автоматизированное тестирование:
- 50 unit tests = 5 секунд
- 20 integration tests = 30 секунд
- Итого ≈ 1 минута на каждый релиз

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

1. Unit Regression Testing

Проверка того, что отдельные методы работают как раньше:

@Test
public void testUserValidation() {
    User user = new User("john@example.com");
    assertTrue(user.isValid());
}

2. Integration Regression Testing

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

@SpringBootTest
public class OrderRepositoryTest {
    @Test
    public void testOrderPersistence() {
        Order order = new Order("USER123", new BigDecimal("100"));
        orderRepository.save(order);
        
        Order retrieved = orderRepository.findById(order.getId()).orElse(null);
        assertNotNull(retrieved);
        assertEquals("USER123", retrieved.getUserId());
    }
}

3. System Regression Testing

Проверка всей системы через API:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class OrderControllerTest {
    @Test
    public void testOrderCreationEndpoint() {
        given()
            .contentType("application/json")
            .body(new CreateOrderRequest("item1", 2))
        .when()
            .post("/api/orders")
        .then()
            .statusCode(201)
            .body("id", notNullValue());
    }
}

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

1. Тесты должны быть быстрыми

// ПЛОХО — тест медленный, делает реальный DB запрос
@Test
public void testOrderCreation() {
    Order order = orderRepository.save(new Order("USER1", new BigDecimal("100")));
    assertTrue(order.getId() > 0);
}

// ХОРОШО — тест быстрый, использует моки
@Test
public void testOrderCreation() {
    OrderRepository mockRepo = mock(OrderRepository.class);
    Order order = new Order("USER1", new BigDecimal("100"));
    when(mockRepo.save(order)).thenReturn(order);
    assertTrue(order.isValid());
}

2. Поддерживай тесты актуальными

Когда меняется требование, обнови тест:

// Требование изменилось: скидка теперь 15%, не 10%
@Test
public void testDiscountCalculation() {
    OrderService service = new OrderService();
    BigDecimal total = service.calculateTotalWithDiscount(new BigDecimal("1000"));
    assertEquals(new BigDecimal("850"), total); // 1000 * 0.85, не 900
}

3. CI/CD должна запускать тесты автоматически

# GitHub Actions
name: Regression Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: mvn test
      - run: mvn integration-test

Выводы

Регрессионное тестирование нужно для:

  1. Защиты от побочных эффектов новых изменений
  2. Безопасного рефакторинга кода
  3. Раннего обнаружения ошибок
  4. Документирования поведения
  5. Снижения затрат на тестирование
  6. Уверенности в качестве кода

Без регрессионного тестирования каждый новый feature рискует сломать старый функционал. Это критически важно для поддерживаемости проекта на long-term basis.

Для чего нужно регрессионное тестирование? | PrepBro