Как Использовать Один Браузер Для Нескольких Тестов В Pytest

by Omar Yusuf 61 views

Привет, ребята! Если вы только начинаете свой путь в автоматизированном тестировании, как и я когда-то, то наверняка сталкивались с вопросом, как эффективно использовать браузер в ваших тестах. Особенно, когда у вас много тестов, разбросанных по разным файлам. Сегодня мы разберемся, как запустить один браузер для нескольких тестов в разных файлах 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 с scope session.
  • 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, который будет делать скриншот при падении теста. Это может быть полезно для отладки проблем.

Дополнительные ресурсы

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