deep-risk/backend/scripts/test_revenue_algorithm.py
2025-12-14 20:08:27 +08:00

270 lines
9.5 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.

#!/usr/bin/env python3
"""
收入完整性检测算法测试脚本
自动运行所有测试场景并生成测试报告
"""
import os
import sys
import json
import time
import requests
from datetime import datetime
from typing import Dict, List, Tuple
sys.path.append('/Users/liulujian/Documents/code/deeprisk-claude-1/backend')
from loguru import logger
logger.add("test_revenue_algorithm.log", rotation="100 MB", level="INFO")
class RevenueAlgorithmTester:
"""收入完整性检测算法测试器"""
def __init__(self, api_base: str = "http://localhost:8000/api/v1"):
self.api_base = api_base
self.test_results = []
self.passed_count = 0
self.failed_count = 0
def load_test_scenarios(self) -> Dict:
"""加载测试场景"""
scenarios_file = "/Users/liulujian/Documents/code/deeprisk-claude-1/backend/test_data/revenue_test/test_scenarios.json"
with open(scenarios_file, 'r', encoding='utf-8') as f:
return json.load(f)
def run_single_test(self, scenario_id: str, scenario: Dict) -> Dict:
"""运行单个测试场景"""
streamer_id = scenario['streamer_id']
expected_level = scenario['expected_risk_level']
logger.info(f"开始测试: {scenario_id} - {scenario['name']}")
try:
# 构建请求
request_data = {
"entity_id": streamer_id,
"entity_type": "streamer",
"period": "2024-01",
"rule_ids": ["REVENUE_INTEGRITY_CHECK"],
"parameters": {
"comparison_type": "monthly"
}
}
# 发送请求
start_time = time.time()
response = requests.post(
f"{self.api_base}/risk-detection/execute",
json=request_data,
timeout=30
)
end_time = time.time()
# 检查响应状态
if response.status_code != 200:
return {
"scenario_id": scenario_id,
"scenario_name": scenario['name'],
"streamer_id": streamer_id,
"status": "FAILED",
"error": f"HTTP {response.status_code}",
"expected_risk_level": expected_level,
"actual_risk_level": None,
"expected_risk_score": scenario['expected_risk_score'],
"actual_risk_score": None,
"duration_ms": int((end_time - start_time) * 1000),
"description": scenario['description']
}
# 解析响应
result = response.json()
# 提取结果
actual_level = result.get('risk_level')
actual_score = result.get('risk_score')
# 验证结果
is_passed = (actual_level == expected_level)
if is_passed:
self.passed_count += 1
logger.info(f"✓ 通过: {scenario_id}")
else:
self.failed_count += 1
logger.warning(f"✗ 失败: {scenario_id} - 预期 {expected_level}, 实际 {actual_level}")
return {
"scenario_id": scenario_id,
"scenario_name": scenario['name'],
"streamer_id": streamer_id,
"status": "PASSED" if is_passed else "FAILED",
"error": None,
"expected_risk_level": expected_level,
"actual_risk_level": actual_level,
"expected_risk_score": scenario['expected_risk_score'],
"actual_risk_score": actual_score,
"duration_ms": int((end_time - start_time) * 1000),
"description": scenario['description'],
"response": result
}
except Exception as e:
self.failed_count += 1
logger.error(f"✗ 异常: {scenario_id} - {str(e)}")
return {
"scenario_id": scenario_id,
"scenario_name": scenario['name'],
"streamer_id": streamer_id,
"status": "FAILED",
"error": str(e),
"expected_risk_level": expected_level,
"actual_risk_level": None,
"expected_risk_score": scenario['expected_risk_score'],
"actual_risk_score": None,
"duration_ms": 0,
"description": scenario['description']
}
def run_all_tests(self) -> Dict:
"""运行所有测试场景"""
logger.info("=" * 80)
logger.info("开始运行收入完整性检测算法测试")
logger.info("=" * 80)
# 加载测试场景
scenarios = self.load_test_scenarios()
# 运行测试
start_time = time.time()
for scenario_id, scenario in scenarios.items():
result = self.run_single_test(scenario_id, scenario)
self.test_results.append(result)
time.sleep(0.5) # 防止请求过快
end_time = time.time()
# 生成报告
report = self.generate_report(end_time - start_time)
return report
def generate_report(self, total_duration: float) -> Dict:
"""生成测试报告"""
total_tests = len(self.test_results)
pass_rate = (self.passed_count / total_tests * 100) if total_tests > 0 else 0
report = {
"test_time": datetime.now().isoformat(),
"total_tests": total_tests,
"passed": self.passed_count,
"failed": self.failed_count,
"pass_rate": f"{pass_rate:.1f}%",
"total_duration_seconds": round(total_duration, 2),
"test_results": self.test_results
}
return report
def print_summary(self, report: Dict):
"""打印测试摘要"""
print("\n" + "=" * 80)
print("收入完整性检测算法测试报告")
print("=" * 80)
print(f"测试时间: {report['test_time']}")
print(f"总测试数: {report['total_tests']}")
print(f"通过: {report['passed']}")
print(f"失败: {report['failed']}")
print(f"通过率: {report['pass_rate']}")
print(f"总耗时: {report['total_duration_seconds']}")
print("=" * 80)
print()
# 按场景打印结果
for result in report['test_results']:
status_symbol = "" if result['status'] == 'PASSED' else ""
print(f"{status_symbol} {result['scenario_id']}: {result['scenario_name']}")
print(f" 主播ID: {result['streamer_id']}")
print(f" 预期等级: {result['expected_risk_level']}")
print(f" 实际等级: {result['actual_risk_level']}")
print(f" 预期评分: {result['expected_risk_score']}")
print(f" 实际评分: {result['actual_risk_score']}")
if result['error']:
print(f" 错误: {result['error']}")
print()
print("=" * 80)
def save_report(self, report: Dict):
"""保存测试报告"""
output_file = "/Users/liulujian/Documents/code/deeprisk-claude-1/backend/test_data/revenue_test/test_report.json"
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(report, f, ensure_ascii=False, indent=2)
logger.info(f"测试报告已保存到: {output_file}")
print(f"\n📄 详细报告已保存到: {output_file}")
def check_api_availability(self) -> bool:
"""检查API是否可用"""
try:
response = requests.get(f"{self.api_base}/risk-detection/execute", timeout=5)
# 这里可能会返回405 (Method Not Allowed)表示API存在
# 或者500错误表示服务正在运行
if response.status_code in [200, 405, 422, 500]:
logger.info("✓ API服务可用")
return True
else:
logger.error(f"✗ API服务异常: HTTP {response.status_code}")
return False
except Exception as e:
logger.error(f"✗ 无法连接到API服务: {str(e)}")
return False
def main():
"""主函数"""
print("=" * 80)
print("收入完整性检测算法 - 自动化测试工具")
print("=" * 80)
print()
# 初始化测试器
tester = RevenueAlgorithmTester()
# 检查API服务
print("1. 检查API服务...")
if not tester.check_api_availability():
print("\n❌ API服务不可用请确保后端服务正在运行")
print(" 启动命令: cd /Users/liulujian/Documents/code/deeprisk-claude-1/backend && python app/main.py")
sys.exit(1)
print(" ✓ API服务正常\n")
# 运行测试
print("2. 运行测试场景...")
report = tester.run_all_tests()
# 打印摘要
print("3. 生成测试报告...")
tester.print_summary(report)
# 保存报告
tester.save_report(report)
# 输出结论
if tester.failed_count == 0:
print("🎉 所有测试通过!")
print("\n✅ 算法实现正确,能够准确识别不同风险等级的收入问题")
sys.exit(0)
else:
print(f"\n⚠️ 有 {tester.failed_count} 个测试失败,请检查算法实现")
print("\n可能的原因:")
print(" 1. 阈值配置不正确")
print(" 2. 数据获取逻辑错误")
print(" 3. 风险计算公式错误")
print(" 4. 数据源问题")
sys.exit(1)
if __name__ == "__main__":
main()