mirror of
https://github.com/hpd840321/starRiverProperty.git
synced 2026-06-09 16:30:29 +08:00
docs+test: 发布包对拍计划、pytest 双端 API 对拍与 run_elevator_parity 脚本
- docs/elevator-api-parity: 计划/报告模板/示例 - tools/elevator_api_parity: 端点目录、fixtures、对拍 client/compare、报告生成 - scripts/run_elevator_parity: JDK8 构建 + 单测/对拍(无服务时跳过对拍用例) Made-with: Cursor Former-commit-id: 3d54a40e1a7ae0b1724261d4f18910a6f415f853
This commit is contained in:
+58
@@ -0,0 +1,58 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from parity.catalog_loader import load as load_catalog
|
||||
from parity.client import call_both
|
||||
|
||||
_DIR = Path(__file__).resolve().parent.parent
|
||||
_FIX = _DIR / "fixtures"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("two_instances_ready")
|
||||
@pytest.mark.live
|
||||
def test_parity_from_catalog(
|
||||
request,
|
||||
base_old,
|
||||
base_new,
|
||||
session_http,
|
||||
):
|
||||
"""按 api_catalog 双端对拍。compare_mode: deep | code_only | status_only"""
|
||||
cat = load_catalog()["endpoints"] # type: ignore[operator]
|
||||
for ep in cat:
|
||||
name = ep["id"]
|
||||
fixture = ep.get("fixture")
|
||||
body: dict
|
||||
if fixture:
|
||||
body = json.loads((_FIX / fixture).read_text(encoding="utf-8"))
|
||||
else:
|
||||
body = {}
|
||||
pr = call_both(
|
||||
name=ep.get("name", name),
|
||||
method=ep.get("method", "POST"),
|
||||
path=ep["path"],
|
||||
body=body,
|
||||
base_old=base_old,
|
||||
base_new=base_new,
|
||||
session=session_http,
|
||||
compare_mode=ep.get("compare_mode", "code_only"),
|
||||
)
|
||||
row = {
|
||||
"id": name,
|
||||
"name": ep.get("name", name),
|
||||
"method": pr.method,
|
||||
"path": pr.path,
|
||||
"old_status": pr.old_status,
|
||||
"new_status": pr.new_status,
|
||||
"match": pr.match,
|
||||
"message": pr.message,
|
||||
}
|
||||
request.config._parity_rows.append(row) # type: ignore
|
||||
# 在 code_only 下通常允许两边同一业务 code;若都非 200 也记录
|
||||
assert pr.match, (
|
||||
f"{name} mismatch: {pr.message}\n"
|
||||
f"old_http={pr.old_status} new_http={pr.new_status}\n"
|
||||
f"old_head={pr.old_text[:500]!r}\nnew_head={pr.new_text[:500]!r}"
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
"""不依赖联调机:纯比较逻辑自测。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from parity import compare as C
|
||||
|
||||
|
||||
def test_normalize_equal():
|
||||
a = {"b": 2, "a": 1, "c": {"z": 1, "y": 2}}
|
||||
b = {"c": {"y": 2, "z": 1}, "a": 1, "b": 2}
|
||||
assert C.normalize(a) == C.normalize(b)
|
||||
|
||||
|
||||
def test_business_code_from_cloudwalk_result():
|
||||
j = '{"code":"0","data":{}}'
|
||||
p = C.parse_json_loose(j)
|
||||
assert C.business_code(p) == "0"
|
||||
Reference in New Issue
Block a user