fix(tests): tmp_path 落点改到仓库内,消除 33 个与缺陷无关的 setup 失败

问题:本机 `%TEMP%\pytest-of-Windows` 被权限更高的会话建过,当前用户无权写入,
于是所有用 `tmp_path` 的用例在 setup 阶段批量 ERROR(WinError 5)——实测 33 个,
散布在 offsite 附件预览、通知发送、promotion、worker 等处。这类噪声会让
"到底哪里坏了"完全看不出来(同事这批新用例首次把它暴露出来)。

修法:在 tests/conftest.py 覆盖 `tmp_path`,把根目录改到仓库内 `.workdir/pytest-tmp`
(已在 .gitignore)。语义不变——每个用例仍拿到一个**新建的空目录**(残留目录会污染断言)。
只覆盖 `tmp_path` 而不动 `tmp_path_factory`:后者是 pytest 私有构造,参数随版本变化
(实测直接实例化 `TempPathFactory(...)` 会 TypeError),而本仓库用例只用 `tmp_path`。

同时把 pyproject.toml 里那条 `basetemp = ...` 删掉:pytest **只在命令行认 basetemp**,
写在 ini 里会被静默忽略(实测无效),留着会让人误以为已配好。改为注释指向 conftest。

效果:不带任何参数 `pytest -q` 从「3 failed + 33 errors」变为「3 failed,0 error」。
This commit is contained in:
qyqy
2026-09-11 19:13:43 +08:00
committed by wangjianlong_0626
parent 636dcbbe7e
commit 8cff6b35f9
2 changed files with 36 additions and 8 deletions
+33 -1
View File
@@ -15,6 +15,9 @@ NullPool 让每次取用都新建连接、归还即关闭,从根上消除跨
import asyncio
import sys
from typing import TYPE_CHECKING
import pytest
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
from sqlalchemy.pool import NullPool
@@ -31,7 +34,36 @@ _db.SessionFactory = async_sessionmaker( # type: ignore[assignment]
_db.engine, class_=AsyncSession, expire_on_commit=False
)
import pytest # noqa: E402
@pytest.fixture
def tmp_path() -> "Path":
"""把 `tmp_path` 的根目录改到**仓库内**(`.workdir/pytest-tmp`)。
为什么必须覆盖:pytest 默认在系统临时目录建 `%TEMP%\\pytest-of-<user>`。Windows 上
那个目录一旦被**权限更高的会话**(例如以管理员身份跑过一次测试)建过,当前用户就
无权再写入,于是**所有**用 `tmp_path` 的用例在 setup 阶段批量失败
(实测 33 个用例 ERROR、报 `PermissionError: [WinError 5]`),而它们与真实缺陷无关——
这种噪声会让"到底哪里坏了"完全看不出来。
覆盖后临时目录落在仓库内:不依赖系统临时目录权限,随 `.workdir/` 一起被 .gitignore
忽略,清理范围可见。语义不变——每个用例拿到一个**新建的空目录**(残留目录会让上一条
用例的产物污染断言)。
为什么只覆盖 `tmp_path` 而不动 `tmp_path_factory`:后者是 pytest 的私有构造
(`TempPathFactory.__init__` 的参数随版本变化,实测直接实例化会 `TypeError`),
而本仓库的用例只用 `tmp_path`。改动面越小,越不容易在下一次升级时炸。
"""
import shutil
from pathlib import Path
root = Path(".workdir") / "pytest-tmp"
root.mkdir(parents=True, exist_ok=True)
# 用目录数量推序号:不依赖 pytest 内部状态,重跑时自动接着编号。
index = len([item for item in root.iterdir() if item.is_dir()]) + 1
path = root / f"test{index}"
shutil.rmtree(path, ignore_errors=True)
path.mkdir(parents=True)
return path
from app.core.contracts import AgentDefinition, CoreResult, ResolvedAgentConfig # noqa: E402
from app.service.agent.base import BaseAgent # noqa: E402