#!/bin/bash """ 完整的E2E和UAT测试运行脚本 自动启动服务器、运行测试、生成报告、清理环境 """ set -e # 遇到错误立即退出 # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 项目根目录 PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)" SCRIPTS_DIR="$PROJECT_ROOT/scripts" LOG_DIR="$PROJECT_ROOT/test_logs" REPORT_DIR="$PROJECT_ROOT/test_reports" # 创建必要的目录 mkdir -p "$LOG_DIR" mkdir -p "$REPORT_DIR" # 日志文件 TIMESTAMP=$(date +"%Y%m%d_%H%M%S") LOG_FILE="$LOG_DIR/e2e_uat_$TIMESTAMP.log" echo -e "${BLUE}========================================${NC}" echo -e "${BLUE} E2E和UAT自动化测试系统${NC}" echo -e "${BLUE}========================================${NC}" echo "" # 函数:打印带时间戳的日志 log() { echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$LOG_FILE" } # 函数:打印错误 error() { echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE" } # 函数:打印警告 warn() { echo -e "${YELLOW}[WARN]${NC} $1" | tee -a "$LOG_FILE" } # 函数:检查Python依赖 check_python_dependencies() { log "检查Python依赖..." if ! command -v python3 &> /dev/null; then error "Python3未安装" exit 1 fi log "检查Playwright..." if ! python3 -c "import playwright" 2>/dev/null; then error "Playwright未安装,请运行: pip install playwright" exit 1 fi log "检查httpx..." if ! python3 -c "import httpx" 2>/dev/null; then error "httpx未安装,请运行: pip install httpx" exit 1 fi log "✅ 所有Python依赖检查通过" } # 函数:启动测试服务器 start_servers() { log "启动测试服务器..." cd "$PROJECT_ROOT" # 启动后端服务器 log "启动后端服务器..." nohup java -jar novalon-manage-api/manage-app/target/manage-app-1.0.0.jar > "$LOG_DIR/backend_$TIMESTAMP.log" 2>&1 & BACKEND_PID=$! echo $BACKEND_PID > "$LOG_DIR/backend.pid" # 等待后端启动 log "等待后端服务器就绪..." for i in {1..30}; do if curl -s http://localhost:8084/actuator/health > /dev/null 2>&1; then log "✅ 后端服务器启动成功 (PID: $BACKEND_PID)" break fi sleep 2 done if ! curl -s http://localhost:8084/actuator/health > /dev/null 2>&1; then error "后端服务器启动失败" return 1 fi # 启动前端服务器 log "启动前端服务器..." cd novalon-manage-web nohup npm run dev > "$LOG_DIR/frontend_$TIMESTAMP.log" 2>&1 & FRONTEND_PID=$! echo $FRONTEND_PID > "$LOG_DIR/frontend.pid" cd "$PROJECT_ROOT" # 等待前端启动 log "等待前端服务器就绪..." for i in {1..30}; do if curl -s http://localhost:3003 > /dev/null 2>&1; then log "✅ 前端服务器启动成功 (PID: $FRONTEND_PID)" break fi sleep 2 done if ! curl -s http://localhost:3003 > /dev/null 2>&1; then error "前端服务器启动失败" return 1 fi log "✅ 所有服务器启动完成" return 0 } # 函数:停止测试服务器 stop_servers() { log "停止测试服务器..." # 停止后端服务器 if [ -f "$LOG_DIR/backend.pid" ]; then BACKEND_PID=$(cat "$LOG_DIR/backend.pid") if ps -p $BACKEND_PID > /dev/null; then log "停止后端服务器 (PID: $BACKEND_PID)..." kill $BACKEND_PID log "✅ 后端服务器已停止" fi rm -f "$LOG_DIR/backend.pid" fi # 停止前端服务器 if [ -f "$LOG_DIR/frontend.pid" ]; then FRONTEND_PID=$(cat "$LOG_DIR/frontend.pid") if ps -p $FRONTEND_PID > /dev/null; then log "停止前端服务器 (PID: $FRONTEND_PID)..." kill $FRONTEND_PID log "✅ 前端服务器已停止" fi rm -f "$LOG_DIR/frontend.pid" fi log "✅ 所有服务器已停止" } # 函数:运行E2E测试 run_e2e_tests() { log "开始运行E2E测试..." cd "$PROJECT_ROOT" # 运行Python Playwright测试 log "执行E2E和UAT自动化测试..." python3 "$SCRIPTS_DIR/e2e_uat_automation.py" \ --base-url "http://localhost:3003" \ --api-url "http://localhost:8084" \ --timeout 30000 TEST_EXIT_CODE=$? if [ $TEST_EXIT_CODE -eq 0 ]; then log "✅ E2E和UAT测试全部通过" else error "❌ E2E和UAT测试存在失败 (退出码: $TEST_EXIT_CODE)" fi return $TEST_EXIT_CODE } # 函数:清理测试环境 cleanup() { log "清理测试环境..." # 停止服务器 stop_servers # 清理临时文件 log "清理临时文件..." # 可以添加其他清理逻辑 log "✅ 测试环境清理完成" } # 函数:生成测试总结 generate_summary() { log "生成测试总结..." SUMMARY_FILE="$REPORT_DIR/summary_$TIMESTAMP.txt" cat > "$SUMMARY_FILE" << EOF ======================================== E2E和UAT测试总结 ======================================== 测试时间: $(date '+%Y-%m-%d %H:%M:%S') 测试日志: $LOG_FILE 测试报告目录: $REPORT_DIR 测试结果: EOF # 检查测试报告 if [ -f "$REPORT_DIR/E2E_UAT_Report_*.txt" ]; then LATEST_REPORT=$(ls -t "$REPORT_DIR/E2E_UAT_Report_*.txt" | head -1) echo "" >> "$SUMMARY_FILE" echo "详细测试报告: $LATEST_REPORT" >> "$SUMMARY_FILE" echo "" >> "$SUMMARY_FILE" cat "$LATEST_REPORT" >> "$SUMMARY_FILE" fi echo "" >> "$SUMMARY_FILE" echo "========================================" >> "$SUMMARY_FILE" log "✅ 测试总结已生成: $SUMMARY_FILE" } # 主函数 main() { # 解析命令行参数 ACTION=${1:-"run"} case $ACTION in "start") log "启动测试服务器" check_python_dependencies start_servers ;; "stop") log "停止测试服务器" stop_servers ;; "test") log "运行E2E测试" check_python_dependencies run_e2e_tests ;; "run") log "执行完整测试流程" check_python_dependencies start_servers sleep 10 # 等待服务器完全启动 run_e2e_tests TEST_EXIT_CODE=$? generate_summary cleanup exit $TEST_EXIT_CODE ;; "cleanup") log "清理测试环境" cleanup ;; "report") log "生成测试报告" generate_summary ;; *) echo "用法: $0 {start|stop|test|run|cleanup|report}" echo "" echo "命令:" echo " start - 启动测试服务器" echo " stop - 停止测试服务器" echo " test - 运行E2E测试" echo " run - 执行完整测试流程(启动服务器+运行测试+清理)" echo " cleanup - 清理测试环境" echo " report - 生成测试报告" echo "" echo "示例:" echo " $0 run # 执行完整测试流程" echo " $0 start # 仅启动服务器" echo " $0 test # 仅运行测试" echo " $0 stop # 仅停止服务器" exit 1 ;; esac } # 捕获退出信号,确保清理 trap cleanup EXIT INT TERM # 执行主函数 main "$@"