""" scripts/test_jd_intake.py — JD Intake + rank_job_list 集成测试 验证:粘贴 JD 文本 → parse_jd → normalize → rank_job_list 全链路 """ import sys, json, pathlib sys.path.insert(0, str(pathlib.Path(__file__).parent.parent)) from src.jd_parser import parse_jd from src.job_intake import parse_single_jd, parse_multiple_jds, normalize_job, merge_builtin_and_user_jobs, load_builtin_jobs from src.resume_parser import parse_resume from src.matcher import rank_job_list JD_LLM = """岗位:大模型应用算法实习生 公司:字节跳动 AI 部门 地点:北京 方向:大模型应用算法 要求:熟悉 Python、PyTorch、Transformer,有 RAG/Agent 项目经验,了解 LangChain 和向量数据库。负责企业级 LLM 应用开发和 Agent 工作流设计。面试覆盖 RAG 召回策略、Agent 兜底、Prompt 工程。""" JD_REC = """岗位:推荐算法实习生 公司:快手 地点:深圳 方向:推荐算法 要求:熟悉推荐系统、召回排序,掌握 Python 和深度学习框架。了解 A/B Test 和离线评估指标。负责内容推荐模型优化和线上 A/B 实验。""" RESUME = """张同学 | 计算机科学与技术 | 2026 届硕士 技能:Python、PyTorch、Transformer、RAG、Agent、Embedding 项目:RAG 知识库问答系统、LLM Agent 工具调用 Demo""" def main(): print("=== Test 1: parse_single_jd ===") j1 = parse_single_jd(JD_LLM) assert j1["title"], "title missing" assert j1["skills"], "skills missing" assert j1["source"] == "user_pasted", f"source={j1['source']}" print(f" [OK] title={j1['title']}, skills={j1['skills'][:5]}, source={j1['source']}") print("=== Test 2: parse_multiple_jds ===") multi = f"{JD_LLM}\n---JD---\n{JD_REC}" jobs = parse_multiple_jds(multi) assert len(jobs) == 2, f"expected 2, got {len(jobs)}" print(f" [OK] parsed {len(jobs)} JDs: {[j['title'] for j in jobs]}") print("=== Test 3: normalize + merge ===") import pathlib as _pl _ROOT = _pl.Path(__file__).parent.parent builtin = load_builtin_jobs(str(_ROOT / "data" / "jobs.json")) merged = merge_builtin_and_user_jobs(builtin, jobs) print(f" [OK] builtin={len(builtin)}, user={len(jobs)}, merged={len(merged)}") print("=== Test 4: rank_job_list (LLM JD) ===") profile = parse_resume(RESUME) scored = rank_job_list(RESUME, profile, "大模型应用算法", "北京", "实习", 5, [j1]) assert len(scored) > 0, "rank_job_list returned empty" top = scored[0] print(f" [OK] Top1={top['title']}, match={top.get('match_score')}, apply_priority={top.get('apply_priority')}") print("=== Test 5: golden cases with jd_text ===") golden_path = pathlib.Path("eval/golden_cases.json") golden = json.loads(golden_path.read_text(encoding="utf-8")) jd_cases = [c for c in golden if "jd_text" in c] print(f" [OK] Found {len(jd_cases)} JD intake golden cases: {[c['case_id'] for c in jd_cases]}") for case in jd_cases: job = parse_single_jd(case["jd_text"]) profile = parse_resume(case["resume_text"]) scored = rank_job_list(case["resume_text"], profile, case["target_role"], case["target_city"], case["stage"], 3, [job]) assert scored, f"rank_job_list empty for {case['case_id']}" print(f" [OK] {case['case_id']}: top match={scored[0].get('match_score')}, apply={scored[0].get('apply_priority')}") print("\n=== All JD Intake tests passed ===") if __name__ == "__main__": main()