test: simplify E2E tests - login per test (pytest-asyncio compatibility)
This commit is contained in:
parent
204f9f26de
commit
adcb22dc75
@ -4,21 +4,15 @@ E2E тесты для Kwork API.
|
|||||||
Требуют реальных credentials и запускаются только локально.
|
Требуют реальных credentials и запускаются только локально.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
from kwork_api import KworkClient
|
|
||||||
|
|
||||||
# Загружаем .env
|
# Загружаем .env
|
||||||
load_dotenv(Path(__file__).parent / ".env")
|
load_dotenv(Path(__file__).parent / ".env")
|
||||||
|
|
||||||
# Отключаем auto mode для pytest-asyncio чтобы использовать один event loop
|
|
||||||
pytest_plugins = ('pytest_asyncio',)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def kwork_credentials():
|
def kwork_credentials():
|
||||||
@ -40,40 +34,6 @@ def require_credentials(kwork_credentials):
|
|||||||
return kwork_credentials
|
return kwork_credentials
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
|
||||||
def client(require_credentials):
|
|
||||||
"""
|
|
||||||
E2E клиент для всех тестов в модуле.
|
|
||||||
|
|
||||||
Авторизуется один раз и переиспользуется во всех тестах модуля.
|
|
||||||
"""
|
|
||||||
async def create_client():
|
|
||||||
return await KworkClient.login(
|
|
||||||
username=require_credentials["username"],
|
|
||||||
password=require_credentials["password"],
|
|
||||||
)
|
|
||||||
|
|
||||||
client = asyncio.run(create_client())
|
|
||||||
yield client
|
|
||||||
asyncio.run(client.close())
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
|
||||||
def catalog_kwork_id(client):
|
|
||||||
"""
|
|
||||||
Получить ID первого кворка из каталога для тестов.
|
|
||||||
|
|
||||||
Переиспользуется во всех тестах модуля.
|
|
||||||
"""
|
|
||||||
async def get_first_kwork():
|
|
||||||
catalog = await client.catalog.get_list(page=1)
|
|
||||||
if len(catalog.kworks) > 0:
|
|
||||||
return catalog.kworks[0].id
|
|
||||||
return None
|
|
||||||
|
|
||||||
return asyncio.run(get_first_kwork())
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function")
|
||||||
def slowmo(request):
|
def slowmo(request):
|
||||||
"""Задержка между тестами для rate limiting."""
|
"""Задержка между тестами для rate limiting."""
|
||||||
|
|||||||
@ -11,73 +11,110 @@ from kwork_api import KworkClient
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.e2e
|
@pytest.mark.e2e
|
||||||
async def test_get_catalog_list(client):
|
async def test_get_catalog_list(require_credentials):
|
||||||
"""E2E: Получить список кворков из каталога.
|
"""E2E: Получить список кворков из каталога.
|
||||||
|
|
||||||
HAR: POST https://api.kwork.ru/catalogMainv2
|
HAR: POST https://api.kwork.ru/catalogMainv2
|
||||||
"""
|
"""
|
||||||
# Первая страница каталога
|
client = await KworkClient.login(
|
||||||
catalog = await client.catalog.get_list(page=1)
|
username=require_credentials["username"],
|
||||||
|
password=require_credentials["password"],
|
||||||
assert catalog is not None
|
)
|
||||||
# API может вернуть пустой список (это нормально)
|
|
||||||
if len(catalog.kworks) > 0:
|
try:
|
||||||
# Проверка структуры первого кворка
|
# Первая страница каталога
|
||||||
first_kwork = catalog.kworks[0]
|
catalog = await client.catalog.get_list(page=1)
|
||||||
assert first_kwork.id is not None
|
|
||||||
assert first_kwork.title is not None
|
assert catalog is not None
|
||||||
assert first_kwork.price is not None
|
# API может вернуть пустой список (это нормально)
|
||||||
|
if len(catalog.kworks) > 0:
|
||||||
|
# Проверка структуры первого кворка
|
||||||
|
first_kwork = catalog.kworks[0]
|
||||||
|
assert first_kwork.id is not None
|
||||||
|
assert first_kwork.title is not None
|
||||||
|
assert first_kwork.price is not None
|
||||||
|
finally:
|
||||||
|
await client.close()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.e2e
|
@pytest.mark.e2e
|
||||||
async def test_get_kwork_details(client, catalog_kwork_id):
|
async def test_get_kwork_details(require_credentials):
|
||||||
"""E2E: Получить детали кворка.
|
"""E2E: Получить детали кворка.
|
||||||
|
|
||||||
HAR: POST https://api.kwork.ru/getKworkDetails
|
HAR: POST https://api.kwork.ru/getKworkDetails
|
||||||
"""
|
"""
|
||||||
# Пропускаем если каталог пустой
|
client = await KworkClient.login(
|
||||||
if catalog_kwork_id is None:
|
username=require_credentials["username"],
|
||||||
pytest.skip("Catalog is empty")
|
password=require_credentials["password"],
|
||||||
|
)
|
||||||
# Получаем детали
|
|
||||||
details = await client.catalog.get_details(catalog_kwork_id)
|
try:
|
||||||
|
# Сначала получаем каталог чтобы найти реальный ID
|
||||||
assert details is not None
|
catalog = await client.catalog.get_list(page=1)
|
||||||
assert details.id == catalog_kwork_id
|
|
||||||
assert details.title is not None
|
# Если каталог пустой - пропускаем тест
|
||||||
assert details.price is not None
|
if len(catalog.kworks) == 0:
|
||||||
|
pytest.skip("Catalog is empty")
|
||||||
|
|
||||||
|
kwork_id = catalog.kworks[0].id
|
||||||
|
|
||||||
|
# Получаем детали
|
||||||
|
details = await client.catalog.get_details(kwork_id)
|
||||||
|
|
||||||
|
assert details is not None
|
||||||
|
assert details.id == kwork_id
|
||||||
|
assert details.title is not None
|
||||||
|
assert details.price is not None
|
||||||
|
finally:
|
||||||
|
await client.close()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.e2e
|
@pytest.mark.e2e
|
||||||
async def test_get_projects_list(client):
|
async def test_get_projects_list(require_credentials):
|
||||||
"""E2E: Получить список проектов с биржи.
|
"""E2E: Получить список проектов с биржи.
|
||||||
|
|
||||||
HAR: POST https://api.kwork.ru/projects
|
HAR: POST https://api.kwork.ru/projects
|
||||||
"""
|
"""
|
||||||
projects = await client.projects.get_list(page=1)
|
client = await KworkClient.login(
|
||||||
|
username=require_credentials["username"],
|
||||||
assert projects is not None
|
password=require_credentials["password"],
|
||||||
# Проекты могут быть пустыми
|
)
|
||||||
if len(projects.projects) > 0:
|
|
||||||
first_project = projects.projects[0]
|
try:
|
||||||
assert first_project.id is not None
|
projects = await client.projects.get_list(page=1)
|
||||||
assert first_project.title is not None
|
|
||||||
|
assert projects is not None
|
||||||
|
# Проекты могут быть пустыми
|
||||||
|
if len(projects.projects) > 0:
|
||||||
|
first_project = projects.projects[0]
|
||||||
|
assert first_project.id is not None
|
||||||
|
assert first_project.title is not None
|
||||||
|
finally:
|
||||||
|
await client.close()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.e2e
|
@pytest.mark.e2e
|
||||||
async def test_get_user_info(client):
|
async def test_get_user_info(require_credentials):
|
||||||
"""E2E: Получить информацию о текущем пользователе.
|
"""E2E: Получить информацию о текущем пользователе.
|
||||||
|
|
||||||
HAR: POST https://api.kwork.ru/user
|
HAR: POST https://api.kwork.ru/user
|
||||||
"""
|
"""
|
||||||
user = await client.user.get_info()
|
client = await KworkClient.login(
|
||||||
assert user is not None
|
username=require_credentials["username"],
|
||||||
# API возвращает dict с данными пользователя
|
password=require_credentials["password"],
|
||||||
assert isinstance(user, dict)
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
user = await client.user.get_info()
|
||||||
|
assert user is not None
|
||||||
|
# API возвращает dict с данными пользователя
|
||||||
|
assert isinstance(user, dict)
|
||||||
|
finally:
|
||||||
|
await client.close()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.e2e
|
@pytest.mark.e2e
|
||||||
async def test_get_reference_data(client):
|
async def test_get_reference_data(require_credentials):
|
||||||
"""E2E: Получить справочные данные (города, страны, фичи).
|
"""E2E: Получить справочные данные (города, страны, фичи).
|
||||||
|
|
||||||
HAR endpoints:
|
HAR endpoints:
|
||||||
@ -86,47 +123,71 @@ async def test_get_reference_data(client):
|
|||||||
- POST https://api.kwork.ru/getAvailableFeatures
|
- POST https://api.kwork.ru/getAvailableFeatures
|
||||||
- POST https://api.kwork.ru/getBadgesInfo
|
- POST https://api.kwork.ru/getBadgesInfo
|
||||||
"""
|
"""
|
||||||
# Города (может вернуть пустой список)
|
client = await KworkClient.login(
|
||||||
cities = await client.reference.get_cities()
|
username=require_credentials["username"],
|
||||||
assert isinstance(cities, list)
|
password=require_credentials["password"],
|
||||||
|
)
|
||||||
# Страны (может вернуть пустой список)
|
|
||||||
countries = await client.reference.get_countries()
|
try:
|
||||||
assert isinstance(countries, list)
|
# Города (может вернуть пустой список)
|
||||||
|
cities = await client.reference.get_cities()
|
||||||
# Фичи
|
assert isinstance(cities, list)
|
||||||
features = await client.reference.get_features()
|
|
||||||
assert isinstance(features, list)
|
# Страны (может вернуть пустой список)
|
||||||
|
countries = await client.reference.get_countries()
|
||||||
# Бейджи
|
assert isinstance(countries, list)
|
||||||
badges = await client.reference.get_badges_info()
|
|
||||||
assert isinstance(badges, list)
|
# Фичи
|
||||||
|
features = await client.reference.get_features()
|
||||||
|
assert isinstance(features, list)
|
||||||
|
|
||||||
|
# Бейджи
|
||||||
|
badges = await client.reference.get_badges_info()
|
||||||
|
assert isinstance(badges, list)
|
||||||
|
finally:
|
||||||
|
await client.close()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.e2e
|
@pytest.mark.e2e
|
||||||
async def test_get_notifications(client):
|
async def test_get_notifications(require_credentials):
|
||||||
"""E2E: Получить уведомления.
|
"""E2E: Получить уведомления.
|
||||||
|
|
||||||
HAR: POST https://api.kwork.ru/notifications
|
HAR: POST https://api.kwork.ru/notifications
|
||||||
"""
|
"""
|
||||||
notifications = await client.notifications.get_list()
|
client = await KworkClient.login(
|
||||||
assert notifications is not None
|
username=require_credentials["username"],
|
||||||
# Уведомления могут быть пустыми
|
password=require_credentials["password"],
|
||||||
assert hasattr(notifications, 'notifications')
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
notifications = await client.notifications.get_list()
|
||||||
|
assert notifications is not None
|
||||||
|
# Уведомления могут быть пустыми
|
||||||
|
assert hasattr(notifications, 'notifications')
|
||||||
|
finally:
|
||||||
|
await client.close()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.e2e
|
@pytest.mark.e2e
|
||||||
async def test_get_user_orders(client):
|
async def test_get_user_orders(require_credentials):
|
||||||
"""E2E: Получить заказы пользователя.
|
"""E2E: Получить заказы пользователя.
|
||||||
|
|
||||||
HAR endpoints:
|
HAR endpoints:
|
||||||
- POST https://api.kwork.ru/payerOrders
|
- POST https://api.kwork.ru/payerOrders
|
||||||
- POST https://api.kwork.ru/workerOrders
|
- POST https://api.kwork.ru/workerOrders
|
||||||
"""
|
"""
|
||||||
# Заказы как заказчик
|
client = await KworkClient.login(
|
||||||
payer_orders = await client.projects.get_payer_orders()
|
username=require_credentials["username"],
|
||||||
assert isinstance(payer_orders, list)
|
password=require_credentials["password"],
|
||||||
|
)
|
||||||
# Заказы как исполнитель
|
|
||||||
worker_orders = await client.projects.get_worker_orders()
|
try:
|
||||||
assert isinstance(worker_orders, list)
|
# Заказы как заказчик
|
||||||
|
payer_orders = await client.projects.get_payer_orders()
|
||||||
|
assert isinstance(payer_orders, list)
|
||||||
|
|
||||||
|
# Заказы как исполнитель
|
||||||
|
worker_orders = await client.projects.get_worker_orders()
|
||||||
|
assert isinstance(worker_orders, list)
|
||||||
|
finally:
|
||||||
|
await client.close()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user