Selenium WebDriver: полное руководство по автоматизации тестирования

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Специалисты по тестированию программного обеспечения (QA)
  • Разработчики, интересующиеся автоматизацией тестирования
  • Новички в области IT, желающие освоить навыки тестирования с использованием Selenium

    Ручное тестирование веб-приложений — процесс, отнимающий уйму времени и чреватый человеческими ошибками. Когда проект растет, а количество проверок увеличивается в геометрической прогрессии, становится очевидно: автоматизация — не роскошь, а необходимость. Selenium WebDriver — мощный инструмент, способный превратить часы утомительного кликанья по страницам в минуты автоматического выполнения тестов. В этом пошаговом руководстве мы пройдём путь от установки первого драйвера до создания масштабируемой архитектуры тестов, которая избавит вас от рутины и поднимет качество продукта на новый уровень. 🚀

Хотите не просто узнать, а по-настоящему освоить автоматизацию тестирования? На Курсе тестировщика ПО от Skypro вы получите практические навыки работы с Selenium под руководством действующих инженеров из топовых компаний. Вместо сухой теории — реальные проекты, которые пополнят ваше портфолио. За 9 месяцев вы трансформируетесь из новичка в востребованного QA-инженера с гарантированным трудоустройством. Ваша карьера в IT ждёт!

Что такое Selenium и почему он нужен для автоматизации

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

В отличие от других инструментов, Selenium обеспечивает кроссбраузерное тестирование, поддерживая все популярные браузеры: Chrome, Firefox, Safari, Edge и даже мобильные браузеры через Appium. Это позволяет убедиться, что ваше приложение работает одинаково хорошо для всех пользователей, независимо от их предпочтений.

Основные преимущества Selenium для автоматизации тестирования:

  • Бесплатность и открытый исходный код — никаких лицензионных платежей
  • Поддержка множества языков программирования: Java, Python, C#, JavaScript и других
  • Интеграция с CI/CD-инструментами для непрерывного тестирования
  • Огромное сообщество разработчиков и богатая экосистема дополнительных инструментов
  • Возможность создания сложных сценариев с условной логикой и проверками

Для многих компаний внедрение автоматизации на базе Selenium становится поворотным моментом в развитии процессов тестирования. Вот сравнительная таблица, демонстрирующая экономию времени при использовании автоматизации:

Задача тестирования Ручное тестирование (часы) Автоматизация с Selenium (часы) Экономия времени (%)
Регрессионное тестирование (50 кейсов) 8-10 0.5-1 90%
Кросс-браузерное тестирование (5 браузеров) 15-20 2-3 85%
Тестирование форм ввода данных 3-4 0.2-0.3 93%
Проверка UI на различных разрешениях 5-7 0.5-1 86%

Алексей Петров, Lead QA Engineer

Когда наша команда столкнулась с необходимостью тестировать e-commerce платформу с тысячами товаров и десятками интеграций, мы поняли: ручным тестированием не обойтись. Релизы дважды в неделю, а регрессионное тестирование занимало до трёх дней. Внедрение Selenium позволило автоматизировать 80% критичных сценариев.

Помню наш первый запуск полного набора тестов — то, что раньше занимало у команды из пяти человек 24 часа, теперь выполнялось за 40 минут. Когда через месяц после внедрения мы обнаружили критичный баг в процессе оформления заказа на одной из страниц, которую редко посещали пользователи, стало очевидно: Selenium не просто экономит время — он находит то, что мы, вероятно, пропустили бы при ручном тестировании.

Пошаговый план для смены профессии

Настройка среды для работы с Selenium WebDriver

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

Шаг 1: Выбор и установка языка программирования

Selenium поддерживает множество языков, но для начинающих я рекомендую Python или Java. Python отличается лаконичным синтаксисом и подходит для быстрого старта, а Java — более строгий язык, востребованный в крупных проектах.

  • Для Python: Установите Python 3.x с официального сайта
  • Для Java: Установите JDK 11+ и Maven для управления зависимостями

Шаг 2: Установка Selenium WebDriver

Для Python:

pip install selenium

Для Java (добавьте в pom.xml):

<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.10.0</version>
</dependency>

Шаг 3: Установка драйверов браузеров

WebDriver требует специфичных для каждого браузера драйверов. Существует два способа их использования:

  1. Автоматический способ (рекомендуется с Selenium 4+): Использование Selenium Manager
  2. Ручной способ: Загрузка и настройка путей к драйверам

Для автоматического управления драйверами в Python:

from selenium import webdriver
driver = webdriver.Chrome() # Selenium Manager автоматически найдет и установит драйвер

Для ручной установки драйверов:

Шаг 4: Настройка фреймворка для тестирования

Для структурирования тестов рекомендую использовать специализированный фреймворк:

  • Python: pytest или unittest
  • Java: JUnit или TestNG

Для Python:

pip install pytest pytest-html

Сравнение популярных сред разработки для работы с Selenium:

IDE Поддержка языков Плагины для Selenium Отладка тестов Подходит для начинающих
PyCharm Python Selenium, Pytest Отличная Да
IntelliJ IDEA Java, Python, JS Selenium, JUnit, TestNG Превосходная Средне
Visual Studio Code Все основные Через расширения Хорошая Да
Eclipse Java, C++ Selenium, TestNG Хорошая Нет

Шаг 5: Проверка настройки

Создайте простой скрипт для проверки корректности установки:

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://www.google.com")
search_box = driver.find_element(By.NAME, "q")
search_box.send_keys("Selenium WebDriver")
search_box.submit()
print("Заголовок страницы:", driver.title)
driver.quit()

Если скрипт выполнится без ошибок, значит ваша среда настроена правильно, и вы готовы двигаться дальше! 🎯

Основные методы поиска элементов в Selenium

Поиск элементов — фундамент любой автоматизации в Selenium. От правильности выбора селектора зависит стабильность и надежность тестов. Освоив эти методы, вы сможете взаимодействовать с любыми элементами на веб-странице, даже если разработчики меняют их внешний вид или позиционирование. 🔍

В Selenium WebDriver поиск элементов реализуется через два основных метода:

  • find_element() — возвращает первый найденный элемент
  • find_elements() — возвращает список всех найденных элементов

Эти методы используются в сочетании с локаторами — специальными идентификаторами элементов на странице. Рассмотрим основные типы локаторов по степени надежности:

  1. ID — самый надежный и быстрый способ поиска
  2. Name — хорошая альтернатива, когда ID недоступен
  3. CSS-селекторы — мощный и гибкий метод поиска
  4. XPath — универсальный, но сложный и потенциально хрупкий метод
  5. Class Name — полезен, когда элементы имеют уникальные классы
  6. Tag Name — слишком общий, обычно используется в комбинации с другими методами
  7. Link Text и Partial Link Text — специфичны для ссылок

Примеры использования различных локаторов:

# По ID
element = driver.find_element(By.ID, "login-button")

# По имени
element = driver.find_element(By.NAME, "username")

# По CSS-селектору
element = driver.find_element(By.CSS_SELECTOR, ".product-card:nth-child(3)")

# По XPath
element = driver.find_element(By.XPATH, "//div[@class='menu']/ul/li[3]")

# По классу
elements = driver.find_elements(By.CLASS_NAME, "product-item")

# По тегу
elements = driver.find_elements(By.TAG_NAME, "a")

# По тексту ссылки
element = driver.find_element(By.LINK_TEXT, "Перейти в корзину")

# По части текста ссылки
element = driver.find_element(By.PARTIAL_LINK_TEXT, "корзину")

Сравнение эффективности различных локаторов:

Тип локатора Скорость выполнения Устойчивость к изменениям Сложность написания Рекомендуется для
ID Высокая Высокая (если ID статичен) Низкая Первый выбор, если доступен
Name Высокая Средняя Низкая Формы ввода данных
CSS Высокая Средняя Средняя Большинство сценариев
XPath Низкая Низкая (абсолютный) / Средняя (относительный) Высокая Сложные структуры, динамические элементы
Class Name Средняя Низкая Низкая Поиск групп элементов
Tag Name Высокая Низкая Низкая Поиск всех элементов одного типа
Link Text Средняя Низкая (зависит от локализации) Низкая Навигационные элементы

Стратегии создания надежных локаторов:

  • Используйте data-атрибуты — попросите разработчиков добавлять специальные атрибуты для автоматизации (например, data-testid="login-button")
  • Применяйте относительные локаторы — в Selenium 4+ появились новые методы: with_tag_name("div").above(element)
  • Комбинируйте локаторы для создания уникального пути к элементу
  • Избегайте индексов в селекторах, так как они часто меняются при обновлении страницы

Инструменты для определения локаторов:

  • DevTools в браузере — Ctrl+Shift+I или F12
  • Расширение Selenium IDE для записи и определения элементов
  • ChroPath — расширение для Chrome, автоматически создает XPath и CSS-селекторы

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

# Поиск элемента с помощью JavaScript
element = driver.execute_script("return document.getElementById('complex-element')")

# Прокрутка до элемента перед взаимодействием
element = driver.find_element(By.ID, "element-at-bottom")
driver.execute_script("arguments[0].scrollIntoView();", element)

Мария Соколова, Senior QA Automation Engineer

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

Решение пришло не сразу. Мы начали с попытки использовать XPath, но он оказался слишком медленным для масштабной системы. Затем я предложила стратегию: запросить у команды разработки добавление специальных data-test-id атрибутов для ключевых элементов интерфейса.

Первоначально идея встретила сопротивление — "лишний код", "затраты времени". Я подготовила презентацию, показывающую, сколько часов команда QA тратит на поддержку падающих тестов после каждого релиза. Цифры оказались убедительнее слов — за год мы тратили почти 200 человеко-часов только на обновление локаторов!

После внедрения data-атрибутов стабильность наших тестов выросла с 60% до 98%. Теперь даже при серьезном редизайне интерфейса наши автотесты продолжают работать, экономя компании значительные ресурсы.

Помните: правильный выбор локаторов — это искусство, требующее практики. Начните с простых и надежных методов, постепенно осваивая более сложные техники по мере необходимости. Ваша цель — создать тесты, которые не сломаются при незначительных изменениях интерфейса. 💪

Создание первого автоматизированного теста

Теория без практики мертва, поэтому давайте реализуем полноценный автоматизированный тест с использованием Selenium WebDriver. Мы создадим тест, который проверит функциональность входа в систему на демо-сайте. Этот пример станет фундаментом, на котором вы сможете построить более сложные тестовые сценарии. 🛠️

Для начала определим, что именно мы хотим протестировать:

  1. Открытие страницы входа
  2. Ввод корректных учетных данных
  3. Нажатие кнопки входа
  4. Проверка успешного входа (наличие приветствия или переход в личный кабинет)

Приступим к написанию теста на Python с использованием pytest:

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

@pytest.fixture
def browser():
# Подготовка драйвера перед каждым тестом
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10) # Неявное ожидание для всех элементов
yield driver
# Завершение работы драйвера после теста
driver.quit()

def test_successful_login(browser):
# Шаг 1: Открыть страницу входа
browser.get("https://demo.opencart.com/index.php?route=account/login")

# Шаг 2: Ввод учетных данных
email_field = browser.find_element(By.ID, "input-email")
password_field = browser.find_element(By.ID, "input-password")

email_field.send_keys("test@example.com")
password_field.send_keys("password123")

# Шаг 3: Нажатие кнопки входа
login_button = browser.find_element(By.CSS_SELECTOR, "input[value='Login']")
login_button.click()

# Шаг 4: Проверка успешного входа
# Использование явного ожидания для элемента, подтверждающего вход
account_header = WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.XPATH, "//h2[text()='My Account']"))
)

# Проверка, что мы действительно на странице аккаунта
assert "My Account" in browser.title
assert account_header.is_displayed()

Разбор ключевых компонентов теста:

  • Фикстура browser — настраивает и закрывает WebDriver для каждого теста
  • implicitly_wait(10) — задает неявное ожидание элементов до 10 секунд
  • find_element — поиск элементов страницы по различным локаторам
  • send_keys — эмуляция ввода текста пользователем
  • click — эмуляция нажатия на элемент
  • WebDriverWait с expected_conditions — явное ожидание определенного состояния элемента
  • assert — проверка ожидаемого результата

Добавление проверок и обработка ошибок

Хороший тест должен не только проверять позитивный сценарий, но и корректно обрабатывать возможные ошибки. Расширим наш тест:

def test_login_with_invalid_credentials(browser):
browser.get("https://demo.opencart.com/index.php?route=account/login")

# Ввод неверных учетных данных
email_field = browser.find_element(By.ID, "input-email")
password_field = browser.find_element(By.ID, "input-password")

email_field.send_keys("wrong@example.com")
password_field.send_keys("wrongpassword")

# Нажатие кнопки входа
login_button = browser.find_element(By.CSS_SELECTOR, "input[value='Login']")
login_button.click()

# Проверка появления сообщения об ошибке
error_message = WebDriverWait(browser, 10).until(
EC.visibility_of_element_located((By.CSS_SELECTOR, ".alert-danger"))
)

assert "Warning: No match for E-Mail Address and/or Password" in error_message.text

Советы по созданию эффективных тестов:

  • Используйте паттерн AAA (Arrange-Act-Assert): подготовка, действие, проверка
  • Добавляйте подробные комментарии к каждому шагу теста
  • Применяйте явные ожидания вместо неявных для критичных элементов
  • Делайте скриншоты в случае падения теста для упрощения отладки
  • Используйте параметризацию для запуска теста с различными входными данными

Пример параметризированного теста:

@pytest.mark.parametrize("email,password,expected_result", [
("test@example.com", "password123", True), # Валидные данные
("wrong@example.com", "password123", False), # Неверный email
("test@example.com", "wrongpass", False), # Неверный пароль
("", "", False), # Пустые поля
])
def test_login_scenarios(browser, email, password, expected_result):
browser.get("https://demo.opencart.com/index.php?route=account/login")

email_field = browser.find_element(By.ID, "input-email")
password_field = browser.find_element(By.ID, "input-password")

email_field.send_keys(email)
password_field.send_keys(password)

login_button = browser.find_element(By.CSS_SELECTOR, "input[value='Login']")
login_button.click()

if expected_result:
# Проверка успешного входа
account_header = WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.XPATH, "//h2[text()='My Account']"))
)
assert "My Account" in browser.title
else:
# Проверка сообщения об ошибке
error_message = WebDriverWait(browser, 10).until(
EC.visibility_of_element_located((By.CSS_SELECTOR, ".alert-danger"))
)
assert "Warning" in error_message.text

Запуск и анализ результатов тестирования

Для запуска созданных тестов используйте следующую команду:

pytest test_login.py -v

Флаг -v (verbose) обеспечивает подробный вывод результатов. Для генерации HTML-отчета добавьте:

pytest test_login.py --html=report.html

Этот базовый пример демонстрирует основные принципы создания автоматизированных тестов с Selenium. По мере роста количества тестов вы столкнетесь с необходимостью лучшей организации кода — и здесь на помощь приходит паттерн Page Object Model, который мы рассмотрим в следующем разделе. 🚀

Масштабирование тестов с Page Object Model

По мере роста количества автоматизированных тестов вы неизбежно столкнетесь с проблемой: ваш код становится трудноподдерживаемым, а изменение элементов интерфейса требует правок во множестве тестов. Решением этой проблемы является паттерн Page Object Model (POM) — архитектурный подход, который значительно повышает масштабируемость и поддерживаемость тестов. 📈

Суть Page Object Model:

  • Каждая страница или компонент веб-приложения представляется отдельным классом
  • Элементы страницы и взаимодействия с ними инкапсулируются внутри соответствующего класса
  • Тесты взаимодействуют со страницами только через их публичные методы
  • При изменении интерфейса обновляется только класс страницы, а не все тесты

Давайте переработаем наш предыдущий тест входа в систему, применяя Page Object Model. Сначала создадим базовый класс для всех страниц:

class BasePage:
def __init__(self, driver):
self.driver = driver

def find_element(self, locator, timeout=10):
"""Поиск элемента с явным ожиданием"""
return WebDriverWait(self.driver, timeout).until(
EC.presence_of_element_located(locator)
)

def find_elements(self, locator, timeout=10):
"""Поиск элементов с явным ожиданием"""
return WebDriverWait(self.driver, timeout).until(
EC.presence_of_all_elements_located(locator)
)

def click_element(self, locator, timeout=10):
"""Клик по элементу с ожиданием кликабельности"""
element = WebDriverWait(self.driver, timeout).until(
EC.element_to_be_clickable(locator)
)
element.click()

def input_text(self, locator, text, timeout=10):
"""Ввод текста с предварительной очисткой поля"""
element = self.find_element(locator, timeout)
element.clear()
element.send_keys(text)

Теперь создадим класс страницы входа:

class LoginPage(BasePage):
# Локаторы страницы
EMAIL_FIELD = (By.ID, "input-email")
PASSWORD_FIELD = (By.ID, "input-password")
LOGIN_BUTTON = (By.CSS_SELECTOR, "input[value='Login']")
ERROR_MESSAGE = (By.CSS_SELECTOR, ".alert-danger")

def open(self):
"""Открывает страницу входа"""
self.driver.get("https://demo.opencart.com/index.php?route=account/login")
return self

def login(self, email, password):
"""Выполняет вход с указанными учетными данными"""
self.input_text(self.EMAIL_FIELD, email)
self.input_text(self.PASSWORD_FIELD, password)
self.click_element(self.LOGIN_BUTTON)

def get_error_message(self):
"""Возвращает текст сообщения об ошибке"""
error_element = self.find_element(self.ERROR_MESSAGE)
return error_element.text

def is_error_displayed(self):
"""Проверяет наличие сообщения об ошибке"""
try:
return self.find_element(self.ERROR_MESSAGE, timeout=5).is_displayed()
except:
return False

И класс страницы аккаунта:

class AccountPage(BasePage):
# Локаторы страницы
ACCOUNT_HEADER = (By.XPATH, "//h2[text()='My Account']")
LOGOUT_LINK = (By.LINK_TEXT, "Logout")

def is_user_logged_in(self):
"""Проверяет, что пользователь успешно вошел в систему"""
try:
return self.find_element(self.ACCOUNT_HEADER, timeout=5).is_displayed()
except:
return False

def logout(self):
"""Выполняет выход из системы"""
self.click_element(self.LOGOUT_LINK)

Теперь перепишем наши тесты, используя созданные классы:

def test_successful_login_pom(browser):
# Инициализация страниц
login_page = LoginPage(browser)
account_page = AccountPage(browser)

# Выполнение теста
login_page.open()
login_page.login("test@example.com", "password123")

# Проверка результатов
assert account_page.is_user_logged_in()
assert "My Account" in browser.title

def test_login_with_invalid_credentials_pom(browser):
# Инициализация страницы
login_page = LoginPage(browser)

# Выполнение теста
login_page.open()
login_page.login("wrong@example.com", "wrongpassword")

# Проверка результатов
assert login_page.is_error_displayed()
assert "Warning" in login_page.get_error_message()

Преимущества использования Page Object Model:

  1. Улучшенная поддерживаемость: изменения в UI затрагивают только соответствующие классы страниц
  2. Повторное использование кода: общие методы для работы со страницами доступны во всех тестах
  3. Читаемость тестов: тесты становятся декларативными, описывающими бизнес-процессы, а не технические детали
  4. Изоляция: разделение логики тестов от реализации взаимодействия с интерфейсом
  5. Удобство обновления: при изменении локаторов или логики нужно обновить только один класс

Расширенные техники для масштабирования тестов:

  • Цепочка методов (method chaining) для более элегантных тестов:
login_result = LoginPage(browser).open().login("test@example.com", "password123")
assert login_result.is_user_logged_in()

  • Компонентный подход: выделение повторяющихся компонентов (шапка, футер, меню) в отдельные классы
  • Фабрики страниц: автоматическая инициализация нужных страниц по мере навигации
  • Интеграция с системами отчётности вроде Allure для наглядной визуализации тестов

Page Object Model особенно полезен при работе в командах, где над тестами работают несколько специалистов. Этот паттерн создает единый стандарт взаимодействия с элементами интерфейса, что упрощает понимание и расширение тестового фреймворка.

Начиная с проекта с небольшого количества тестов, вы, возможно, не сразу оцените все преимущества POM. Однако, как только ваша тестовая база вырастет до десятков или сотен тестов, вы обнаружите, насколько проще поддерживать и масштабировать автоматизированное тестирование с этим архитектурным подходом. 🚀

Автоматизация веб-тестирования с Selenium — это не просто набор инструментов, а целая философия создания качественных и поддерживаемых тестов. Начав с понимания основ работы WebDriver и правильного поиска элементов, вы постепенно перейдете к созданию масштабируемой архитектуры с применением Page Object Model. Помните: главная ценность автоматизации не в количестве покрытых тестами функций, а в стабильности вашего тестового фреймворка и скорости получения обратной связи о качестве продукта. Начните с малого, следуйте лучшим практикам, и вскоре вы обнаружите, что ручное тестирование осталось в прошлом, а ваша команда может сосредоточиться на более сложных и интересных задачах, доверив рутину автоматическим тестам.

Читайте также

Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Что такое Selenium?
1 / 5

Загрузка...