Przeglądaj źródła

test(interface): 接口冒烟闭环 2026-11-04 13:23 — 通过率 46% (fix=2 reg=0) [CONN_ERR翻转标flaky: fix=2 reg=0]; 测试用例 361/386 完成(文档化219)

E2E Test Bot 1 tydzień temu
rodzic
commit
2f3c73f45a

+ 9 - 7
INTERFACE_TEST_REPORT.md

@@ -1,15 +1,17 @@
-# CFC 接口冒烟测试报告 (20261104_082308)
+# CFC 接口冒烟测试报告 (20261104_131914)
 
 - 目标: cfc.iwintrue.com  用例总数: **549**
-- 业务成功率(BIZ_OK): **252/549 = 45%**
+- 业务成功率(BIZ_OK): **254/549 = 46%**
 
 ## 分类汇总
-- BIZ_OK: 252
+- BIZ_OK: 254
 - BIZ_FAIL: 295
-- CONN_ERR: 2
 
-## ⚠️ 回归劣化(1 个,之前通过现失败)
-- `POST /api/user/portrait/generate`  (现 CONN_ERR)
+## ✅ 回归修复(2 个,之前失败现已通过)
+- `POST /api/user/portrait/generate`  (原 CONN_ERR)  ← CONN_ERR 恢复,疑为口径抖动而非真实修复,需直连复核
+- `POST /api/user/portrait/regenerate`  (原 CONN_ERR)  ← CONN_ERR 恢复,疑为口径抖动而非真实修复,需直连复核
+
+> (其中 CONN_ERR 翻转 fix=2/reg=0 属口径抖动,非真实修复/劣化)
 
 ## 需开发团队关注的契约缺口 (NOT_FOUND=0)
 
@@ -22,7 +24,7 @@
 - 自动化用例总数(可执行 `test()`):**386**(api 层 55 / 角色分包 52 / DOM 层 279)
 - 文档化用例(设计层 TC-xxxx):**219**
 - 已完成(自动化且未被跳过):**361/386 = 93%**
-- 已实跑通过:接口冒烟 BIZ_OK **252** 端点 + API e2e 本轮 **51** 通过 / 3 failed / 3 skipped(来源 playwright_smoke.log)
+- 已实跑通过:接口冒烟 BIZ_OK **254** 端点 + API e2e 本轮 **51** 通过 / 3 failed / 3 skipped(来源 playwright_smoke.log)
 
 ### 未完成 / 未开始的原因(共 3 类)
 1. [279 项] DOM 型 E2E 无法执行(CFC-ENV-001):279 个用例已编写,但远程 cfc.iwintrue.com 为纯 Spring Boot API 后端、未部署 uni-app H5 / cfc-web 前端,浏览器型用例无法运行,未开始执行。

+ 2 - 2
interface_test_report.tsv

@@ -994,9 +994,9 @@ utils/api	getRecommendList	POST	/api/recommend/list	200	200	BIZ_OK
 utils/api	getChildOverview	POST	/api/stats/child/overview	200	200	BIZ_OK
 utils/api	getTaskHistory	POST	/api/tasks/history	200	200	BIZ_OK
 utils/api	editPortrait	POST	/api/user/portrait/edit	200	500	BIZ_FAIL
-utils/api	generatePortrait	POST	/api/user/portrait/generate	-1	None	CONN_ERR
+utils/api	generatePortrait	POST	/api/user/portrait/generate	200	200	BIZ_OK
 utils/api	getPortrait	POST	/api/user/portrait/get	200	200	BIZ_OK
-utils/api	regeneratePortrait	POST	/api/user/portrait/regenerate	-1	None	CONN_ERR
+utils/api	regeneratePortrait	POST	/api/user/portrait/regenerate	200	200	BIZ_OK
 utils/profile-backfill	backfillProfile	POST	/api/user/profile/backfill	200	500	BIZ_FAIL
 utils/sso	createSsoTicket	POST	/api/auth/sso-ticket	200	500	BIZ_FAIL
 auto	auto	GET	/api/cf/family-summary	200	200	BIZ_OK

+ 24 - 2
ops_interface_smoke.py

@@ -1030,6 +1030,27 @@ CASES = [
 ]
 
 
+# ── 长耗时 AI 路径单列超时(避免「正常但慢」被误判成 CONN_ERR)───────────────
+# 这些接口即使空体冒烟也会同步触发 LLM 调用,历史实测耗时在 5~50s 区间抖动,
+# 网关侧另有 proxy_read_timeout 60s 的一道 504。若沿用统一的 --timeout(8~10s),
+# 同一接口会在 fix/reg 之间来回假翻转(06:54 轮实测 9.52s 通过、10.55s 被斩,
+# 恰好骑在 10s 阈值两侧)。故此处按前缀单列更宽的超时,让慢但成功如实记 BIZ_OK,
+# 让真正超过网关 60s 的失败如实记 SERVER_ERR/504,而不是混成 CONN_ERR。
+SLOW_PATH_PREFIXES = (
+    '/api/user/portrait/generate',
+    '/api/user/portrait/regenerate',
+)
+SLOW_PATH_TIMEOUT = int(os.getenv('CFC_SLOW_TIMEOUT', '90'))
+
+
+def _timeout_for(path, default):
+    """长耗时 AI 路径放行到 SLOW_PATH_TIMEOUT,其余接口沿用 --timeout。"""
+    for _pfx in SLOW_PATH_PREFIXES:
+        if path.startswith(_pfx):
+            return max(default, SLOW_PATH_TIMEOUT)
+    return default
+
+
 def _call(base, method, path, token=None, timeout=10, host=None, body=b'{}'):
     url = base.rstrip('/') + path
     headers = {'Content-Type': 'application/json'}
@@ -1246,7 +1267,8 @@ def main():
             _m = body_map.get((method, real)) or body_map.get((method, path))
             if _m is not None:
                 body = _m
-        r = _call(args.base, method, real, token=token, timeout=args.timeout, host=args.host, body=body)
+        r = _call(args.base, method, real, token=token, timeout=_timeout_for(real, args.timeout),
+                  host=args.host, body=body)
         http_code, biz, cat = _classify(r)
         stats[cat] = stats.get(cat, 0) + 1
         pages.add(page)
@@ -1264,7 +1286,7 @@ def main():
                 return ''
 
         def _run(page, fn, method, path, body, tok):
-            rr = _call(args.base, method, path, token=tok, timeout=args.timeout,
+            rr = _call(args.base, method, path, token=tok, timeout=_timeout_for(path, args.timeout),
                        host=args.host, body=body)
             hc, bz, ct = _classify(rr)
             stats[ct] = stats.get(ct, 0) + 1

+ 2 - 2
playwright_smoke.log

@@ -70,7 +70,7 @@ Running 57 tests using 1 worker
 
 [44/57] [desktop] › e2e\api\nonfunc-perf-compat.spec.js:106:1 › [响应时间基线] 已登录家庭列表单请求耗时冒烟 ≤ 8s
 [desktop] › e2e\api\nonfunc-perf-compat.spec.js:106:1 › [响应时间基线] 已登录家庭列表单请求耗时冒烟 ≤ 8s
-[耗时] 家庭列表 77ms
+[耗时] 家庭列表 113ms
 
 [45/57] [desktop] › e2e\api\nonfunc-perf-compat.spec.js:117:6 › [TC-C-N01/X-N04] 任务打卡幂等:重复提交不重复计分(需任务流夹具)
 [46/57] [desktop] › e2e\api\nonfunc-perf-compat.spec.js:122:6 › [TC-X-N03] 活动名额并发不超卖:100 名额 / 瞬时 500 请求(需活动夹具 + 压测授权)
@@ -128,4 +128,4 @@ Running 57 tests using 1 worker
     [desktop] › e2e\api\nonfunc-security.spec.js:75:3 › 非功能/安全接口冒烟 › [TC-A-N05] 非管理员访问后台接口被拒(401/403) 
     [desktop] › e2e\api\nonfunc-security.spec.js:121:3 › 非功能/安全接口冒烟 › [TC-P-N11] 报告上传非 PDF/恶意内容被拒(非 200) 
   3 skipped
-  51 passed (46.8s)
+  51 passed (1.1m)