Files
gaokao-volunteer-system/data/crowd_db/tests/test_special_programs.py
Hermes Agent bf0ed7eeab
Some checks failed
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
feat(special-programs): 5类特殊批次定向培养计划数据+规则+prompt+引擎
数据层:
- data/crowd_db/special_programs.json: 5类项目定义+20+真实院校分数线
  - 农村订单定向免费医学生: 长沙医学院(444)/湘南学院(441)/河南科技(510)等
  - 公费农科生: 山东农业大学(460)/湖南农业大学(430)等
  - 公费消防/应急管理: 中国消防救援学院(500)等
  - 铁路定向公费生: 武汉铁路(223)/郑州铁路(330)/石家庄铁路(350)等
  - 司法系统定向/社区矫正: 中央司法警官学院(480)等

- data/crowd_db/special_programs_loader.py: 查询引擎
  - list_programs_for_province(): 按省份筛选适用项目
  - find_matching_schools(): 按省份+分数匹配院校(含 0.85 弹性阈值)
  - build_recommendation_for_review(): 生成审核推荐摘要(含 match_score)

规则层:
- data/rules/special_programs_rules.json: 9条特殊批次政策规则
  - 提前批填报要求/户籍要求/服务期承诺/体检标准/学费政策/编制保障

prompt 层:
- build_audit_prompt: 加入5条特殊批次捡漏路径引导
  - LLM 审核时必须考虑这些路径,低分考生方案无特殊批次会在 key_findings 提示
  - 新增 special_program_recommendations 输出字段
- build_cwb_prompt: 保底档应包含特殊批次路径之一

测试: 27 passed (special_programs 11 + llm 16)
2026-06-28 15:17:42 +08:00

107 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""特殊批次定向培养计划模块测试。"""
from __future__ import annotations
from pathlib import Path
from data.crowd_db.special_programs_loader import SpecialProgramsLoader
_DATA_PATH = Path(__file__).resolve().parent.parent / "special_programs.json"
_RULES_PATH = (
Path(__file__).resolve().parents[3]
/ "data"
/ "rules"
/ "special_programs_rules.json"
)
class TestSpecialProgramsLoader:
def setup_method(self):
self.loader = SpecialProgramsLoader(
data_path=_DATA_PATH, rules_path=_RULES_PATH
)
def test_loads_5_program_types(self):
programs = self.loader.list_programs()
types = {p["program_type"] for p in programs}
assert types == {
"rural_medical",
"public_agriculture",
"fire_rescue",
"railway_directed",
"judicial_directed",
}
def test_get_program(self):
p = self.loader.get_program("rural_medical")
assert p is not None
assert p["program_name"] == "农村订单定向免费医学生"
assert p["key_features"]["service_years"] == 6
def test_get_program_not_found(self):
assert self.loader.get_program("nonexistent") is None
def test_list_programs_for_hunan(self):
programs = self.loader.list_programs_for_province("湖南")
types = {p["program_type"] for p in programs}
# 湖南应该有 rural_medicalapplicable_provinces 含"湖南"
# fire_rescue/railway_directed/judicial_directed 是"全国"
assert "rural_medical" in types
assert "fire_rescue" in types # 全国
assert "railway_directed" in types # 全国
def test_find_matching_schools_for_hunan_578(self):
"""湖南 578 分应该能匹配到铁路/消防/医疗等院校。"""
results = self.loader.find_matching_schools("湖南", 578)
assert len(results) > 0
# 应包含铁路(湖南铁道职业技术学院 340 分)
types = {r["program_type"] for r in results}
assert "railway_directed" in types
def test_find_matching_schools_low_score(self):
"""低分考生250应该匹配到铁路专科。"""
results = self.loader.find_matching_schools("湖北", 250)
# 武汉铁路职业技术学院 223 分
railway = [r for r in results if r["program_type"] == "railway_directed"]
assert len(railway) > 0
assert any("武汉铁路" in r["school"] for r in railway)
def test_find_matching_schools_high_score_excludes_far(self):
"""高分考生不应匹配到分数差距过大的院校。"""
results = self.loader.find_matching_schools("湖南", 650)
# 650 分不应匹配到 223 分的武汉铁路(差距 427 分223*0.85=189.55
# 但仍然匹配(因为 650 >= 189.55),只是 gap 很大
# 验证至少不报错
assert isinstance(results, list)
def test_get_applicable_rules(self):
rules = self.loader.get_applicable_rules("rural_medical")
rule_ids = {r["rule_id"] for r in rules}
assert "special.rural_medical.hukou_requirement" in rule_ids
assert "special.rural_medical.service_commitment" in rule_ids
assert "special.general.tuition_free" in rule_ids
def test_build_recommendation_for_review(self):
"""审核场景推荐摘要。"""
recs = self.loader.build_recommendation_for_review("湖南", 450)
assert len(recs) > 0
# 450 分应该能匹配到定向医疗444/441分
types = {r["program_type"] for r in recs}
assert "rural_medical" in types
# 每条都有 match_score
for r in recs:
assert "match_score" in r
assert 0 <= r["match_score"] <= 100
def test_build_recommendation_no_match(self):
"""不存在的省份只返回全国性项目fire/railway/judicial不报错。"""
recs = self.loader.build_recommendation_for_review("火星", 500)
# 全国性项目仍可能返回,但不应报错
assert isinstance(recs, list)
def test_rules_loaded(self):
rules = self.loader.rules
assert "rules" in rules
assert len(rules["rules"]) >= 9