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

Как можно обрабатывать исключения?

2.0 Middle🔥 303 комментариев
#Java#Python#Теория тестирования#Фреймворки тестирования

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

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

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

Обработка исключений в программировании

Обработка исключений — это механизм контроля ошибок, позволяющий программе корректно реагировать на непредвиденные ситуации без аварийного завершения. Как QA Automation Engineer с 10+ лет опытом, я рассматриваю обработку исключений с двух сторон: как разработчик тестового фреймворка и как аналитик устойчивости тестов.

Основные конструкции для обработки исключений

1. Блоки try-catch-finally (в Java-подобных языках)

try {
    // Код, который может вызвать исключение
    WebElement element = driver.findElement(By.id("dynamic-element"));
    element.click();
} catch (NoSuchElementException e) {
    // Обработка конкретного исключения
    System.out.println("Элемент не найден: " + e.getMessage());
    // Логирование для отладки
    logger.error("Element not found", e);
} catch (TimeoutException e) {
    // Обработка другого типа исключения
    System.out.println("Таймаут при поиске элемента");
} finally {
    // Код, который выполнится всегда
    driver.quit(); // Гарантированное освобождение ресурсов
}

2. Множественные catch-блоки и multi-catch (Java 7+)

try {
    performRiskyOperation();
} catch (IOException | SQLException e) {
    // Обработка нескольких типов исключений одинаковым образом
    logger.error("Resource access failed", e);
    throw new TestFrameworkException("Operation failed", e);
}

3. Блок try-with-resources (Java 7+ для AutoCloseable)

try (FileInputStream fis = new FileInputStream("test-data.xml");
     BufferedReader reader = new BufferedReader(new InputStreamReader(fis))) {
    // Ресурсы автоматически закроются после блока
    String line = reader.readLine();
} catch (IOException e) {
    // Обработка исключений ввода-вывода
}

Стратегии обработки исключений в автоматизации тестирования

1. Явная обработка в тестовых методах

# Пример на Python
def test_login_with_invalid_credentials():
    try:
        login_page.enter_credentials("wrong", "wrong")
        login_page.click_submit()
        assert home_page.is_displayed(), "Должна быть ошибка авторизации"
    except ElementNotVisibleException as e:
        pytest.fail(f"Элемент интерфейса не виден: {str(e)}")
    except TimeoutException as e:
        # Повторная попытка или логирование
        logger.warning(f"Таймаут при выполнении теста: {str(e)}")
        retry_operation()
    finally:
        cleanup_test_data()  # Очистка тестовых данных

2. Использование оберток и декораторов

// Паттерн "Retry" для неустойчивых операций
public class RetryUtil {
    public static <T> T retry(Callable<T> operation, int maxAttempts) {
        Exception lastException = null;
        
        for (int attempt = 1; attempt <= maxAttempts; attempt++) {
            try {
                return operation.call();
            } catch (Exception e) {
                lastException = e;
                logger.warn("Attempt {} failed: {}", attempt, e.getMessage());
                if (attempt < maxAttempts) {
                    waitBeforeRetry(attempt);
                }
            }
        }
        throw new RuntimeException("Operation failed after " + maxAttempts + " attempts", lastException);
    }
}

3. Кастомные исключения для тестового фреймворка

public class TestAutomationException extends RuntimeException {
    private final Screenshot screenshot;
    
    public TestAutomationException(String message, Throwable cause) {
        super(message, cause);
        this.screenshot = captureScreenshot();
    }
    
    public Screenshot getScreenshot() {
        return screenshot;
    }
}

// Использование
try {
    complexValidation();
} catch (ValidationException e) {
    throw new TestAutomationException("Validation failed in test", e);
}

Практические рекомендации для QA Automation

  1. Логирование с контекстом — всегда включайте в логи:

    • Время возникновения исключения
    • Состояние системы (URL, данные теста)
    • Скриншоты для UI-тестов
    • Стек вызовов
  2. Гранулярность обработки:

    • Обрабатывайте на низком уровне технические исключения (таймауты, сетевые ошибки)
    • На высоком уровне — бизнес-логику тестов
  3. Восстановление состояния — ключевой аспект:

    public void safeTestExecution() {
        TestContext context = null;
        try {
            context = setupTestEnvironment();
            executeTestSteps();
        } catch (AssertionError e) {
            // Тестовые проверки не прошли
            reportTestFailure(e);
        } catch (Exception e) {
            // Системные ошибки
            reportInfrastructureIssue(e);
        } finally {
            if (context != null) {
                context.cleanup(); // Гарантированная очистка
            }
        }
    }
    
  4. Использование assertion-библиотек с поддержкой мягких проверок:

    SoftAssertions softly = new SoftAssertions();
    try {
        softly.assertThat(actualTitle).isEqualTo(expectedTitle);
        softly.assertThat(elementCount).isGreaterThan(0);
        softly.assertAll(); // Все проверки выполнятся
    } catch (AssertionError e) {
        // Все неудачные проверки в одном отчете
    }
    
  5. Обработка асинхронных исключений (особенно важно для Selenium):

    // Ожидание с обработкой таймаута
    public WebElement waitForElement(By locator, int timeoutSeconds) {
        try {
            WebDriverWait wait = new WebDriverWait(driver, timeoutSeconds);
            return wait.until(ExpectedConditions.visibilityOfElementLocated(locator));
        } catch (TimeoutException e) {
            throw new ElementNotFoundException(
                String.format("Element %s not found in %d seconds", locator, timeoutSeconds), 
                e
            );
        }
    }
    

Антипаттерны обработки исключений

  • Пустые catch-блоки — скрывают реальные проблемы
  • Излишне широкий catch (catch Exception) — затрудняет диагностику
  • Игнорирование checked exceptions — нарушает контракты методов
  • Исключения в finally-блоке — маскируют оригинальную ошибку

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

Как можно обрабатывать исключения? | PrepBro