Описаны: - Структура проекта и иерархия тестов - Быстрый старт (venv, зависимости, .env) - Команды запуска: все тесты / по роли / по БП / по шагу - Полезные флаги pytest (headed/headless, slowmo, -k, --co) - Шаблон создания нового бизнес-процесса вручную - Правила именования (папки, файлы, классы, методы, маркеры) - Инструкция по добавлению ФЛК-генератора - Инструкция по добавлению статического артефакта
e2e_Pets — End-to-End тесты портала учёта животных
Автоматизированное тестирование портала vet.goznak.ru
на базе Playwright + pytest.
Содержание
- Структура проекта
- Быстрый старт
- Запуск тестов
- Создание нового теста
- Добавление генератора данных (ФЛК)
- Добавление статического артефакта
Структура проекта
e2e_Pets/
├── .env # Учётные данные (не в git)
├── .env.example # Шаблон .env
├── pytest.ini # Конфигурация pytest
├── requirements.txt # Зависимости
│
└── tests/
├── conftest.py # Глобальные фикстуры (browser_page, bp_state)
├── testdata/
│ └── generators.py # Генераторы случайных данных по ФЛК
│
├── 01_vetdept/ # ЛК: Управление ветеринарии
│ ├── conftest.py # fixtures_dir, shared_state
│ ├── fixtures/ # Статические артефакты (фото, PDF)
│ └── BP01_navigation/ # Бизнес-процесс 01
│ └── test_bp01_navigation.py
│
└── 02_vetstation/ # ЛК: Ветеринарная станция
├── conftest.py
├── fixtures/
└── BP01_dashboard/ # Бизнес-процесс 01
└── test_bp01_dashboard.py
Иерархия тестов: Проект → ЛК (роль) → БП (BP01_...) → Шаги (test_s01_..., test_s02_...)
Быстрый старт
1. Клонировать репозиторий
git clone <url>
cd e2e_Pets
2. Создать виртуальное окружение и установить зависимости
python -m venv venv
.\venv\Scripts\pip.exe install -r requirements.txt
.\venv\Scripts\playwright.exe install chromium
3. Настроить учётные данные
Copy-Item .env.example .env
# Открыть .env и заполнить логины/пароли
Запуск тестов
Все команды выполняются из корня проекта (
e2e_Pets/). HTML-отчёт автоматически создаётся вhtml-report/report.html.
Запустить ВСЕ тесты
.\venv\Scripts\pytest.exe
Запустить тесты конкретного ЛК (роли)
# ЛК Управление ветеринарии
.\venv\Scripts\pytest.exe tests/01_vetdept/
# ЛК Ветеринарная станция
.\venv\Scripts\pytest.exe tests/02_vetstation/
Запустить конкретный бизнес-процесс
# BP01 навигации в ЛК Управление ветеринарии
.\venv\Scripts\pytest.exe tests/01_vetdept/BP01_navigation/
# BP01 дашборда в ЛК Ветеринарная станция
.\venv\Scripts\pytest.exe tests/02_vetstation/BP01_dashboard/
Запустить конкретный шаг
# Только шаг 3 из BP01 ветстанции
.\venv\Scripts\pytest.exe tests/02_vetstation/BP01_dashboard/ -k "s03"
# Только шаги 1 и 2
.\venv\Scripts\pytest.exe tests/02_vetstation/BP01_dashboard/ -k "s01 or s02"
Полезные флаги
| Флаг | Описание |
|---|---|
-v |
Подробный вывод с именами шагов |
--headed |
Показывать браузер (по умолчанию включён в pytest.ini) |
--headless |
Запустить без браузера (быстрее) |
--slowmo 500 |
Замедление действий на 500мс (для отладки) |
-k "BP01" |
Запустить только тесты содержащие "BP01" в имени |
--co -q |
Только показать список тестов без запуска |
# Показать список всех тестов (без запуска)
.\venv\Scripts\pytest.exe --co -q
# Запустить без браузера и без замедления
.\venv\Scripts\pytest.exe --headless --slowmo 0
# Запустить в headless-режиме только vetdept
.\venv\Scripts\pytest.exe tests/01_vetdept/ --headless --slowmo 0
Создание нового теста
Нужен новый бизнес-процесс?
Опиши его в свободной форме — например:
«Нужен тест для ветстанции: открыть список животных, применить фильтр по кошкам, убедиться что список отфильтровался, открыть карточку первого животного, проверить наличие кнопки редактирования»
ИИ-ассистент создаст файл в нужном месте, следуя архитектуре проекта.
Если хочешь создать вручную — шаблон:
1. Создать папку бизнес-процесса
# Для роли vetstation, новый бизнес-процесс BP02
mkdir tests\02_vetstation\BP02_animals
New-Item tests\02_vetstation\BP02_animals\__init__.py
2. Создать файл теста
Имя файла: test_bp02_<название>.py
import os
import pytest
from playwright.sync_api import Page, expect
BASE_URL = os.getenv("BASE_URL", "https://vet.goznak.ru")
@pytest.mark.vetstation # <- маркер роли
@pytest.mark.usefixtures("browser_page") # <- авторизация и браузер
class TestBP02Animals:
"""
BP02: Краткое описание бизнес-процесса
Проверяет что пользователь может:
- Шаг 1: ...
- Шаг 2: ...
"""
@pytest.mark.dependency(name="BP02::s01")
def test_s01_<название>(self, browser_page: Page, bp_state: dict):
"""Шаг 1: Описание шага — именно это появится в отчёте"""
# ... код теста ...
bp_state["key"] = "value" # передать данные следующему шагу
@pytest.mark.dependency(name="BP02::s02", depends=["BP02::s01"])
def test_s02_<название>(self, browser_page: Page, bp_state: dict):
"""Шаг 2: Описание шага"""
value = bp_state["key"] # получить данные от предыдущего шага
# ... код теста ...
3. Правила именования
| Элемент | Формат | Пример |
|---|---|---|
| Папка БП | BP<NN>_<описание> |
BP02_animals |
| Файл теста | test_bp<NN>_<описание>.py |
test_bp02_animals.py |
| Класс | TestBP<NN><Описание> |
TestBP02Animals |
| Метод (шаг) | test_s<NN>_<описание> |
test_s01_open_list |
| Зависимость | BP<NN>::s<NN> |
BP02::s01 |
4. Маркеры ролей
| Маркер | Роль |
|---|---|
@pytest.mark.vetdept |
Управление ветеринарии |
@pytest.mark.vetstation |
Ветеринарная станция |
@pytest.mark.prefecture |
Администрация (префектура) |
Добавление генератора данных (ФЛК)
Файл: tests/testdata/generators.py
Содержит пошаговое руководство по добавлению нового генератора прямо в начале файла. Коротко:
# Шаблон новой функции-генератора:
def gen_<сущность>_<поле>() -> str:
"""
Краткое описание.
ФЛК:
- Правило 1
- Правило 2
Пример вывода: 'AB1234'
"""
# ... реализация ...
Использование в тесте:
from tests.testdata.generators import gen_microchip, gen_animal_name
def test_s01_fill_form(self, browser_page, bp_state):
name = gen_animal_name()
chip = gen_microchip()
browser_page.fill("#name", name)
browser_page.fill("#chip", chip)
bp_state["name"] = name # передаём следующему шагу
Добавление статического артефакта
-
Положи файл в папку
fixtures/нужной роли:tests/01_vetdept/fixtures/images/cat_photo.jpg -
Раскомментируй шаблон фикстуры в
tests/<роль>/conftest.py:@pytest.fixture(scope="session") def cat_photo(fixtures_dir) -> Path: """Фото кошки для теста загрузки.""" return fixtures_dir / "images" / "cat_photo.jpg" -
Используй в тесте:
def test_s02_upload(self, browser_page, bp_state, cat_photo): browser_page.set_input_files("input[type=file]", str(cat_photo))