refactor(tests): Simplify test setup and fix client fixture
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
13
.drone.yml
13
.drone.yml
@@ -19,17 +19,18 @@ steps:
|
|||||||
commands:
|
commands:
|
||||||
- echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin
|
- echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin
|
||||||
|
|
||||||
# --- ИЗМЕНЕНИЕ ЗДЕСЬ ---
|
|
||||||
- name: testing
|
- name: testing
|
||||||
image: python:3.11-slim
|
image: python:3.11-slim
|
||||||
# Передаем фейковые секреты напрямую в окружение этого шага
|
|
||||||
environment:
|
|
||||||
YANDEX_CLIENT_ID: "test_id_from_drone"
|
|
||||||
YANDEX_CLIENT_SECRET: "test_secret_from_drone"
|
|
||||||
commands:
|
commands:
|
||||||
# Команды создания .env.test больше не нужны
|
# 1. Создаем .env файл. pydantic-settings его найдет и использует.
|
||||||
|
- echo 'YANDEX_CLIENT_ID="test_id"' > .env
|
||||||
|
- echo 'YANDEX_CLIENT_SECRET="test_secret"' >> .env
|
||||||
|
|
||||||
|
# 2. Устанавливаем зависимости
|
||||||
- pip install poetry
|
- pip install poetry
|
||||||
- poetry install
|
- poetry install
|
||||||
|
|
||||||
|
# 3. Запускаем тесты
|
||||||
- poetry run pytest -v
|
- poetry run pytest -v
|
||||||
|
|
||||||
- name: deploy
|
- name: deploy
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import os
|
# app/core/config.py
|
||||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
class Settings(BaseSettings):
|
||||||
@@ -7,12 +7,7 @@ class Settings(BaseSettings):
|
|||||||
YANDEX_METRIKA_API_URL: str = "https://api-metrika.yandex.net"
|
YANDEX_METRIKA_API_URL: str = "https://api-metrika.yandex.net"
|
||||||
LOG_LEVEL: str = "INFO"
|
LOG_LEVEL: str = "INFO"
|
||||||
|
|
||||||
# ИЗМЕНЕНИЕ ЗДЕСЬ:
|
# Возвращаем простую и надежную конфигурацию
|
||||||
# Если запущена среда pytest, используем .env.test, иначе .env
|
|
||||||
if "PYTEST_CURRENT_TEST" in os.environ:
|
|
||||||
model_config = SettingsConfigDict(env_file=".env.test")
|
|
||||||
else:
|
|
||||||
model_config = SettingsConfigDict(env_file=".env")
|
model_config = SettingsConfigDict(env_file=".env")
|
||||||
|
|
||||||
|
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
@@ -2,20 +2,10 @@ import pytest
|
|||||||
from httpx import AsyncClient, ASGITransport
|
from httpx import AsyncClient, ASGITransport
|
||||||
from app.main import app
|
from app.main import app
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
# Убираем async def и yield. Это будет обычная, синхронная фикстура,
|
||||||
def anyio_backend():
|
# которая создает асинхронный клиент.
|
||||||
"""
|
|
||||||
Это фикстура, необходимая для pytest-asyncio, чтобы он работал
|
|
||||||
с httpx в асинхронном режиме. Просто стандартный шаблон.
|
|
||||||
"""
|
|
||||||
return "asyncio"
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
async def client() -> AsyncClient:
|
def client() -> AsyncClient:
|
||||||
"""
|
|
||||||
Главная фикстура. Создает тестовый клиент, который мы будем
|
|
||||||
использовать во всех наших тестах.
|
|
||||||
"""
|
|
||||||
transport = ASGITransport(app=app)
|
transport = ASGITransport(app=app)
|
||||||
async with AsyncClient(transport=transport, base_url="http://test") as async_client:
|
# Просто создаем и возвращаем клиент
|
||||||
yield async_client
|
return AsyncClient(transport=transport, base_url="http://test")
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_get_counters_unauthorized(client): # <-- Получаем client как аргумент
|
async def test_get_counters_unauthorized(client):
|
||||||
|
async with client:
|
||||||
response = await client.get("/api/v1/counters/")
|
response = await client.get("/api/v1/counters/")
|
||||||
|
|
||||||
assert response.status_code == 403
|
assert response.status_code == 403
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
# Тесты теперь не знают про 'app', они знают только про 'client'
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_health_check(client): # <-- Получаем client как аргумент
|
async def test_health_check(client): # <-- client - это теперь сам AsyncClient
|
||||||
|
async with client: # <-- Используем async with для управления контекстом
|
||||||
response = await client.get("/")
|
response = await client.get("/")
|
||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
|
|||||||
Reference in New Issue
Block a user