🏠 Домашнее задание: Summary session 6
Примечание. Урок 12 — это summary-урок (повторение). Отдельного LMS-задания для него нет. Вместо этого здесь: разбор ДЗ из лекции (POM Checkout), самопроверка знаний, настройка окружения и проверка в VS Code.
⚡ ДЗ из лекции: checkout через POM
Открыть saucedemo.com → авторизоваться → добавить 3 товара (Backpack, Bolt T-Shirt, Onesie) → корзина → Checkout → заполнить форму → проверить Total = $58.29.
Использовать POM: LoginPage, InventoryPage, CartPage, CheckoutPage.
ДЗ из лекции: Checkout через POM
Задание из лекции Summary session 6. Написать автоматизированный тест с использованием POM, который выполняет:
- Открыть сайт: https://www.saucedemo.com/
- Авторизоваться как
standard_user - Добавить в корзину: Sauce Labs Backpack, Sauce Labs Bolt T-Shirt, Sauce Labs Onesie
- Перейти в корзину
- Нажать Checkout
- Заполнить форму: имя, фамилия, почтовый индекс
- Прочитать итоговую стоимость (Total)
- Проверить, что итоговая сумма равна $58.29
Подготовка окружения
# PowerShell — создание и активация venv
python -m venv venv
.\venv\Scripts\Activate.ps1
# Установка зависимостей
pip install selenium webdriver-manager pytest
# Структура проекта для ДЗ
saucedemo_checkout/
├── pages/
│ ├── __init__.py
│ ├── base_page.py
│ ├── login_page.py
│ ├── inventory_page.py
│ ├── cart_page.py
│ └── checkout_page.py
└── tests/
├── __init__.py
├── base_test.py
└── test_checkout.py
Пошаговое решение
Шаг 1: BasePage
# pages/base_page.py
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class BasePage:
def __init__(self, driver):
self.driver = driver
self.wait = WebDriverWait(driver, 10)
def find(self, locator):
return self.wait.until(EC.presence_of_element_located(locator))
def click(self, locator):
self.wait.until(EC.element_to_be_clickable(locator)).click()
def type_text(self, locator, text):
field = self.find(locator)
field.clear()
field.send_keys(text)
def get_text(self, locator):
return self.find(locator).text
def find_all(self, locator):
return self.wait.until(EC.presence_of_all_elements_located(locator))
Шаг 2: CheckoutPage
# pages/checkout_page.py
from selenium.webdriver.common.by import By
from pages.base_page import BasePage
class CheckoutPage(BasePage):
FIRST_NAME = (By.ID, "first-name")
LAST_NAME = (By.ID, "last-name")
POSTAL_CODE = (By.ID, "postal-code")
CONTINUE_BTN = (By.ID, "continue")
TOTAL_LABEL = (By.CLASS_NAME, "summary_total_label")
def fill_checkout_form(self, first_name, last_name, postal_code):
self.type_text(self.FIRST_NAME, first_name)
self.type_text(self.LAST_NAME, last_name)
self.type_text(self.POSTAL_CODE, postal_code)
self.click(self.CONTINUE_BTN)
def get_total_price(self):
return self.get_text(self.TOTAL_LABEL)
Шаг 3: BaseTest с CheckoutPage
# tests/base_test.py
import pytest
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from pages.login_page import LoginPage
from pages.inventory_page import InventoryPage
from pages.cart_page import CartPage
from pages.checkout_page import CheckoutPage
class BaseTest:
@pytest.fixture(scope="class", autouse=True)
def setup(self):
self.driver = webdriver.Chrome(
service=ChromeService(ChromeDriverManager().install())
)
self.driver.maximize_window()
self.driver.get("https://www.saucedemo.com/")
self.login_page = LoginPage(self.driver)
self.inventory_page = InventoryPage(self.driver)
self.cart_page = CartPage(self.driver)
self.checkout_page = CheckoutPage(self.driver)
yield
self.driver.quit()
Шаг 4: Тест checkout
# tests/test_checkout.py
from tests.base_test import BaseTest
class TestCheckout(BaseTest):
def test_checkout_total_price(self):
# 1. Открытие и авторизация
self.login_page.open()
self.login_page.success_login("standard_user", "secret_sauce")
# 2. Добавление товаров в корзину
self.inventory_page.add_item_to_cart("Sauce Labs Backpack")
self.inventory_page.add_item_to_cart("Sauce Labs Bolt T-Shirt")
self.inventory_page.add_item_to_cart("Sauce Labs Onesie")
# 3. Переход в корзину
self.inventory_page.go_to_cart()
# 4. Оформление заказа
self.cart_page.proceed_to_checkout()
self.checkout_page.fill_checkout_form("John", "Doe", "12345")
# 5. Проверка итоговой стоимости
total_price = self.checkout_page.get_total_price()
assert total_price == "Total: $58.29", f"Итоговая сумма неверна: {total_price}"
Примечание: Метод
get_total_price() возвращает полный текст элемента .summary_total_label. Это может быть "Total: $58.29", поэтому лучше проверять через assert "$58.29" in total_price, если текст элемента содержит префикс.
Запуск и проверка в VS Code
Запуск из терминала (PowerShell)
# Запуск теста
pytest tests/test_checkout.py -v
# Ожидаемый вывод:
# PASSED tests/test_checkout.py::TestCheckout::test_checkout_total_price
Запуск с отладкой (F5 в VS Code)
Создайте файл .vscode/launch.json:
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "pytest: checkout",
"type": "debugpy",
"request": "launch",
"module": "pytest",
"args": ["tests/test_checkout.py", "-v"],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal"
}
]
}
- Откройте
tests/test_checkout.py - Поставьте точку останова на строке
assert total_price == ... - Нажмите F5 — запустится отладка
- В панели Variables проверьте значение
total_price
Самопроверка
После успешного выполнения вы должны понимать:
- Почему POM лучше, чем тесты с «голыми» локаторами
- Как структурировать проект:
pages/,tests/,conftest.py - Зачем нужен
BasePageи как от него наследоваться - Как работает
BaseTestсscope="class"иautouse=True - Почему важен
__init__.pyв каждой директории-пакете