Как вы использовали Optional API в тестовом коде на Java?

«Как вы использовали Optional API в тестовом коде на Java?» — вопрос из категории Java, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В тестовом коде на Java я применяю Optional для более чистого и безопасного взаимодействия с методами, которые могут возвращать null, особенно при работе с данными из конфигураций, фикстур или поиска элементов в коллекциях.

Основные сценарии использования в тестах:

  1. Безопасное получение тестовых данных:
    // Конфигурационный класс может вернуть null, если ключ не найден
    Optional<String> baseUrl = Config.getProperty("app.base.url");
    // Вместо проверки if (baseUrl != null) используем:
    String url = baseUrl.orElseThrow(() -> 
    new RuntimeException("Base URL is not configured in test properties"));
    DriverManager.getDriver().get(url);
  2. Поиск элемента в списке или мапе (вспомогательные методы):
    public Optional<WebElement> findElementSafe(By locator) {
    try {
        return Optional.of(driver.findElement(locator));
    } catch (NoSuchElementException e) {
        return Optional.empty(); // Элемент не найден, но тест не падает здесь
    }
    }
    // Использование в тесте:
    findElementSafe(By.id("dynamic-widget"))
    .ifPresentOrElse(
        widget -> widget.click(), // Действие, если элемент есть
        () -> log.info("Widget not present, skipping interaction") // Если нет
    );
  3. Цепочки преобразований с безопасной обработкой отсутствующих значений:
    
    // Получение текста из элемента, который может отсутствовать, и его преобразование
    Optional<Integer> itemCount = findElementSafe(By.cssSelector(".cart-count"))
    .map(WebElement::getText)
    .map(String::trim)
    .filter(text -> !text.isEmpty())
    .map(Integer::parseInt); // Если на любом этапе будет null/empty, результат - Optional.empty()

int count = itemCount.orElse(0); // Значение по умолчанию для ассерта assertEquals(5, count, "Cart should contain 5 items");


**Преимущества для QA:** Код становится более читаемым, уменьшается количество `NullPointerException` в тестах, явно показывается намерение работать с потенциально отсутствующим значением. Однако важно не злоупотреблять `Optional` для простых случаев, где `if (obj != null)` достаточно.