# -*- coding: utf-8 -*- """Общие фикстуры и помощники для автотестов курса. Запуск из корня курса: python -m pytest tests/ -k lab01 -v """ import importlib.util import math import os import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT)) def load_solution(lab_dir: str): """Импортирует solution.py из папки лабораторной как отдельный модуль.""" path = ROOT / lab_dir / "solution.py" if not path.exists(): raise FileNotFoundError(f"не найден {path}") spec = importlib.util.spec_from_file_location(f"solution_{lab_dir}", path) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) return mod def close(a, b, rel=1e-6, abs_tol=1e-6): """Сравнение с допуском: для float-результатов (π, интеграл, checksum). Принимает как значения, так и кортежи (value, seconds), которые возвращают функции-заготовки студентов. """ if isinstance(a, tuple): a = a[0] if isinstance(b, tuple): b = b[0] if isinstance(a, int) and isinstance(b, int): return a == b return math.isclose(float(a), float(b), rel_tol=rel, abs_tol=abs_tol) def source_of(lab_dir: str) -> str: """Исходный код solution.py — для проверки использованных механизмов.""" return (ROOT / lab_dir / "solution.py").read_text(encoding="utf-8")