#!/usr/bin/env python3 """ LLM 投資建議服務測試腳本 用於測試 LLM 服務是否正常工作 """ import os import sys import json from unittest.mock import Mock, patch # 添加專案根目錄到 Python 路徑 sys.path.append(os.path.dirname(os.path.abspath(__file__))) from llm_service import LLMInvestmentAdvisor, get_llm_advisor from prompts.investment_advice import get_comprehensive_analysis_prompt def test_llm_service_initialization(): """測試 LLM 服務初始化""" print("🔍 測試 LLM 服務初始化...") try: # 測試沒有 API 金鑰的情況 try: advisor = LLMInvestmentAdvisor(api_key=None) print("❌ 應該拋出錯誤但沒有拋出") return False except ValueError as e: print(f"✅ 正確拋出錯誤:{e}") # 測試有假 API 金鑰的情況 fake_api_key = "sk-fake-key-for-testing" try: advisor = LLMInvestmentAdvisor(api_key=fake_api_key) print("✅ 成功初始化 LLM 服務") return True except Exception as e: print(f"❌ 初始化失敗:{e}") return False except Exception as e: print(f"❌ 測試失敗:{e}") return False def test_prompt_generation(): """測試 Prompt 生成""" print("\n🔍 測試 Prompt 生成...") try: # 模擬策略資料 mock_strategy_data = { 'id': 123, 'name': '測試策略', 'role': '最大化夏普比率', 'annual_ret': 0.15, 'vol': 0.20, 'annual_sr': 1.8, 'mdd': -0.12, 'alpha': 0.08, 'beta': 0.95, 'var10': 0.05, 'r2': 0.85, 'gamma': 2.5, 'assets': ['AAPL', 'GOOGL', 'MSFT'], 'tw': True } prompt = get_comprehensive_analysis_prompt(mock_strategy_data) if len(prompt) > 100 and '策略名稱:測試策略' in prompt: print("✅ Prompt 生成成功") print(f"📝 Prompt 長度:{len(prompt)} 字符") return True else: print("❌ Prompt 生成格式錯誤") return False except Exception as e: print(f"❌ Prompt 生成失敗:{e}") return False def test_fallback_advice(): """測試 Fallback 建議""" print("\n🔍 測試 Fallback 建議...") try: advisor = LLMInvestmentAdvisor(api_key="fake-key") # 模擬會失敗的策略資料 strategy_data = { 'annual_ret': 0.25, 'vol': 0.15, 'annual_sr': 2.1 } fallback_advice = advisor._get_fallback_advice(strategy_data) if len(fallback_advice) > 100 and '年化報酬率:25.00%' in fallback_advice: print("✅ Fallback 建議生成成功") return True else: print("❌ Fallback 建議格式錯誤") return False except Exception as e: print(f"❌ Fallback 測試失敗:{e}") return False def test_api_format(): """測試 API 回應格式""" print("\n🔍 測試 API 回應格式...") try: # 模擬成功的 API 回應 mock_response = { 'success': True, 'advice': '這是一個測試建議。年化報酬率表現良好,建議持續監控市場變化。', 'strategy_id': 123 } if all(key in mock_response for key in ['success', 'advice', 'strategy_id']): print("✅ API 回應格式正確") return True else: print("❌ API 回應格式錯誤") return False except Exception as e: print(f"❌ API 格式測試失敗:{e}") return False def test_error_format(): """測試錯誤回應格式""" print("\n🔍 測試錯誤回應格式...") try: # 模擬錯誤回應 mock_error_response = { 'success': False, 'error': 'API 金鑰無效', 'details': '請檢查 OpenAI API 金鑰設定' } if all(key in mock_error_response for key in ['success', 'error']): print("✅ 錯誤回應格式正確") return True else: print("❌ 錯誤回應格式錯誤") return False except Exception as e: print(f"❌ 錯誤格式測試失敗:{e}") return False def main(): """主測試函數""" print("🚀 開始測試 LLM 投資建議服務\n") tests = [ ("LLM 服務初始化", test_llm_service_initialization), ("Prompt 生成", test_prompt_generation), ("Fallback 建議", test_fallback_advice), ("API 回應格式", test_api_format), ("錯誤回應格式", test_error_format), ] passed = 0 total = len(tests) for test_name, test_func in tests: if test_func(): passed += 1 print() print("📊 測試結果摘要") print(f"✅ 通過:{passed}/{total}") print(f"❌ 失敗:{total - passed}/{total}") if passed == total: print("🎉 所有測試通過!LLM 服務準備就緒。") return 0 else: print("⚠️ 部分測試失敗,請檢查配置。") return 1 if __name__ == "__main__": exit(main())