ShopTRAINING/test/comprehensive_test.py

318 lines
13 KiB
Python
Raw Permalink Normal View History

2025-07-02 11:05:23 +08:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
综合测试脚本 - 验证现代化系统是否正确工作
"""
import os
import sys
import urllib.request
import json
import time
import threading
from datetime import datetime
# 设置UTF-8编码
os.environ['PYTHONIOENCODING'] = 'utf-8'
os.environ['PYTHONLEGACYWINDOWSSTDIO'] = '0'
if os.name == 'nt':
try:
os.system('chcp 65001 >nul 2>&1')
if hasattr(sys.stdout, 'reconfigure'):
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
sys.stderr.reconfigure(encoding='utf-8', errors='replace')
except Exception:
pass
class ModernSystemTester:
"""现代化系统测试器"""
def __init__(self):
self.base_url = "http://127.0.0.1:5000"
self.test_results = []
def log_test(self, test_name, status, message="", details=None):
"""记录测试结果"""
result = {
"test": test_name,
"status": status,
"message": message,
"details": details,
"timestamp": datetime.now().strftime('%H:%M:%S')
}
self.test_results.append(result)
status_emoji = "" if status == "PASS" else "" if status == "FAIL" else ""
print(f"{status_emoji} [{result['timestamp']}] {test_name}: {message}")
if details:
print(f" 详情: {details}")
def check_api_connectivity(self):
"""测试1: API连接性"""
try:
with urllib.request.urlopen(f"{self.base_url}/api/version", timeout=5) as response:
if response.getcode() == 200:
data = json.loads(response.read().decode('utf-8'))
version = data.get('data', {}).get('version', 'unknown')
features = data.get('data', {}).get('features', [])
self.log_test("API连接性", "PASS", f"版本 {version}", f"特性: {len(features)}")
return True
except Exception as e:
self.log_test("API连接性", "FAIL", f"连接失败: {str(e)}")
return False
def test_modern_logging(self):
"""测试2: 现代化日志系统"""
try:
# 检查日志文件是否存在
log_files = []
today = datetime.now().strftime('%Y-%m-%d')
expected_files = [
f"api_{today}.log",
f"api_error_{today}.log"
]
for file in expected_files:
if os.path.exists(file):
log_files.append(file)
if log_files:
self.log_test("日志文件生成", "PASS", f"发现 {len(log_files)} 个日志文件", log_files)
return True
else:
self.log_test("日志文件生成", "FAIL", "未发现loguru日志文件")
return False
except Exception as e:
self.log_test("日志文件生成", "FAIL", f"检查失败: {str(e)}")
return False
def test_training_process_manager(self):
"""测试3: 训练进程管理器"""
try:
# 提交训练任务
training_data = {
"product_id": "P001",
"model_type": "transformer",
"epochs": 2,
"training_mode": "product"
}
json_data = json.dumps(training_data).encode('utf-8')
req = urllib.request.Request(
f"{self.base_url}/api/training",
data=json_data,
headers={'Content-Type': 'application/json'}
)
with urllib.request.urlopen(req, timeout=30) as response:
if response.getcode() == 200:
result = json.loads(response.read().decode('utf-8'))
task_id = result.get('task_id')
message = result.get('message', '')
# 检查是否使用了现代化进程管理器
uses_modern_system = '独立进程' in message
if uses_modern_system:
self.log_test("进程管理器", "PASS", "使用独立进程管理器", f"任务ID: {task_id[:8]}")
return task_id
else:
self.log_test("进程管理器", "FAIL", "未使用现代化进程管理器", message)
return None
except Exception as e:
self.log_test("进程管理器", "FAIL", f"提交任务失败: {str(e)}")
return None
def test_task_status_tracking(self, task_id):
"""测试4: 任务状态跟踪"""
if not task_id:
self.log_test("任务状态跟踪", "SKIP", "无有效任务ID")
return False
try:
max_checks = 10
for i in range(max_checks):
with urllib.request.urlopen(f"{self.base_url}/api/training/{task_id}", timeout=5) as response:
if response.getcode() == 200:
result = json.loads(response.read().decode('utf-8'))
if result.get('status') == 'success':
data = result.get('data', {})
status = data.get('status', 'unknown')
progress = data.get('progress', 0)
process_id = data.get('process_id', 'N/A')
if i == 0: # 第一次检查
self.log_test("任务状态跟踪", "PASS",
f"状态={status}, 进度={progress}%, 进程ID={process_id}")
if status in ['completed', 'failed']:
return status == 'completed'
time.sleep(2)
self.log_test("任务状态跟踪", "FAIL", f"超时: {max_checks * 2}秒后任务仍未完成")
return False
except Exception as e:
self.log_test("任务状态跟踪", "FAIL", f"状态查询失败: {str(e)}")
return False
def test_unicode_support(self):
"""测试5: 中文和emoji支持"""
try:
# 检查产品列表API是否正确返回中文
with urllib.request.urlopen(f"{self.base_url}/api/products", timeout=5) as response:
if response.getcode() == 200:
result = json.loads(response.read().decode('utf-8'))
products = result.get('data', [])
chinese_found = False
for product in products:
name = product.get('name', '')
if any('\u4e00' <= char <= '\u9fff' for char in name): # 检查中文字符
chinese_found = True
break
if chinese_found:
self.log_test("中文支持", "PASS", f"发现 {len(products)} 个产品,包含中文")
# 测试emoji是否在控制台正常显示
test_emoji = "🚀📊🔧💬✅❌⏳🎯"
print(f" Emoji测试: {test_emoji}")
self.log_test("Emoji支持", "PASS", "控制台emoji显示正常")
return True
else:
self.log_test("中文支持", "FAIL", "未发现中文产品名称")
return False
except Exception as e:
self.log_test("中文支持", "FAIL", f"测试失败: {str(e)}")
return False
def test_concurrent_training(self):
"""测试6: 并发训练能力"""
try:
# 同时提交3个训练任务
models = ['mlstm', 'tcn', 'kan']
task_ids = []
for model in models:
training_data = {
"product_id": "P001",
"model_type": model,
"epochs": 1,
"training_mode": "product"
}
json_data = json.dumps(training_data).encode('utf-8')
req = urllib.request.Request(
f"{self.base_url}/api/training",
data=json_data,
headers={'Content-Type': 'application/json'}
)
with urllib.request.urlopen(req, timeout=30) as response:
if response.getcode() == 200:
result = json.loads(response.read().decode('utf-8'))
task_ids.append(result.get('task_id'))
time.sleep(0.5) # 稍微错开提交时间
if len(task_ids) == 3:
self.log_test("并发训练", "PASS", f"成功提交 {len(task_ids)} 个并发任务")
return True
else:
self.log_test("并发训练", "FAIL", f"只成功提交 {len(task_ids)}/3 个任务")
return False
except Exception as e:
self.log_test("并发训练", "FAIL", f"并发测试失败: {str(e)}")
return False
def test_all_tasks_api(self):
"""测试7: 任务列表API"""
try:
with urllib.request.urlopen(f"{self.base_url}/api/training", timeout=5) as response:
if response.getcode() == 200:
result = json.loads(response.read().decode('utf-8'))
if result.get('status') == 'success':
tasks = result.get('data', [])
self.log_test("任务列表API", "PASS", f"发现 {len(tasks)} 个历史任务")
return True
else:
self.log_test("任务列表API", "FAIL", "API返回错误状态")
return False
except Exception as e:
self.log_test("任务列表API", "FAIL", f"API调用失败: {str(e)}")
return False
def generate_report(self):
"""生成测试报告"""
print("\n" + "=" * 80)
print("🎯 现代化系统测试报告")
print("=" * 80)
total_tests = len(self.test_results)
passed_tests = len([r for r in self.test_results if r['status'] == 'PASS'])
failed_tests = len([r for r in self.test_results if r['status'] == 'FAIL'])
skipped_tests = len([r for r in self.test_results if r['status'] == 'SKIP'])
print(f"📊 测试统计:")
print(f" 总计: {total_tests} 个测试")
print(f" 通过: {passed_tests} 个 ✅")
print(f" 失败: {failed_tests} 个 ❌")
print(f" 跳过: {skipped_tests} 个 ⏭️")
print(f" 成功率: {passed_tests/total_tests*100:.1f}%")
print(f"\n📋 详细结果:")
for result in self.test_results:
status_emoji = "" if result['status'] == "PASS" else "" if result['status'] == "FAIL" else "⏭️"
print(f" {status_emoji} {result['test']}: {result['message']}")
print(f"\n🎯 总体评估:")
if failed_tests == 0:
print(" 🏆 所有测试通过!现代化系统工作完全正常")
return True
elif failed_tests <= 2:
print(" ⚠️ 大部分测试通过,系统基本正常,有少量问题需要修复")
return False
else:
print(" ❌ 多个测试失败,现代化系统存在问题需要进一步修复")
return False
def run_all_tests(self):
"""运行所有测试"""
print("🚀 开始现代化系统综合测试")
print("=" * 80)
# 测试序列
if not self.check_api_connectivity():
print("❌ API服务器未运行请先启动: uv run server/modern_api.py")
return False
self.test_modern_logging()
task_id = self.test_training_process_manager()
self.test_task_status_tracking(task_id)
self.test_unicode_support()
self.test_concurrent_training()
self.test_all_tasks_api()
return self.generate_report()
def main():
"""主函数"""
tester = ModernSystemTester()
success = tester.run_all_tests()
if success:
print("\n🎉 现代化系统修改完全正确!")
exit(0)
else:
print("\n⚠️ 现代化系统存在问题,需要进一步修复")
exit(1)
if __name__ == "__main__":
main()