from pathlib import Path import subprocess import sys import time import pytest import requests # Make `site/` importable as top-level modules: app, routes, db, operations, ... SITE_DIR = Path(__file__).resolve().parents[1] / "site" if str(SITE_DIR) not in sys.path: sys.path.insert(0, str(SITE_DIR)) # Путь к polygon: соседняя репа в корне autotest POLYGON_DIR = Path(__file__).resolve().parents[2] / "polygon" / "site" POLYGON_URL = "http://localhost:5000" @pytest.fixture def app_client(): """Flask test client для app-autotest.""" from app import app app.config.update(TESTING=True) with app.test_client() as client: yield client @pytest.fixture(scope="session") def polygon_server(): """Запустить polygon как subprocess на весь pytest-session. Используется для интеграционных тестов app-autotest ↔ polygon. После всех тестов процесс убивается. """ if not POLYGON_DIR.is_dir(): pytest.skip("polygon repo not found") proc = subprocess.Popen( ["python3", "app.py"], cwd=str(POLYGON_DIR), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) # Ждём готовности (poll /health, timeout 10s) deadline = time.time() + 10 while time.time() < deadline: try: r = requests.get(f"{POLYGON_URL}/health", timeout=2) if r.status_code == 200: break except requests.ConnectionError: time.sleep(0.5) else: proc.terminate() proc.wait() pytest.fail("polygon did not start within 10s") yield POLYGON_URL proc.terminate() proc.wait() @pytest.fixture(autouse=True) def reset_polygon(polygon_server): """Перед каждым интеграционным тестом — сброс состояния polygon.""" requests.post(f"{polygon_server}/api/v1/svc/_mock/reset", timeout=5)