From 4aad65aad9dddb0d4c93ccc7049efe37e45f4b62 Mon Sep 17 00:00:00 2001 From: claude_dev Date: Sat, 22 Aug 2026 20:54:32 +0800 Subject: [PATCH] =?UTF-8?q?test(ci):=20=E6=96=B9=E6=B3=95=E9=9D=A2?= =?UTF-8?q?=E9=92=89=E6=AD=BB=E6=B5=8B=E8=AF=95=E5=A4=8D=E5=88=B6=E8=BF=9B?= =?UTF-8?q?CI=E6=89=A7=E8=A1=8C=E8=8C=83=E5=9B=B4=E2=80=94=E2=80=94issue#3?= =?UTF-8?q?5=E6=96=B9=E6=A1=88A,ff05207=E3=80=8C=E7=BC=BA=E4=BB=BB?= =?UTF-8?q?=E4=B8=80CI=E7=BA=A2=E3=80=8D=E4=BB=8E=E8=99=9A=E6=A0=87?= =?UTF-8?q?=E5=8F=98=E6=88=90=E7=AB=8B=20[nas]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 钉死测试(test_method_surface_no_gap_left)原在tests/portfolio/test_provider.py, 而ci-cd.yml pytest只跑tests/data_platform→CI从不执行=钉死虚标(issue#35)。 本commit把该测试逐字复制到tests/data_platform/test_provider_method_parity.py (复制契约:两处同步改),CI 零改动零新依赖,其他测试零影响: - 牙齿自检:bullet_trade不可用直接FAIL非skip(skip=环境劣化时钉死无声失效, 重蹈#35;单测失败不中断同批其他测试) - RED实证:给unified源码临时加假公共方法zz_fake_parity_gap→ AssertionError「回测有实盘无:['zz_fake_parity_gap']」→还原复绿 - venv310按CI原样跑全套tests/data_platform:178绿(原177+新增1) 方案B(CI扩跑整个tests/portfolio,需先清13个Mac环境性失败)仍为可选增强,不阻塞 --- .../test_provider_method_parity.py | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 tests/data_platform/test_provider_method_parity.py diff --git a/tests/data_platform/test_provider_method_parity.py b/tests/data_platform/test_provider_method_parity.py new file mode 100644 index 0000000..44e7044 --- /dev/null +++ b/tests/data_platform/test_provider_method_parity.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +"""provider 方法面钉死测试(CI 版,issue #35 方案 A)。 + +背景:2026-08-21 实盘选股挂死+涨跌停过滤失效,根因都是「回测 provider +(LocalUnifiedProvider)有、实盘 provider(SanguoMiniQmtProvider)无」的方法缺口 +(累计 5 个洞)。ff05207 在 tests/portfolio/test_provider.py 加了钉死测试,但 +CI 的 pytest 只跑 tests/data_platform → 钉死虚标(issue #35)。本文件把钉死 +**原样复制**进 CI 执行范围,不改 CI workflow、不动其他测试。 + +牙齿自检:bullet_trade 不可用直接 FAIL(而非 skip)——skip 会让钉死在环境 +劣化时无声失效,重蹈 issue #35;单测失败不会中断同批其他测试(pytest 仅 +collection error 才中断),不影响 CI 其他功能。 +""" +import os + +# 必须早于 bullet_trade import:0.9.2 默认 provider=jqdata 会拖 jqdatasdk +os.environ.setdefault("DEFAULT_DATA_PROVIDER", "miniqmt") + +import pathlib +import re + + +def test_method_surface_no_gap_left(): + """unified 全部公共方法在实盘 provider(+MiniQMTProvider base)都有。 + + 与 tests/portfolio/test_provider.py::test_method_surface_no_gap_left + 逐字等价(复制契约:两处必须同步改)。 + """ + try: + from sanguo_portfolio import SanguoMiniQmtProvider + from bullet_trade.data.providers.miniqmt import MiniQMTProvider + except ImportError as exc: + import pytest + pytest.fail( + f"方法面钉死测试无法执行(缺依赖 {exc})——CI venv310 必须装 " + f"bullet_trade,否则钉死虚标(issue #35 重演)") + + base_dir = pathlib.Path(__file__).resolve().parents[2] + uni_src = (base_dir / "sanguo_portfolio/providers/local_unified_provider.py" + ).read_text(encoding="utf-8") + uni_methods = set(re.findall(r"^\s{4}def ([a-z]\w+)\(", uni_src, re.M)) + provider = SanguoMiniQmtProvider.__dict__ + base_methods = set( + n for n, v in vars(MiniQMTProvider).items() + if callable(v) and not n.startswith("__")) + missing = sorted( + m for m in uni_methods + if not m.startswith("_") + and m not in provider and m not in base_methods) + assert missing == [], f"回测有实盘无: {missing}"