mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-06-04 07:26:46 +00:00
@@ -43,7 +43,7 @@ Before executing any task, identify the domain and load the corresponding docume
|
||||
|
||||
### Testing
|
||||
* **Primary Reference:** `docs/testing.md`
|
||||
* **Required Constraints:** pytest is the only runner; `tests/conftest.py` isolates each run to a temporary `CONFIG_DIR`. Tests must not touch the real database, network, or external services (TMDB, LLM catalogs, downloaders, media servers, MP server) — mock at the boundary or replay recorded responses; the bar is zero real outbound traffic. Tests must restore any process-level state they stub (`sys.modules`, singletons, caches, settings). New tests must be pytest-native (function + `assert` + fixtures); do not add new `unittest.TestCase`. Convert existing `TestCase` files to pytest-native opportunistically when you modify them.
|
||||
* **Required Constraints:** pytest is the only runner; `tests/conftest.py` isolates each run to a temporary `CONFIG_DIR`. Tests must not touch the real database, network, or external services (TMDB, LLM catalogs, downloaders, media servers, MP server) — mock at the boundary or replay recorded responses; the bar is zero real outbound traffic. Tests must restore any process-level state they stub (`sys.modules`, singletons, caches, settings). New tests must be pytest-native (function + `assert` + fixtures); do not add new `unittest.TestCase`. Convert existing `TestCase` files to pytest-native opportunistically when you modify them. Before opening a PR to `v2`, run the full suite locally (`python tests/run.py`) and confirm it is green with zero real network calls; the `.github/workflows/test.yml` gate runs the same suite on every PR/push to `v2`.
|
||||
|
||||
### Commands and Development Workflow
|
||||
* **Primary Reference:** `docs/rules/03-commands.md`
|
||||
|
||||
@@ -129,6 +129,8 @@ def test_recognize_prefers_explicit_id(sample_meta, monkeypatch):
|
||||
- **测试间污染(测不准)**:定位被改而未还原的进程级状态(单例 / `lru_cache` / `sys.modules` / 环境变量 / `settings`),按「自隔离」补还原。
|
||||
- **怀疑用例空过**:用变异验证——临时打断对应生产逻辑(让它返回错误值),跑该用例应**失败**;若仍通过,说明断言没真正覆盖该逻辑。
|
||||
|
||||
## CI
|
||||
## CI 与 PR
|
||||
|
||||
CI 以 pytest 运行 `tests`。建议 CI 与本地复现都用仅安装 `requirements.in` 的干净环境,保证可选扩展、动态模块的存在性与 CI 一致。
|
||||
- **门禁**:`.github/workflows/test.yml` 在指向 `v2` 的 `pull_request` / `push` 及手动触发时,用 `python tests/run.py` 跑全量单测。
|
||||
- **PR**:`python tests/run.py` 确认全绿、且 socket 探针零真实出站,避免把红的改动推上去空耗门禁。
|
||||
- 复现 CI 用仅安装 `requirements.in` 的干净环境(含 pytest 与可选扩展),保证可选扩展、动态模块的存在性与 CI 一致。
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -75,13 +75,17 @@ def setUpModule():
|
||||
patch.object(MoviePilotServerHelper, "report_recognize_share", new=MagicMock(return_value=None)),
|
||||
patch.object(MoviePilotServerHelper, "query_recognize_share", new=MagicMock(return_value=None)),
|
||||
])
|
||||
started = []
|
||||
try:
|
||||
for patcher in _PATCHERS:
|
||||
patcher.start()
|
||||
started.append(patcher)
|
||||
except Exception:
|
||||
# 任一 patcher.start() 失败(如重构致类/方法改名)时回滚已启动的桩并清空,
|
||||
# 避免半启动状态泄漏到其它测试模块。
|
||||
tearDownModule()
|
||||
# 仅回滚已成功启动的桩:对未启动的 patcher 调用 stop() 会抛 RuntimeError,
|
||||
# 既掩盖原始启动异常又中断清理;记录 started 可精确回滚、避免半启动状态泄漏。
|
||||
for patcher in started:
|
||||
patcher.stop()
|
||||
_PATCHERS.clear()
|
||||
raise
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user