Как Использовать Один Браузер Для Нескольких Тестов В Pytest
Привет, ребята! Если вы только начинаете свой путь в автоматизированном тестировании, как и я когда-то, то наверняка сталкивались с вопросом, как эффективно использовать браузер в ваших тестах. Особенно, когда у вас много тестов, разбросанных по разным файлам. Сегодня мы разберемся, как запустить один браузер для нескольких тестов в разных файлах Python, используя Pytest. Это поможет вам сэкономить ресурсы и время, а также сделает ваши тесты более быстрыми и эффективными. Итак, поехали!
Проблема: Множество браузеров, медленные тесты
Когда я только начинал писать автотесты, у меня была такая же проблема. Каждый тест запускал свой собственный экземпляр браузера, что приводило к следующим проблемам:
- Медленное выполнение тестов: Запуск и остановка браузера для каждого теста занимает много времени. Если у вас сотни тестов, это может превратиться в кошмар.
- Большая нагрузка на систему: Каждый экземпляр браузера потребляет ресурсы компьютера. Если у вас одновременно запущено много тестов, это может привести к замедлению работы системы.
- Сложность в управлении: Когда каждый тест работает в своем браузере, сложнее отслеживать и управлять состоянием тестов.
Чтобы избежать этих проблем, нам нужно научиться использовать один браузер для нескольких тестов. К счастью, Pytest предоставляет нам мощные инструменты для этого.
Решение: Pytest Fixtures и Scope
Основным инструментом для решения этой задачи в Pytest являются fixtures. Fixtures – это функции, которые выполняются перед или после тестов и предоставляют тестовым функциям ресурсы или состояния. В нашем случае, мы будем использовать fixture для запуска браузера один раз перед всеми тестами и закрытия его после завершения всех тестов.
Ключевым понятием здесь является scope fixture. Scope определяет, как часто fixture будет выполняться. Pytest предоставляет несколько scope:
function
(по умолчанию): Fixture выполняется для каждой тестовой функции.class
: Fixture выполняется один раз для каждого класса тестов.module
: Fixture выполняется один раз для каждого модуля (файла) тестов.session
: Fixture выполняется один раз для всей тестовой сессии.
В нашем случае, мы будем использовать scope session
, чтобы браузер запускался только один раз для всей сессии тестов.
Шаг 1: Создание Fixture для Браузера
Для начала, создадим fixture, который будет запускать браузер. Я буду использовать Chrome, но вы можете выбрать любой другой браузер, поддерживаемый Selenium. Вот пример кода:
import pytest
from selenium import webdriver
@pytest.fixture(scope="session")
def browser():
driver = webdriver.Chrome()
yield driver
driver.quit()
Давайте разберем этот код:
@pytest.fixture(scope="session")
: Этот декоратор говорит Pytest, что это fixture с scopesession
.def browser():
: Это наша функция fixture. Она запускает браузер.driver = webdriver.Chrome()
: Это код, который запускает Chrome.yield driver
: Ключевое словоyield
делает эту функцию генератором. Оно возвращает объектdriver
тестовым функциям, а код послеyield
будет выполнен после завершения всех тестов.driver.quit()
: Этот код закрывает браузер.
Теперь у нас есть fixture, который запускает браузер один раз для всей сессии тестов.
Шаг 2: Использование Fixture в Тестах
Теперь, когда у нас есть fixture, мы можем использовать его в наших тестах. Для этого просто добавьте имя fixture (в нашем случае, browser
) в качестве аргумента в тестовую функцию. Вот пример:
def test_example(browser):
browser.get("https://www.google.com")
assert "Google" in browser.title
В этом примере, Pytest автоматически передаст объект driver
, созданный нашим fixture browser
, в тестовую функцию test_example
. Мы можем использовать этот объект для взаимодействия с браузером, например, для открытия веб-страницы и проверки заголовка.
Шаг 3: Организация Тестов по Файлам
Теперь давайте представим, что у нас есть несколько файлов с тестами. Например:
test_login.py
: Содержит тесты для проверки функциональности входа в систему.test_profile.py
: Содержит тесты для проверки функциональности профиля пользователя.
Мы можем использовать fixture browser
в тестах в обоих файлах. Pytest автоматически запустит браузер один раз для всех тестов в обоих файлах.
Пример test_login.py
:
# test_login.py
def test_login_success(browser):
browser.get("https://example.com/login")
# ... (код для входа в систему)
assert "Welcome" in browser.page_source
def test_login_failure(browser):
browser.get("https://example.com/login")
# ... (код для ввода неверных учетных данных)
assert "Invalid credentials" in browser.page_source
Пример test_profile.py
:
# test_profile.py
def test_profile_update(browser):
browser.get("https://example.com/profile")
# ... (код для обновления профиля)
assert "Profile updated" in browser.page_source
def test_profile_view(browser):
browser.get("https://example.com/profile")
# ... (код для просмотра профиля)
assert "Profile" in browser.title
Как видите, мы используем fixture browser
в каждой тестовой функции, и Pytest позаботится о том, чтобы браузер был запущен только один раз для всех тестов.
Дополнительные Советы и Трюки
1. Использование Conftest.py
Чтобы не дублировать код fixture в каждом файле тестов, вы можете определить fixture в специальном файле conftest.py
. Pytest автоматически обнаруживает этот файл и делает fixture, определенные в нем, доступными для всех тестов в проекте.
Пример conftest.py
:
# conftest.py
import pytest
from selenium import webdriver
@pytest.fixture(scope="session")
def browser():
driver = webdriver.Chrome()
yield driver
driver.quit()
Теперь вы можете удалить fixture browser
из ваших тестовых файлов, и Pytest будет использовать fixture, определенный в conftest.py
.
2. Передача Параметров Браузера
Иногда вам может понадобиться передавать параметры в браузер, например, для запуска в headless режиме или для установки размера окна. Вы можете сделать это, добавив аргументы командной строки в Pytest и используя их в fixture.
Пример:
# conftest.py
import pytest
from selenium import webdriver
def pytest_addoption(parser):
parser.addoption("--headless", action="store_true", help="Run browser in headless mode")
@pytest.fixture(scope="session")
def browser(pytestconfig):
headless = pytestconfig.getoption("headless")
options = webdriver.ChromeOptions()
if headless:
options.add_argument("--headless")
driver = webdriver.Chrome(options=options)
yield driver
driver.quit()
В этом примере мы добавили аргумент командной строки --headless
, который позволяет запускать Chrome в headless режиме. Мы используем pytestconfig
для получения значения этого аргумента и передачи его в ChromeOptions.
3. Использование Docker
Если вы хотите еще больше упростить настройку окружения для тестирования, вы можете использовать Docker. Docker позволяет вам запускать браузер в изолированном контейнере, что гарантирует, что у вас будет консистентное окружение для тестов, независимо от вашей операционной системы. Docker — это мощный инструмент, который помогает разработчикам и тестировщикам создавать, развертывать и запускать приложения в контейнерах. Контейнеры — это как легковесные виртуальные машины, которые содержат все необходимое для запуска приложения, включая код, библиотеки, зависимости и настройки.
Для запуска тестов в Docker вам потребуется Dockerfile, который определяет, как будет создан контейнер, и docker-compose.yml, который определяет, как будут запущены контейнеры.
Dockerfile (пример):
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["pytest"]
docker-compose.yml (пример):
version: "3.9"
services:
web:
build: .
ports:
- "8000:8000"
depends_on:
- chrome
chrome:
image: selenium/standalone-chrome
ports:
- "4444:4444"
Этот пример показывает, как запустить Chrome в отдельном контейнере и связать его с вашим приложением. Это позволяет вам запускать тесты в изолированном окружении, что делает их более надежными и предсказуемыми.
Заключение
В этой статье мы рассмотрели, как запустить один браузер для нескольких тестов в разных файлах Python, используя Pytest. Мы узнали, как использовать fixtures с scope session
для запуска браузера один раз для всей сессии тестов, как использовать conftest.py
для организации fixtures, как передавать параметры в браузер и как использовать Docker для упрощения настройки окружения. Надеюсь, эти советы помогут вам сделать ваши тесты более быстрыми, эффективными и надежными. Если у вас есть какие-либо вопросы или комментарии, не стесняйтесь задавать их в комментариях! Удачи вам в автоматизированном тестировании, ребята!
FAQ
1. Что делать, если тесты падают из-за состояния браузера?
Если тесты падают из-за состояния браузера, попробуйте очищать куки и локальное хранилище после каждого теста. Вы можете добавить код для этого в fixture browser
.
2. Как запустить тесты параллельно?
Pytest имеет плагин pytest-xdist
, который позволяет запускать тесты параллельно. Это может значительно ускорить выполнение тестов.
3. Как использовать разные браузеры для тестов?
Вы можете создать несколько fixtures для разных браузеров и использовать их в тестах в зависимости от ваших потребностей.
4. Как логировать действия браузера?
Selenium предоставляет возможности для логирования действий браузера. Вы можете настроить логирование, чтобы отслеживать ошибки и проблемы в ваших тестах.
5. Как делать скриншоты при падении тестов?
Вы можете добавить код в fixture browser
, который будет делать скриншот при падении теста. Это может быть полезно для отладки проблем.
Дополнительные ресурсы
Надеюсь, эта статья была полезной для вас. Удачи в ваших проектах по автоматизации тестирования! И помните, автоматизированное тестирование — это ключ к созданию качественного и надежного программного обеспечения. Не бойтесь экспериментировать и пробовать новые подходы, и вы обязательно достигнете успеха!