feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
This commit is contained in:
@@ -0,0 +1,371 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
前后端API交互自动化测试工具(增强版)
|
||||
支持参数化测试、边界条件测试、异常场景测试和自动认证
|
||||
"""
|
||||
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
from typing import List, Dict, Any
|
||||
|
||||
# 添加项目根目录到Python路径
|
||||
project_root = Path(__file__).parent
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
from config.settings import config
|
||||
from core.api_tester import APITester
|
||||
from utils.logger import TestLogger, LoggerFactory
|
||||
from utils.reporter import ReportGenerator, TestResult as ReportTestResult, TestSummary
|
||||
from test_cases.api_tests_enhanced import (
|
||||
APITestCases,
|
||||
ParameterizedTestCases,
|
||||
BoundaryTestCases,
|
||||
ExceptionTestCases
|
||||
)
|
||||
|
||||
|
||||
class EnhancedTestRunner:
|
||||
"""增强测试运行器"""
|
||||
|
||||
def __init__(self):
|
||||
"""初始化测试运行器"""
|
||||
self.logger = LoggerFactory.get_logger(
|
||||
"enhanced_test_runner",
|
||||
config.logging_file,
|
||||
config.logging_level,
|
||||
config.logging_console
|
||||
)
|
||||
|
||||
self.tester = APITester(self.logger, auto_auth=True)
|
||||
self.api_test_cases = APITestCases(self.tester)
|
||||
self.parameterized_test_cases = ParameterizedTestCases(self.tester)
|
||||
self.boundary_test_cases = BoundaryTestCases(self.tester)
|
||||
self.exception_test_cases = ExceptionTestCases(self.tester)
|
||||
self.report_generator = ReportGenerator(config.report_output_dir)
|
||||
self.test_results: List[ReportTestResult] = []
|
||||
self.start_time: float = 0
|
||||
|
||||
def run_test(self, test_name: str, test_func) -> bool:
|
||||
"""
|
||||
运行单个测试
|
||||
|
||||
Args:
|
||||
test_name: 测试名称
|
||||
test_func: 测试函数
|
||||
|
||||
Returns:
|
||||
是否通过
|
||||
"""
|
||||
self.logger.log_test_start(test_name)
|
||||
|
||||
try:
|
||||
start_time = time.time()
|
||||
passed = test_func()
|
||||
duration = (time.time() - start_time) * 1000
|
||||
|
||||
self.logger.log_test_end(test_name, passed, duration)
|
||||
|
||||
# 记录测试结果
|
||||
test_result = ReportTestResult(
|
||||
test_name=test_name,
|
||||
test_type="API",
|
||||
url=config.api_base_url,
|
||||
method="N/A",
|
||||
status_code=200 if passed else 0,
|
||||
response_time=duration,
|
||||
success=passed,
|
||||
error_message="" if passed else f"测试失败",
|
||||
request_data={},
|
||||
response_data={},
|
||||
timestamp=time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
)
|
||||
|
||||
self.test_results.append(test_result)
|
||||
|
||||
return passed
|
||||
|
||||
except Exception as e:
|
||||
duration = (time.time() - start_time) * 1000
|
||||
self.logger.log_error(e)
|
||||
|
||||
test_result = ReportTestResult(
|
||||
test_name=test_name,
|
||||
test_type="API",
|
||||
url=config.api_base_url,
|
||||
method="N/A",
|
||||
status_code=0,
|
||||
response_time=duration,
|
||||
success=False,
|
||||
error_message=str(e),
|
||||
request_data={},
|
||||
response_data={},
|
||||
timestamp=time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
)
|
||||
|
||||
self.test_results.append(test_result)
|
||||
|
||||
return False
|
||||
|
||||
def run_basic_tests(self) -> Dict[str, bool]:
|
||||
"""
|
||||
运行基础测试用例
|
||||
|
||||
Returns:
|
||||
测试结果字典
|
||||
"""
|
||||
self.logger.info("="*60)
|
||||
self.logger.info("运行基础测试用例")
|
||||
self.logger.info("="*60)
|
||||
|
||||
return self.api_test_cases.run_all_tests()
|
||||
|
||||
def run_parameterized_tests(self) -> Dict[str, Dict[str, bool]]:
|
||||
"""
|
||||
运行参数化测试用例
|
||||
|
||||
Returns:
|
||||
测试结果字典
|
||||
"""
|
||||
self.logger.info("="*60)
|
||||
self.logger.info("运行参数化测试用例")
|
||||
self.logger.info("="*60)
|
||||
|
||||
results = {}
|
||||
|
||||
# 测试不同凭据登录
|
||||
credentials = [
|
||||
{"username": "admin", "password": "admin123"},
|
||||
{"username": "test", "password": "test123"}
|
||||
]
|
||||
results["不同凭据登录"] = self.parameterized_test_cases.test_login_with_different_credentials(credentials)
|
||||
|
||||
# 测试不同页面大小
|
||||
page_sizes = [10, 20, 50, 100]
|
||||
results["分页功能"] = self.parameterized_test_cases.test_pagination(page_sizes)
|
||||
|
||||
return results
|
||||
|
||||
def run_boundary_tests(self) -> Dict[str, Dict[str, bool]]:
|
||||
"""
|
||||
运行边界条件测试用例
|
||||
|
||||
Returns:
|
||||
测试结果字典
|
||||
"""
|
||||
self.logger.info("="*60)
|
||||
self.logger.info("运行边界条件测试用例")
|
||||
self.logger.info("="*60)
|
||||
|
||||
results = {}
|
||||
|
||||
# 测试用户名长度边界
|
||||
results["用户名长度边界"] = self.boundary_test_cases.test_user_name_length()
|
||||
|
||||
# 测试页面大小边界
|
||||
results["页面大小边界"] = self.boundary_test_cases.test_page_size_boundaries()
|
||||
|
||||
return results
|
||||
|
||||
def run_exception_tests(self) -> Dict[str, Dict[str, bool]]:
|
||||
"""
|
||||
运行异常场景测试用例
|
||||
|
||||
Returns:
|
||||
测试结果字典
|
||||
"""
|
||||
self.logger.info("="*60)
|
||||
self.logger.info("运行异常场景测试用例")
|
||||
self.logger.info("="*60)
|
||||
|
||||
results = {}
|
||||
|
||||
# 测试无效凭据
|
||||
results["无效凭据"] = self.exception_test_cases.test_invalid_credentials()
|
||||
|
||||
# 测试缺少必填字段
|
||||
results["缺少必填字段"] = self.exception_test_cases.test_missing_required_fields()
|
||||
|
||||
# 测试未授权访问
|
||||
results["未授权访问"] = self.exception_test_cases.test_unauthorized_access()
|
||||
|
||||
# 测试无效HTTP方法
|
||||
results["无效HTTP方法"] = self.exception_test_cases.test_invalid_http_methods()
|
||||
|
||||
return results
|
||||
|
||||
def run_all_tests(self) -> Dict[str, Any]:
|
||||
"""
|
||||
运行所有测试用例
|
||||
|
||||
Returns:
|
||||
测试结果摘要
|
||||
"""
|
||||
self.start_time = time.time()
|
||||
|
||||
self.logger.info("="*60)
|
||||
self.logger.info("开始运行所有测试用例(增强版)")
|
||||
self.logger.info("="*60)
|
||||
|
||||
# 1. 基础测试
|
||||
basic_results = self.run_basic_tests()
|
||||
for test_name, passed in basic_results.items():
|
||||
full_test_name = f"基础测试 - {test_name}"
|
||||
self._record_test_result(full_test_name, passed)
|
||||
|
||||
# 2. 参数化测试
|
||||
param_results = self.run_parameterized_tests()
|
||||
for category, results in param_results.items():
|
||||
for test_name, passed in results.items():
|
||||
full_test_name = f"参数化测试 - {category} - {test_name}"
|
||||
self._record_test_result(full_test_name, passed)
|
||||
|
||||
# 3. 边界条件测试
|
||||
boundary_results = self.run_boundary_tests()
|
||||
for category, results in boundary_results.items():
|
||||
for test_name, passed in results.items():
|
||||
full_test_name = f"边界条件测试 - {category} - {test_name}"
|
||||
self._record_test_result(full_test_name, passed)
|
||||
|
||||
# 4. 异常场景测试
|
||||
exception_results = self.run_exception_tests()
|
||||
for category, results in exception_results.items():
|
||||
for test_name, passed in results.items():
|
||||
full_test_name = f"异常场景测试 - {category} - {test_name}"
|
||||
self._record_test_result(full_test_name, passed)
|
||||
|
||||
# 计算测试摘要
|
||||
total_time = (time.time() - self.start_time) * 1000
|
||||
total = len(self.test_results)
|
||||
passed = sum(1 for r in self.test_results if r.success)
|
||||
failed = total - passed
|
||||
skipped = 0
|
||||
pass_rate = (passed / total * 100) if total > 0 else 0
|
||||
|
||||
summary = TestSummary(
|
||||
total=total,
|
||||
passed=passed,
|
||||
failed=failed,
|
||||
skipped=skipped,
|
||||
pass_rate=pass_rate,
|
||||
total_time=total_time,
|
||||
start_time=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(self.start_time)),
|
||||
end_time=time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
)
|
||||
|
||||
# 记录摘要
|
||||
self.logger.log_summary(total, passed, failed, skipped, total_time)
|
||||
|
||||
# 生成报告
|
||||
self._generate_reports(summary)
|
||||
|
||||
return {
|
||||
"total": total,
|
||||
"passed": passed,
|
||||
"failed": failed,
|
||||
"skipped": skipped,
|
||||
"pass_rate": pass_rate,
|
||||
"total_time": total_time
|
||||
}
|
||||
|
||||
def _record_test_result(self, test_name: str, passed: bool, response_time: float = 0) -> None:
|
||||
"""
|
||||
记录测试结果
|
||||
|
||||
Args:
|
||||
test_name: 测试名称
|
||||
passed: 是否通过
|
||||
response_time: 响应时间
|
||||
"""
|
||||
test_result = ReportTestResult(
|
||||
test_name=test_name,
|
||||
test_type="API",
|
||||
url=config.api_base_url,
|
||||
method="N/A",
|
||||
status_code=200 if passed else 0,
|
||||
response_time=response_time,
|
||||
success=passed,
|
||||
error_message="" if passed else f"测试失败",
|
||||
request_data={},
|
||||
response_data={},
|
||||
timestamp=time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
)
|
||||
|
||||
self.test_results.append(test_result)
|
||||
|
||||
def _generate_reports(self, summary: TestSummary) -> None:
|
||||
"""
|
||||
生成测试报告
|
||||
|
||||
Args:
|
||||
summary: 测试摘要
|
||||
"""
|
||||
self.logger.info("生成测试报告...")
|
||||
|
||||
try:
|
||||
reports = self.report_generator.generate_all_reports(self.test_results, summary)
|
||||
|
||||
for format_type, path in reports.items():
|
||||
self.logger.info(f"✅ {format_type.upper()}报告已生成: {path}")
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"生成报告失败: {str(e)}")
|
||||
|
||||
def cleanup(self) -> None:
|
||||
"""清理资源"""
|
||||
self.tester.close()
|
||||
self.logger.info("测试完成,资源已清理")
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
print("="*60)
|
||||
print("前后端API交互自动化测试工具(增强版)")
|
||||
print("="*60)
|
||||
print()
|
||||
|
||||
# 显示配置信息
|
||||
print("配置信息:")
|
||||
print(f" API基础URL: {config.api_base_url}")
|
||||
print(f" 超时时间: {config.api_timeout}秒")
|
||||
print(f" 最大重试次数: {config.api_max_retries}")
|
||||
print(f" 报告输出目录: {config.report_output_dir}")
|
||||
print(f" 报告格式: {', '.join(config.report_formats)}")
|
||||
print()
|
||||
|
||||
# 创建测试运行器
|
||||
runner = EnhancedTestRunner()
|
||||
|
||||
try:
|
||||
# 运行所有测试
|
||||
results = runner.run_all_tests()
|
||||
|
||||
# 显示最终结果
|
||||
print()
|
||||
print("="*60)
|
||||
print("测试完成!")
|
||||
print("="*60)
|
||||
print(f"总计: {results['total']}")
|
||||
print(f"通过: {results['passed']}")
|
||||
print(f"失败: {results['failed']}")
|
||||
print(f"通过率: {results['pass_rate']:.2f}%")
|
||||
print(f"总耗时: {results['total_time']:.2f}ms")
|
||||
print("="*60)
|
||||
|
||||
# 返回退出码
|
||||
sys.exit(0 if results['failed'] == 0 else 1)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n\n测试被用户中断")
|
||||
sys.exit(130)
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n\n测试执行失败: {str(e)}")
|
||||
sys.exit(1)
|
||||
|
||||
finally:
|
||||
runner.cleanup()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user