core/config_paths.py resolves a single override so tests and multiple instances can run against isolated temp config/db without touching user data.
75 lines
2.7 KiB
Python
75 lines
2.7 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""tests/_test_env.py —— 自动化测试的统一临时环境(P0-01 新增)
|
||
|
||
铁律(VERIFICATION.md §凭据与运行数据隔离):
|
||
1. 每个测试进程独立临时目录 + 最小临时配置;
|
||
2. 在 import 任何可能间接加载 MainWindow 的模块之前设置 HAOCODE_CONFIG_FILE;
|
||
3. 在 import MainWindow 之前把 core.db_manager._DEFAULT_DB 指向临时数据库;
|
||
4. 写入、迁移、附件和截图产物只落到临时目录。
|
||
|
||
用法(放在测试文件顶部、任何 UI import 之前):
|
||
|
||
from tests._test_env import isolate
|
||
isolate("bashpanel", config={"providers": {}, "mode_switch": True})
|
||
|
||
说明:
|
||
· 临时目录按 进程 pid 隔离,测试进程互不干扰;
|
||
· 默认临时配置为最小可启动结构(空 providers + 测试 provider);
|
||
· 本模块不 import 任何 PyQt 模块,可在无 GUI 环境中安全调用。
|
||
"""
|
||
import json
|
||
import os
|
||
import sys
|
||
import tempfile
|
||
|
||
_TESTS_DIR = os.path.dirname(os.path.abspath(__file__))
|
||
_ROOT = os.path.dirname(_TESTS_DIR)
|
||
if _ROOT not in sys.path:
|
||
sys.path.insert(0, _ROOT)
|
||
|
||
|
||
def default_config() -> dict:
|
||
"""最小可启动临时配置(不含任何真实凭据)。"""
|
||
return {
|
||
"providers": {
|
||
"testprov": {
|
||
"api_key": "test-key-not-real",
|
||
"base_url": "http://127.0.0.1:9/v1",
|
||
"models": ["test-model"],
|
||
"model_contexts": {"test-model": 100000},
|
||
}
|
||
},
|
||
"default_provider": "testprov",
|
||
"default_model": "test-model",
|
||
}
|
||
|
||
|
||
def isolate(tag: str = "t", config: dict | None = None) -> dict:
|
||
"""创建临时配置 + 临时数据库并完成重定向。必须在 import MainWindow 之前调用。
|
||
|
||
返回 {"base": 临时目录, "config": 临时配置路径, "db": 临时数据库路径}。
|
||
"""
|
||
base = os.path.join(tempfile.gettempdir(),
|
||
f"haocode_test_{tag}_{os.getpid()}")
|
||
os.makedirs(base, exist_ok=True)
|
||
|
||
cfg_path = os.path.join(base, "config.json")
|
||
with open(cfg_path, "w", encoding="utf-8") as f:
|
||
json.dump(config if config is not None else default_config(),
|
||
f, ensure_ascii=False, indent=2)
|
||
|
||
db_path = os.path.join(base, "chat_history.db")
|
||
for p in (db_path, db_path + "-wal", db_path + "-shm"):
|
||
if os.path.exists(p):
|
||
os.remove(p)
|
||
|
||
os.environ["HAOCODE_CONFIG_FILE"] = cfg_path
|
||
|
||
# P1-03:QtWebEngine 独立 profile 重定向到临时目录(源码运行才在 data/webengine/)
|
||
os.environ.setdefault("HAOCODE_WEBENGINE_PROFILE_DIR", os.path.join(base, "webengine_profile"))
|
||
|
||
import core.db_manager as _dbm
|
||
_dbm._DEFAULT_DB = db_path
|
||
|
||
return {"base": base, "config": cfg_path, "db": db_path}
|