#!/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()