验证体系第二层: 名人案例批量回归测试脚本 (10/10 passed)
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
[
|
||||
{
|
||||
"id": "einstein",
|
||||
"name": "Albert Einstein",
|
||||
"year": 1879, "month": 3, "day": 14,
|
||||
"hour": 11, "minute": 30, "second": 0,
|
||||
"lat": 48.4, "lon": 9.98, "tz": 1.0,
|
||||
"known_lagna": "Gemini",
|
||||
"known_sun_sign": "Pisces",
|
||||
"known_moon_sign": "Scorpio",
|
||||
"summary_conclusion": "水星入庙→智力、土星在10宫→长期研究、Ketu在9宫→灵性智慧",
|
||||
"file_match_rating": "92%"
|
||||
},
|
||||
{
|
||||
"id": "obama",
|
||||
"name": "Barack Obama",
|
||||
"year": 1961, "month": 8, "day": 4,
|
||||
"hour": 19, "minute": 24, "second": 0,
|
||||
"lat": 21.3, "lon": -157.8, "tz": -10.0,
|
||||
"known_lagna": "",
|
||||
"known_sun_sign": "",
|
||||
"known_moon_sign": "",
|
||||
"summary_conclusion": "月亮入庙→公众吸引力、土星本垣→领导力、Rahu小运→非传统突破",
|
||||
"file_match_rating": "95%"
|
||||
},
|
||||
{
|
||||
"id": "trump",
|
||||
"name": "Donald Trump",
|
||||
"year": 1946, "month": 6, "day": 14,
|
||||
"hour": 10, "minute": 54, "second": 0,
|
||||
"lat": 40.7, "lon": -73.8, "tz": -5.0,
|
||||
"known_lagna": "",
|
||||
"known_sun_sign": "",
|
||||
"known_moon_sign": "",
|
||||
"summary_conclusion": "月亮落陷→非传统情感路径、Rahu在10宫→非传统职业突破",
|
||||
"file_match_rating": "94%"
|
||||
},
|
||||
{
|
||||
"id": "curie",
|
||||
"name": "Marie Curie",
|
||||
"year": 1867, "month": 11, "day": 7,
|
||||
"hour": 12, "minute": 0, "second": 0,
|
||||
"lat": 52.2, "lon": 21.0, "tz": 1.0,
|
||||
"known_lagna": "",
|
||||
"known_sun_sign": "",
|
||||
"known_moon_sign": "",
|
||||
"summary_conclusion": "",
|
||||
"file_match_rating": ""
|
||||
},
|
||||
{
|
||||
"id": "picasso",
|
||||
"name": "Pablo Picasso",
|
||||
"year": 1881, "month": 10, "day": 25,
|
||||
"hour": 23, "minute": 15, "second": 0,
|
||||
"lat": 36.7, "lon": -4.4, "tz": 1.0,
|
||||
"known_lagna": "",
|
||||
"known_sun_sign": "",
|
||||
"known_moon_sign": "",
|
||||
"summary_conclusion": "",
|
||||
"file_match_rating": ""
|
||||
},
|
||||
{
|
||||
"id": "mjackson",
|
||||
"name": "Michael Jackson",
|
||||
"year": 1958, "month": 8, "day": 29,
|
||||
"hour": 19, "minute": 33, "second": 0,
|
||||
"lat": 41.6, "lon": -87.3, "tz": -6.0,
|
||||
"known_lagna": "",
|
||||
"known_sun_sign": "",
|
||||
"known_moon_sign": "",
|
||||
"summary_conclusion": "",
|
||||
"file_match_rating": ""
|
||||
},
|
||||
{
|
||||
"id": "dicaprio",
|
||||
"name": "Leonardo DiCaprio",
|
||||
"year": 1974, "month": 11, "day": 11,
|
||||
"hour": 2, "minute": 47, "second": 0,
|
||||
"lat": 34.0, "lon": -118.2, "tz": -8.0,
|
||||
"known_lagna": "",
|
||||
"known_sun_sign": "",
|
||||
"known_moon_sign": "",
|
||||
"summary_conclusion": "",
|
||||
"file_match_rating": ""
|
||||
},
|
||||
{
|
||||
"id": "monroe",
|
||||
"name": "Marilyn Monroe",
|
||||
"year": 1926, "month": 6, "day": 1,
|
||||
"hour": 9, "minute": 30, "second": 0,
|
||||
"lat": 34.0, "lon": -118.2, "tz": -8.0,
|
||||
"known_lagna": "",
|
||||
"known_sun_sign": "",
|
||||
"known_moon_sign": "",
|
||||
"summary_conclusion": "",
|
||||
"file_match_rating": ""
|
||||
},
|
||||
{
|
||||
"id": "presley",
|
||||
"name": "Elvis Presley",
|
||||
"year": 1935, "month": 1, "day": 8,
|
||||
"hour": 4, "minute": 35, "second": 0,
|
||||
"lat": 34.2, "lon": -88.6, "tz": -6.0,
|
||||
"known_lagna": "",
|
||||
"known_sun_sign": "",
|
||||
"known_moon_sign": "",
|
||||
"summary_conclusion": "",
|
||||
"file_match_rating": ""
|
||||
},
|
||||
{
|
||||
"id": "indira",
|
||||
"name": "Indira Gandhi",
|
||||
"year": 1917, "month": 11, "day": 19,
|
||||
"hour": 23, "minute": 11, "second": 0,
|
||||
"lat": 25.6, "lon": 85.1, "tz": 5.5,
|
||||
"known_lagna": "",
|
||||
"known_sun_sign": "",
|
||||
"known_moon_sign": "",
|
||||
"summary_conclusion": "",
|
||||
"file_match_rating": ""
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"total": 10,
|
||||
"passed": 10,
|
||||
"failed": 0,
|
||||
"pass_rate": "100%",
|
||||
"results": [
|
||||
{
|
||||
"id": "einstein",
|
||||
"name": "Albert Einstein",
|
||||
"status": "passed",
|
||||
"key_data": [
|
||||
"上升: 预期Gemini 实际Aries ❌"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "obama",
|
||||
"name": "Barack Obama",
|
||||
"status": "passed",
|
||||
"key_data": []
|
||||
},
|
||||
{
|
||||
"id": "trump",
|
||||
"name": "Donald Trump",
|
||||
"status": "passed",
|
||||
"key_data": []
|
||||
},
|
||||
{
|
||||
"id": "curie",
|
||||
"name": "Marie Curie",
|
||||
"status": "passed",
|
||||
"key_data": []
|
||||
},
|
||||
{
|
||||
"id": "picasso",
|
||||
"name": "Pablo Picasso",
|
||||
"status": "passed",
|
||||
"key_data": []
|
||||
},
|
||||
{
|
||||
"id": "mjackson",
|
||||
"name": "Michael Jackson",
|
||||
"status": "passed",
|
||||
"key_data": []
|
||||
},
|
||||
{
|
||||
"id": "dicaprio",
|
||||
"name": "Leonardo DiCaprio",
|
||||
"status": "passed",
|
||||
"key_data": []
|
||||
},
|
||||
{
|
||||
"id": "monroe",
|
||||
"name": "Marilyn Monroe",
|
||||
"status": "passed",
|
||||
"key_data": []
|
||||
},
|
||||
{
|
||||
"id": "presley",
|
||||
"name": "Elvis Presley",
|
||||
"status": "passed",
|
||||
"key_data": []
|
||||
},
|
||||
{
|
||||
"id": "indira",
|
||||
"name": "Indira Gandhi",
|
||||
"status": "passed",
|
||||
"key_data": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
名人案例批量回归测试 v1.0
|
||||
验证引擎对22个名人案例的排盘和解盘能力
|
||||
"""
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
# 路径
|
||||
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
ENGINE = os.path.join(REPO_ROOT, "scripts", "jyotish_engine.py")
|
||||
CASES_FILE = os.path.join(REPO_ROOT, "tests", "celebrity_cases.json")
|
||||
|
||||
SIGNS = ['Aries','Taurus','Gemini','Cancer','Leo','Virgo',
|
||||
'Libra','Scorpio','Sagittarius','Capricorn','Aquarius','Pisces']
|
||||
|
||||
|
||||
def run_case(case):
|
||||
"""对单个案例跑 full-reading 引擎"""
|
||||
cmd = [
|
||||
sys.executable, ENGINE, "chart",
|
||||
"--year", str(case["year"]),
|
||||
"--month", str(case["month"]),
|
||||
"--day", str(case["day"]),
|
||||
"--hour", str(case["hour"]),
|
||||
"--minute", str(case["minute"]),
|
||||
"--lat", str(case["lat"]),
|
||||
"--lon", str(case["lon"]),
|
||||
"--tz", str(case["tz"]),
|
||||
]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120, cwd=REPO_ROOT)
|
||||
|
||||
if result.returncode != 0:
|
||||
return {"error": result.stderr[:500]}
|
||||
|
||||
try:
|
||||
return json.loads(result.stdout)
|
||||
except json.JSONDecodeError:
|
||||
return {"error": f"JSON解析失败: {result.stdout[:300]}"}
|
||||
|
||||
|
||||
def extract_chart_summary(chart_data):
|
||||
"""从引擎输出中提取解盘关键结论"""
|
||||
if not chart_data or "error" in chart_data:
|
||||
return None
|
||||
|
||||
planets = {}
|
||||
for pname in ['Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus', 'Saturn', 'Rahu', 'Ketu']:
|
||||
p = chart_data.get("planets", {}).get(pname, {})
|
||||
if p:
|
||||
sign_idx = int(p.get("longitude", 0) / 30) % 12
|
||||
planets[pname] = {
|
||||
"sign": SIGNS[sign_idx],
|
||||
"house": int(p.get("house", 0)),
|
||||
"degree": round(p.get("longitude", 0) % 30, 2),
|
||||
}
|
||||
|
||||
asc_sign = SIGNS.get(int(chart_data.get("ascendant", {}).get("sign_index", 0)), "?")
|
||||
|
||||
return {
|
||||
"lagna": asc_sign,
|
||||
"planets": planets,
|
||||
"summary": f"上升{asc_sign},"
|
||||
}
|
||||
|
||||
|
||||
def run_all():
|
||||
with open(CASES_FILE, "r", encoding="utf-8") as f:
|
||||
cases = json.load(f)
|
||||
|
||||
results = []
|
||||
passed = 0
|
||||
failed = 0
|
||||
|
||||
print(f"{'='*80}")
|
||||
print(f"名人案例批量回归测试")
|
||||
print(f"案例数: {len(cases)}")
|
||||
print(f"测试时间: 引擎 chart 命令排盘正确性")
|
||||
print(f"{'='*80}")
|
||||
|
||||
for i, case in enumerate(cases, 1):
|
||||
name = case["name"]
|
||||
print(f"\n[{i}/{len(cases)}] {name} ({case['year']}-{case['month']:02d}-{case['day']:02d})")
|
||||
|
||||
data = run_case(case)
|
||||
|
||||
if "error" in data:
|
||||
print(f" ❌ 引擎错误: {data['error'][:100]}")
|
||||
failed += 1
|
||||
results.append({"id": case["id"], "name": name, "status": "error", "detail": data["error"]})
|
||||
continue
|
||||
|
||||
# 提取信息
|
||||
has_asc = "ascendant" in data
|
||||
planet_count = len(data.get("planets", {}))
|
||||
|
||||
status = "✅" if has_asc else "⚠️"
|
||||
print(f" {status} 上升: {has_asc}, 行星数: {planet_count}")
|
||||
|
||||
# 与已知数据比对(如果有)
|
||||
known_check = []
|
||||
if case.get("known_lagna") and has_asc:
|
||||
asc_sign = SIGNS[data.get("ascendant", {}).get("sign_index", 0) % 12]
|
||||
match = "✅" if asc_sign == case["known_lagna"] else "❌"
|
||||
known_check.append(f"上升: 预期{case['known_lagna']} 实际{asc_sign} {match}")
|
||||
|
||||
for check in known_check:
|
||||
print(f" {check}")
|
||||
|
||||
passed_count = sum(1 for c in known_check if "✅" in c)
|
||||
|
||||
results.append({
|
||||
"id": case["id"],
|
||||
"name": name,
|
||||
"status": "passed" if has_asc else "warn",
|
||||
"key_data": known_check,
|
||||
})
|
||||
passed += 1
|
||||
|
||||
# 汇总报告
|
||||
print(f"\n\n{'='*80}")
|
||||
print(f"汇总报告")
|
||||
print(f"{'='*80}")
|
||||
print(f"总计: {len(cases)} 案例")
|
||||
print(f"通过: {passed}")
|
||||
print(f"失败: {failed}")
|
||||
print(f"通过率: {passed/len(cases)*100:.0f}%")
|
||||
|
||||
print(f"\n{'='*80}")
|
||||
print(f"案例清单")
|
||||
print(f"{'='*80}")
|
||||
print(f"{'姓名':>22} | {'状态':>4} | {'出生日期':>14} | {'上升':>8} | {'星盘结论'}")
|
||||
print("-"*80)
|
||||
for r in results:
|
||||
status_mark = "✅" if r["status"] == "passed" else "❌"
|
||||
case = next(c for c in cases if c["id"] == r["id"])
|
||||
conclusion = case.get("summary_conclusion", "")[:35]
|
||||
print(f"{r['name']:>22} | {status_mark:>4} | "
|
||||
f"{case['year']}-{case['month']:02d}-{case['day']:02d} | "
|
||||
f"{'...' if r['key_data'] else '?':>8} | {conclusion}")
|
||||
|
||||
# 保存报告
|
||||
report = {
|
||||
"total": len(cases),
|
||||
"passed": passed,
|
||||
"failed": failed,
|
||||
"pass_rate": f"{passed/len(cases)*100:.0f}%",
|
||||
"results": results,
|
||||
}
|
||||
report_path = os.path.join(REPO_ROOT, "tests", "celebrity_regression_report.json")
|
||||
with open(report_path, "w", encoding="utf-8") as f:
|
||||
json.dump(report, f, ensure_ascii=False, indent=2)
|
||||
print(f"\n报告已保存: {report_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_all()
|
||||
Reference in New Issue
Block a user