| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- # -*- coding: utf-8 -*-
- """
- 扫描 cfc-frontend,提取所有 request() 调用的 method+path,用于检测
- 「新增 / 变更需求」——与基线对比即可知道前端新增了哪些接口,从而自动补全用例。
- 输出(默认 endpoints 模式):每行 `METHOD /api/path`(排序去重),便于 comm 对比。
- python scan_frontend_endpoints.py --out endpoints.txt
- python scan_frontend_endpoints.py --mode cases --out extra.tsv # 直接产出冒烟用例 TSV
- """
- import os, re, sys, argparse
- HERE = os.path.dirname(os.path.abspath(__file__))
- FRONTEND = os.path.join(HERE, 'cfc-frontend')
- # 两种 request 调用风格:
- # 1) request('/api/x', 'POST', data)
- # 2) request({ url: BASE_URL + '/api/x', method: 'POST' })
- path_re_pos = re.compile(r"request\(\s*['\"](/api/[^'\"]+)['\"]\s*,\s*['\"](GET|POST|PUT|DELETE|PATCH)['\"]", re.I)
- path_re_obj = re.compile(r"url\s*:\s*(?:BASE_URL\s*\+\s*)?['\"](/api/[^'\"]+)['\"]")
- method_re_obj = re.compile(r"method\s*:\s*['\"](GET|POST|PUT|DELETE|PATCH)['\"]", re.I)
- SKIP_DIRS = ('node_modules', 'unpackage', '.git', 'dist', 'assets')
- def scan_file(path):
- out = set()
- try:
- with open(path, 'r', encoding='utf-8', errors='ignore') as f:
- text = f.read()
- except Exception:
- return out
- for m in path_re_pos.finditer(text):
- out.add((m.group(2).upper(), m.group(1)))
- for um in path_re_obj.finditer(text):
- p = um.group(1)
- window = text[um.end(): um.end() + 200]
- mm = method_re_obj.search(window)
- method = mm.group(1).upper() if mm else 'POST'
- out.add((method, p))
- return out
- def main():
- ap = argparse.ArgumentParser()
- ap.add_argument('--frontend', default=FRONTEND)
- ap.add_argument('--out')
- ap.add_argument('--mode', choices=['endpoints', 'cases'], default='endpoints')
- args = ap.parse_args()
- results = set()
- for root, dirs, files in os.walk(args.frontend):
- dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
- for fn in files:
- if fn.endswith(('.js', '.vue')):
- results |= scan_file(os.path.join(root, fn))
- if args.mode == 'cases':
- # page fn method path auth param —— 自动补全的用例默认匿名、无路径参数
- lines = sorted(f"auto\tauto\t{m}\t{p}\tfalse\tfalse" for m, p in results)
- else:
- lines = sorted(f"{m} {p}" for m, p in results)
- text = "\n".join(lines) + ("\n" if lines else "")
- if args.out:
- with open(args.out, 'w', encoding='utf-8') as f:
- f.write(text)
- else:
- sys.stdout.write(text)
- if __name__ == '__main__':
- main()
|