автор Малаховская Екатерина
Selenium WebDriver C#
и общие вопросы по автоматизации
Почти на всех моих собеседованиях на позиции по автоматизации тестирования мне давали одно и то же практическое задание:

Интервьюер присылал мне простой тестовый сценарий, который нужно было автоматизировать.

Обычно это что-то простое, например: вход в приложение с последующей проверкой успешного входа, или открытие страницы и добавление товара в корзину.

Я рекомендую начать с простого теста, а затем модифицировать его, добавив методы SetUp и TearDown, перенести логику в модель Page Object и настроить тестирование на нескольких браузерах.
Не забывайте о базовых правилах использования ожиданий и утверждений (assertions)!

Также не забывайте, что очень важно уметь находить элементы на странице (повторите XPath!).

Помимо практической части, вам также могут задать следующие вопросы, связанные с автоматизацией:
*** Сначала я записал вопросы, которые мне часто задавали на собеседованиях. После этого добавил другие вопросы, которые, как я считаю, также могут быть заданы.

1. Можете объяснить, как вы структурируете фреймворк автоматизации тестирования с использованием C#?


Я следую паттерну Page Object Model (POM), который отделяет код, специфичный для страниц (локаторы и действия), от логики тестирования. Моя структура обычно выглядит следующим образом:
  • Test Scripts: Содержит тестовые сценарии.
  • Page Objects: Содержит методы и локаторы, специфичные для страниц.
  • Utilities: Вспомогательные функции, управление конфигурацией и общие действия.
  • Test Data: Внешние файлы (JSON/Excel) для управления тестовыми данными.
  • Test Runner: Я использую NUnit для запуска и отчетности по тестам.

2. Какие существуют способы локализации элементов в Selenium WebDriver?

В Selenium существует несколько способов локализации элементов:
  • By.Id: driver.FindElement(By.Id("element_id"))
  • By.Name: driver.FindElement(By.Name("element_name"))
  • By.XPath: driver.FindElement(By.XPath("//tag[@attribute='value']"))
  • By.CssSelector: driver.FindElement(By.CssSelector(".class_name"))
  • Также есть: By.ClassName, By.TagName, By.LinkText, By.PartialLinkText.
Я обычно предпочитаю Id, XPath и CssSelector, так как они быстрые и надежные.

3. Как вы справляетесь с динамическими элементами на странице?

Для динамических элементов я использую гибкие локаторы, такие как относительный XPath или динамические CSS-селекторы, а также явные ожидания (explicit waits), чтобы убедиться, что элемент присутствует перед взаимодействием с ним.

Также, если это возможно, я прошу разработчиков добавить атрибут data-testid к динамическим элементам. Однако, важно продумать, как удалить такие атрибуты в продакшене. На моем последнем проекте у нас был скрипт, который удалял все атрибуты data-testid в окружении продакшена.

4. Какие типы ожиданий доступны в Selenium?

Selenium предоставляет три основных типа ожиданий:
Implicit Wait (Неявное ожидание): Устанавливает время ожидания по умолчанию для всех поисков элементов.
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
Explicit Wait (Явное ожидание): Ожидает наступления определённого условия.
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.ElementIsVisible(By.Id("element_id")));
Fluent Wait (Плавное ожидание): Позволяет задавать интервалы опроса и игнорировать такие исключения, как NoSuchElementException.
FluentWait<IWebDriver> wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.PollingInterval = TimeSpan.FromMilliseconds(500);

5. Как вы достигаете параллельного выполнения в Selenium с использованием C#?

Я использую атрибут NUnit [Parallelizable] для параллельного выполнения:
[Test, Parallelizable]
public void TestMethod()
{
    // Test logic
}
Также можно задать DegreeOfParallelism в конфигурации NUnit для одновременного запуска тестов.

6. Как вы обеспечиваете поддерживаемость и масштабируемость ваших тестов?

Я следую следующим лучшим практикам:
  • Page Object Model (POM): Отделяет локаторы от логики тестов.
  • Модульные тесты: Использование повторно используемых методов для общих действий.
  • Избегайте хардкода: Храните тестовые данные во внешних источниках.
  • Эффективные ожидания: Используйте явные ожидания для работы с динамическим контентом.

7. Как вы управляете тестовыми данными в своих автоматизированных тестах?

Я выношу тестовые данные во внешние источники, такие как JSON, Excel или базы данных, и загружаю их в тесты во время выполнения. Это позволяет легко изменять данные без необходимости менять код тестов.
Для конфиденциальных данных, таких как учетные данные (например, API-ключи, пароли), я соблюдаю лучшие практики безопасности:
  • Переменные окружения: Храню чувствительную информацию в переменных окружения, а не в коде тестов. Эти переменные настраиваются в тестовом окружении и могут быть безопасно доступны во время выполнения тестов.
  • Безопасные хранилища: Использую инструменты управления секретами, такие как Azure Key Vault, AWS Secrets Manager или HashiCorp Vault, для безопасного хранения учетных данных. Тесты могут получать учетные данные во время выполнения через безопасные API.

8. Как вы интегрируете тесты Selenium в CI/CD pipeline?

Я использую инструменты CI, такие как GitLab или Azure DevOps, для интеграции тестов Selenium. После того как код закоммичен в систему контроля версий (например, Git), GitLab автоматически запускает тесты, а результаты отображаются в отчетах.

9. Как вы генерируете отчеты для автоматизированных тестов?

Я использую такие инструменты, как ExtentReports или встроенную отчетность NUnit для генерации HTML-отчетов с детализированными результатами тестов. Кроме того, я веду логирование важных событий и делаю скриншоты в случае неудач.

На моем текущем проекте я интегрировал XRay с GitLab и генерировал отчеты в XRay.

10. С какими распространенными проблемами вы сталкивались при автоматизации тестирования и как вы их решали?

Некоторые проблемы включают:
  • Нестабильные тесты: Я решил эту проблему, используя правильные ожидания, избегая жестко закодированных задержек (sleep) и перерабатывая ненадежные локаторы.
  • Динамический контент: Управлял этим с помощью гибких локаторов (например, XPath или CSS, которые адаптируются к изменяющемуся контенту).
  • Поддержка тестов: Сократил расходы на поддержку, используя паттерны проектирования, такие как POM, и вынесение тестовых данных во внешние источники.
  • Совместимость браузеров: Убедился, что тесты работают в разных браузерах, регулярно проводя кроссбраузерные тесты и адаптируя код к специфике поведения браузеров.

11. Опишите шаги, которые вы предпринимаете, когда получаете задачу на тестирование. Какие действия вы предпринимаете и как решаете, стоит ли автоматизировать задачу?

Я начинаю с тщательного изучения требований, пользовательских историй или критериев приемки. Если что-то неясно, я связываюсь с владельцем продукта, разработчиками или заинтересованными сторонами, чтобы прояснить детали.

Я разбиваю задачу на несколько тестовых сценариев, включая позитивные, негативные, граничные и пограничные случаи.

Я оцениваю возможные последствия в случае сбоя этой функции (высокий, средний, низкий риск). Критически важные функции (например, авторизация, оплата), которые влияют на пользовательский опыт или бизнес, требуют особого внимания.

Чтобы решить, стоит ли автоматизировать задачу, я оцениваю следующие моменты:
  • Если задача включает в себя повторяющиеся действия (например, регрессионные тесты, smoke-тесты), она хорошо подходит для автоматизации.
  • Если эту функцию нужно будет регулярно тестировать в разных окружениях или после нескольких развертываний (CI/CD), автоматизация необходима.
  • Если функция стабильна и вряд ли будет часто изменяться, автоматизация в долгосрочной перспективе сэкономит время.
  • Основываясь на оценке рисков и решении об автоматизации, я определяю стратегию тестирования (ручное или автоматизированное). Я выполняю тестовые сценарии, регистрирую найденные дефекты и документирую процесс. Я обеспечиваю поддерживаемость тестов и регулярно запускаю их как часть CI-пайплайна, а также обновляю их по мере эволюции приложения.

12. Некоторые тесты не прошли в пайплайне. Какие ваши действия?

Я просматриваю отчеты и логи тестов, чтобы определить, какие конкретные тесты не прошли, и анализирую сообщения об ошибках или трассировку стека.
Определяю, является ли причина сбоя багом в приложении или проблемой с самим тестом (например, нестабильный тест, некорректные утверждения или устаревшие тестовые данные).

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

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

Если проблема связана с нестабильным тестом, устаревшими локаторами или тестовыми данными, я обновляю код теста, локаторы или тестовые данные по мере необходимости.

Если проблема вызвана багом в приложении, я документирую ее.
Если проблема связана с CI-пайплайном, я работаю с командой DevOps для решения проблемы.

*** Следующие вопросы важны для интервью.
13. Что такое Selenium WebDriver и как он работает?

Selenium WebDriver — это инструмент с открытым исходным кодом, используемый для автоматизации веб-приложений. Он взаимодействует напрямую с браузером, используя его нативную поддержку (драйверы браузеров, такие как ChromeDriver, GeckoDriver). WebDriver отправляет команды в браузер и получает результаты, что позволяет автоматизировать действия в браузере, такие как нажатия, ввод текста и навигация.

14. В чем ключевые отличия между Selenium WebDriver и Selenium Grid?

Selenium WebDriver используется для автоматизации браузера на одном устройстве. Selenium Grid позволяет запускать тесты WebDriver на нескольких машинах и браузерах параллельно, что полезно для кроссбраузерного и распределенного тестирования.

15. Как вы управляете драйверами браузеров в Selenium WebDriver?

Для управления различными браузерами я инициализирую соответствующий WebDriver для каждого браузера. Например, для использования Chrome я инициализирую ChromeDriver, для Firefox — GeckoDriver и так далее. Пример на C#:
IWebDriver driver = new ChromeDriver();

16. Как вы управляете конфигурацией в проектах автоматизации тестирования на C#?

Я использую конфигурационные файлы, такие как app.config или json, для хранения настроек, таких как базовые URL-адреса, тип браузера, детали окружения и учетные данные. Эти файлы позволяют легко обновлять настройки и переключаться между окружениями без изменения кода.

17. В чем разница между sleep() и WebDriverWait в Selenium?

Thread.Sleep() приостанавливает выполнение на фиксированное время, независимо от условий. Это может замедлить тесты и не является надежным для динамического контента.

WebDriverWait, с другой стороны, ждет до тех пор, пока не будет выполнено определенное условие (например, элемент станет видимым), что делает его более эффективным и надежным.

18. Какие распространенные исключения вы встречали в Selenium WebDriver?

NoSuchElementException: Элемент не найден.

StaleElementReferenceException: Элемент больше не привязан к DOM.

TimeoutException: Операция превышает установленное время ожидания.

19. Как вы приоритизируете тест-кейсы для автоматизации?

Я приоритизирую тест-кейсы, которые:
  • Повторяются и должны запускаться часто.
  • Имеют высокий бизнес-импакт или критичны для приложения.
  • Стабильны и менее подвержены изменениям.
  • Затратны по времени или трудоемки для ручного выполнения.

Тесты с низким приоритетом:
  • Те, которые запускаются один раз или вряд ли будут повторяться.
  • Исследовательские тесты, требующие человеческого анализа.

20. Как вы обрабатываете исключения в своих тестовых скриптах?

Распространенные исключения в Selenium включают NoSuchElementException, StaleElementReferenceException и TimeoutException.

Для их обработки я:
  • Использую блоки try-catch для перехвата и логирования исключений.
  • Реализую повторные попытки, если это уместно.
  • Использую ожидания (например, WebDriverWait), чтобы убедиться, что элементы присутствуют перед взаимодействием с ними.
try
{
    IWebElement element = driver.FindElement(By.Id("element_id"));
    element.Click();
}
catch (NoSuchElementException e)
{
    Console.WriteLine("Element not found: " + e.Message);
}

21. В чем разница между findElement() и findElements() в Selenium?

findElement() возвращает первый найденный элемент на основе локатора и вызывает NoSuchElementException, если элемент не найден.

findElements() возвращает список всех соответствующих элементов и возвращает пустой список, если элементы не найдены, без генерации исключения.

22. Как бы вы тестировали REST API?

Для тестирования REST API я обычно:
  • Отправляю запросы с использованием HTTP-методов, таких как GET, POST, PUT и DELETE.
  • Проверяю коды ответов: Убеждаюсь, что ответы, такие как 200, 404 и 500, обработаны корректно.
  • Проверяю тело ответа: Удостоверяюсь, что возвращаемые данные корректны и соответствуют ожидаемому формату (например, структура JSON).
  • Проверяю производительность: Контролирую время отклика для оптимизации. Для этих тестов можно использовать такие инструменты, как Postman, RestSharp (для C#) или Selenium с библиотеками API.

23. Как вы обрабатываете загрузку и выгрузку файлов в Selenium WebDriver?

Для загрузки файлов я отправляю путь к файлу напрямую в элемент input:
driver.FindElement(By.Name("fileUpload")).SendKeys("C:\\path\\to\\file.txt");
Для загрузки файлов я настраиваю браузер так, чтобы он автоматически обрабатывал загрузки, часто через настройку предпочтений в Chrome или Firefox. Я также проверяю наличие файла в каталоге загрузки.

Скачать шпаргалку на английском с вопросами и ответами можно здесь:

Хотите лучше разбираться в тестировании и узнать много примеров из практики от опытных преподавателей - приходите на наш курс В тестировщики с нуля!
В тестировщики с нуля
  • 320$
    Lite
    Включает в себя:
    - Пакет В тестировщики с нуля
    - Интенсив по GIT
    - 1 месяц стажировки
  • 400$
    Medium
    Включает в себя:
    - Пакет В тестировщики с нуля
    - Интенсив по GIT
    - Доступ к вебинарам
    - 2 месяца стажировки
  • 540$
    Maximum
    Включает в себя:
    - Пакет В тестировщики с нуля
    - Интенсив по GIT
    - Доступ к вебинарам
    - Курс Тестирование API
    - 4 месяца стажировки
Полезные ресурсы и советы для поиска работы
Выпускник школы QaLearning рассказывает про свой путь обучения, поиска работы и прохождения собеседований. Вы получите много дельных советов!