From 13578ba4c2dd3ee586a14b0b3a3f5b7d362c8c92 Mon Sep 17 00:00:00 2001 From: QihuAI Design Date: Sat, 18 Jul 2026 23:29:55 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=E5=90=8E=E7=AB=AF=20pytest=20=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=9F=BA=E5=BB=BA=20(Phase0)=20=E2=80=94=206=20?= =?UTF-8?q?=E7=94=A8=E4=BE=8B=E5=85=A8=E7=BB=BF=20+=20=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=E5=89=8D=E5=A4=87=E4=BB=BDSOP=E5=90=88=E8=A7=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/python/conftest.py | 12 ++++++++++++ backend/python/pytest.ini | 11 +++++++++++ backend/python/requirements-dev.txt | 4 ++++ backend/python/tests/__init__.py | 0 backend/python/tests/test_market.py | 20 ++++++++++++++++++++ backend/python/tests/test_smoke.py | 21 +++++++++++++++++++++ backend/python/tests/test_sms.py | 21 +++++++++++++++++++++ 7 files changed, 89 insertions(+) create mode 100644 backend/python/conftest.py create mode 100644 backend/python/pytest.ini create mode 100644 backend/python/requirements-dev.txt create mode 100644 backend/python/tests/__init__.py create mode 100644 backend/python/tests/test_market.py create mode 100644 backend/python/tests/test_smoke.py create mode 100644 backend/python/tests/test_sms.py diff --git a/backend/python/conftest.py b/backend/python/conftest.py new file mode 100644 index 0000000..3f5aaa1 --- /dev/null +++ b/backend/python/conftest.py @@ -0,0 +1,12 @@ +"""Pytest 根配置:保证测试运行时 backend 包根目录在 sys.path 中。 + +运行方式(容器内,使用项目 venv): + cd /app/backend/python + /app/backend/python/.venv/bin/python -m pytest +""" +import os +import sys + +ROOT = os.path.dirname(os.path.abspath(__file__)) +if ROOT not in sys.path: + sys.path.insert(0, ROOT) diff --git a/backend/python/pytest.ini b/backend/python/pytest.ini new file mode 100644 index 0000000..6cf9569 --- /dev/null +++ b/backend/python/pytest.ini @@ -0,0 +1,11 @@ +[pytest] +testpaths = tests +python_files = test_*.py +python_classes = Test* +python_functions = test_* +asyncio_mode = auto +asyncio_default_fixture_loop_scope = function +addopts = -q --strict-markers +filterwarnings = + ignore::DeprecationWarning + ignore::PendingDeprecationWarning diff --git a/backend/python/requirements-dev.txt b/backend/python/requirements-dev.txt new file mode 100644 index 0000000..40d21f4 --- /dev/null +++ b/backend/python/requirements-dev.txt @@ -0,0 +1,4 @@ +# Phase 0 测试基建 — 开发/测试依赖(不进入生产 requirements.txt) +pytest==8.3.4 +pytest-asyncio==0.24.0 +httpx==0.27.2 diff --git a/backend/python/tests/__init__.py b/backend/python/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/python/tests/test_market.py b/backend/python/tests/test_market.py new file mode 100644 index 0000000..ce6fa44 --- /dev/null +++ b/backend/python/tests/test_market.py @@ -0,0 +1,20 @@ +"""应用市场场景分类器回归(稳定模块,无外部依赖)。 + +仅校验分类法结构本身不被破坏;不调用 _classify_scene(其内部会请求 LLM)。 +分类法是前端筛选/徽章的数据源,结构回归会导致全站分类错乱。 +""" +from app.api.market import MARKET_SCENES + + +def test_market_scenes_is_14_flat(): + assert len(MARKET_SCENES) == 14 + + +def test_market_scenes_unique_ids_and_required_keys(): + ids = [s["id"] for s in MARKET_SCENES] + assert len(set(ids)) == 14 # 无重复 id + for s in MARKET_SCENES: + assert "id" in s + assert "label" in s + assert "desc" in s + assert isinstance(s["label"], str) and s["label"].strip() diff --git a/backend/python/tests/test_smoke.py b/backend/python/tests/test_smoke.py new file mode 100644 index 0000000..22a4b70 --- /dev/null +++ b/backend/python/tests/test_smoke.py @@ -0,0 +1,21 @@ +"""Phase 0 安全网 — 后端冒烟测试。 + +核心价值:证明整个后端(含 chat.py 等巨型模块)在测试环境下能无错误导入并挂载路由。 +任何破坏 import 的脆弱补丁都会在此立刻变红,从而把"改了没生效 / 启动即崩"挡在部署前。 +""" + + +def test_app_imports_and_has_routes(): + from main import app + + assert app is not None + # 真实路由数远超 0;若 chat.py 等模块 import 失败,本测试在 import 阶段即报错 + assert len(app.routes) > 50 + + +def test_openapi_schema_builds(): + from main import app + + schema = app.openapi() + assert "paths" in schema + assert len(schema["paths"]) > 0 diff --git a/backend/python/tests/test_sms.py b/backend/python/tests/test_sms.py new file mode 100644 index 0000000..99112f7 --- /dev/null +++ b/backend/python/tests/test_sms.py @@ -0,0 +1,21 @@ +"""短信宝脚手架回归(稳定模块,纯函数)。 + +验证登录密码 MD5 算法与短信宝约定一致(32 位小写十六进制)。 +这是短信验证码功能(注册/改密/充值)能连通短信宝的前提。 +""" +import hashlib + +from app.sms_client import smsbao_md5 + + +def test_smsbao_md5_matches_hashlib(): + samples = ["XHR521yhf", "abc123", "密码测试", ""] + for pw in samples: + assert smsbao_md5(pw) == hashlib.md5(pw.encode("utf-8")).hexdigest() + + +def test_smsbao_md5_is_32_lower_hex(): + out = smsbao_md5("XHR521yhf") + assert len(out) == 32 + assert out == out.lower() + assert all(c in "0123456789abcdef" for c in out)