新增e2e测试脚本,修复部分问题
This commit was merged in pull request #51.
This commit is contained in:
@@ -0,0 +1,281 @@
|
||||
# Gym Manage - 全量测试编排脚本
|
||||
# 用法: .\run-all-tests.ps1 [-Backend] [-Admin] [-Member] [-Coach] [-All] [-ReportOnly] [-SkipBuild]
|
||||
# 默认: -All
|
||||
|
||||
param(
|
||||
[switch]$Backend,
|
||||
[switch]$Admin,
|
||||
[switch]$Member,
|
||||
[switch]$Coach,
|
||||
[switch]$All,
|
||||
[switch]$ReportOnly,
|
||||
[switch]$SkipBuild
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$RootDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
|
||||
# 颜色输出
|
||||
function Write-Step { Write-Host "`n========================================" -ForegroundColor Cyan; Write-Host " $args" -ForegroundColor Cyan; Write-Host "========================================" -ForegroundColor Cyan }
|
||||
function Write-Success { Write-Host " [OK] $args" -ForegroundColor Green }
|
||||
function Write-Fail { Write-Host " [FAIL] $args" -ForegroundColor Red }
|
||||
function Write-Warn { Write-Host " [WARN] $args" -ForegroundColor Yellow }
|
||||
function Write-Info { Write-Host " [INFO] $args" -ForegroundColor Gray }
|
||||
|
||||
# 结果收集
|
||||
$Results = @{}
|
||||
$StartTime = Get-Date
|
||||
|
||||
# =============================================
|
||||
# 阶段0: 环境检查
|
||||
# =============================================
|
||||
Write-Step "阶段0: 环境检查"
|
||||
|
||||
# 检查 Java
|
||||
try {
|
||||
$javaVer = java -version 2>&1 | Select-Object -First 1
|
||||
Write-Success "Java available: $javaVer"
|
||||
} catch {
|
||||
Write-Fail "Java not found. Please install JDK 21."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 检查 Node
|
||||
try {
|
||||
$nodeVer = node -v
|
||||
Write-Success "Node available: $nodeVer"
|
||||
} catch {
|
||||
Write-Fail "Node not found. Please install Node.js."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 检查 Maven Wrapper
|
||||
$MvnCmd = if (Test-Path "$RootDir\gym-manage-api\mvnw.cmd") { "$RootDir\gym-manage-api\mvnw.cmd" } else { "mvn" }
|
||||
|
||||
# 检查微信开发者工具CLI(端口45869)
|
||||
$wcCliPort = 45869
|
||||
try {
|
||||
$wcCheck = Invoke-WebRequest -Uri "http://127.0.0.1:$wcCliPort" -TimeoutSec 3 -ErrorAction SilentlyContinue
|
||||
if ($wcCheck.StatusCode -eq 200 -or $wcCheck.StatusCode -eq 404) {
|
||||
Write-Success "WeChat DevTools CLI available on port $wcCliPort"
|
||||
}
|
||||
} catch {
|
||||
Write-Warn "WeChat DevTools CLI not detected on port $wcCliPort. MiniTest tests will be skipped."
|
||||
}
|
||||
|
||||
# =============================================
|
||||
# 阶段1: 启动后端服务
|
||||
# =============================================
|
||||
Write-Step "阶段1: 启动后端服务"
|
||||
|
||||
$BackendPort = 8084
|
||||
$BackendHealthUrl = "http://localhost:$BackendPort/actuator/health"
|
||||
|
||||
function Test-BackendHealth {
|
||||
try {
|
||||
$r = Invoke-WebRequest -Uri $BackendHealthUrl -TimeoutSec 5 -ErrorAction SilentlyContinue
|
||||
return ($r.StatusCode -eq 200)
|
||||
} catch { return $false }
|
||||
}
|
||||
|
||||
$backendWasRunning = Test-BackendHealth
|
||||
if ($backendWasRunning) {
|
||||
Write-Success "Backend already running on port $BackendPort"
|
||||
} else {
|
||||
Write-Info "Starting backend with Maven..."
|
||||
|
||||
$backendJob = Start-Job -ScriptBlock {
|
||||
param($mvnCmd, $apiDir)
|
||||
Set-Location $apiDir
|
||||
& $mvnCmd spring-boot:run -Dspring-boot.run.profiles=test 2>&1
|
||||
} -ArgumentList $MvnCmd, "$RootDir\gym-manage-api\manage-app"
|
||||
|
||||
# 等待后端就绪 (最多90秒)
|
||||
$retries = 0
|
||||
while (-not (Test-BackendHealth) -and $retries -lt 90) {
|
||||
$retries++
|
||||
Write-Progress -Activity "Waiting for backend..." -PercentComplete (($retries / 90) * 100) -Status "$retries/90s"
|
||||
Start-Sleep -Seconds 1
|
||||
}
|
||||
Write-Progress -Activity "Waiting for backend..." -Completed
|
||||
|
||||
if (Test-BackendHealth) {
|
||||
Write-Success "Backend started successfully ($retries seconds)"
|
||||
} else {
|
||||
Write-Fail "Backend failed to start within 90 seconds"
|
||||
Stop-Job $backendJob
|
||||
Remove-Job $backendJob
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# =============================================
|
||||
# 阶段2: 执行测试套件
|
||||
# =============================================
|
||||
|
||||
function Invoke-TestStage {
|
||||
param(
|
||||
[string]$Name,
|
||||
[string]$WorkingDir,
|
||||
[string]$Command,
|
||||
[bool]$Enabled = $true
|
||||
)
|
||||
|
||||
if (-not $Enabled) {
|
||||
Write-Warn "Skipping $Name (not requested)"
|
||||
$Results[$Name] = "SKIPPED"
|
||||
return
|
||||
}
|
||||
|
||||
Write-Step "Running: $Name"
|
||||
Write-Info "Working directory: $WorkingDir"
|
||||
Write-Info "Command: $Command"
|
||||
|
||||
try {
|
||||
Push-Location $WorkingDir
|
||||
$sw = [System.Diagnostics.Stopwatch]::StartNew()
|
||||
Invoke-Expression $Command
|
||||
$sw.Stop()
|
||||
Write-Success "$Name completed in $([math]::Round($sw.Elapsed.TotalSeconds, 1))s"
|
||||
$Results[$Name] = "PASS ($([math]::Round($sw.Elapsed.TotalSeconds, 1))s)"
|
||||
Pop-Location
|
||||
} catch {
|
||||
Write-Fail "$Name failed: $_"
|
||||
$Results[$Name] = "FAIL"
|
||||
Pop-Location
|
||||
}
|
||||
}
|
||||
|
||||
# 决定执行哪些测试
|
||||
$runBackend = $All -or $Backend
|
||||
$runAdmin = $All -or $Admin
|
||||
$runMember = $All -or $Member
|
||||
$runCoach = $All -or $Coach
|
||||
|
||||
if (-not ($Backend -or $Admin -or $Member -or $Coach)) { $runBackend = $runAdmin = $runMember = $runCoach = $true }
|
||||
|
||||
# 后端 API 契约测试
|
||||
Invoke-TestStage -Name "Backend-API-Contract" `
|
||||
-WorkingDir "$RootDir\gym-manage-api" `
|
||||
-Command "$MvnCmd test -pl manage-app -Dtest='cn.novalon.gym.manage.app.contract.*Test' -DfailIfNoTests=false" `
|
||||
-Enabled $runBackend
|
||||
|
||||
# Admin E2E: Smoke
|
||||
Invoke-TestStage -Name "Admin-E2E-Smoke" `
|
||||
-WorkingDir "$RootDir\gym-manage-web" `
|
||||
-Command "npx playwright test --project=smoke --reporter=list" `
|
||||
-Enabled $runAdmin
|
||||
|
||||
# Admin E2E: Journeys (需等待smoke完成)
|
||||
if ($runAdmin) {
|
||||
Invoke-TestStage -Name "Admin-E2E-Journeys" `
|
||||
-WorkingDir "$RootDir\gym-manage-web" `
|
||||
-Command "npx playwright test --project=journeys --reporter=list" `
|
||||
-Enabled $true
|
||||
}
|
||||
|
||||
# UniApp 会员端 MiniTest
|
||||
if ($runMember) {
|
||||
$memberTestDir = "$RootDir\gym-manage-uniapp"
|
||||
if (Test-Path "$memberTestDir\jest.e2e.config.js") {
|
||||
Invoke-TestStage -Name "UniApp-Member-MiniTest" `
|
||||
-WorkingDir $memberTestDir `
|
||||
-Command "npx jest --config jest.e2e.config.js --forceExit" `
|
||||
-Enabled $true
|
||||
} else {
|
||||
Write-Warn "Member MiniTest config not found, skipping"
|
||||
$Results["UniApp-Member-MiniTest"] = "SKIPPED (no config)"
|
||||
}
|
||||
}
|
||||
|
||||
# UniApp 教练端 MiniTest
|
||||
if ($runCoach) {
|
||||
$coachTestDir = "$RootDir\gym-manage-coach-uniapp"
|
||||
if (Test-Path "$coachTestDir\jest.e2e.config.js") {
|
||||
Invoke-TestStage -Name "UniApp-Coach-MiniTest" `
|
||||
-WorkingDir $coachTestDir `
|
||||
-Command "npx jest --config jest.e2e.config.js --forceExit" `
|
||||
-Enabled $true
|
||||
} else {
|
||||
Write-Warn "Coach MiniTest config not found, skipping"
|
||||
$Results["UniApp-Coach-MiniTest"] = "SKIPPED (no config)"
|
||||
}
|
||||
}
|
||||
|
||||
# =============================================
|
||||
# 阶段3: 汇总报告
|
||||
# =============================================
|
||||
Write-Step "阶段3: 测试汇总报告"
|
||||
|
||||
$EndTime = Get-Date
|
||||
$TotalTime = [math]::Round(($EndTime - $StartTime).TotalSeconds, 1)
|
||||
|
||||
$totalPass = 0
|
||||
$totalFail = 0
|
||||
$totalSkip = 0
|
||||
|
||||
Write-Host ""
|
||||
Write-Host " Test Results Summary" -ForegroundColor White
|
||||
Write-Host " $(('=' * 60))" -ForegroundColor DarkGray
|
||||
|
||||
foreach ($key in $Results.Keys | Sort-Object) {
|
||||
$val = $Results[$key]
|
||||
if ($val -like "PASS*") {
|
||||
Write-Host " [PASS] " -NoNewline -ForegroundColor Green
|
||||
Write-Host "$key : $val"
|
||||
$totalPass++
|
||||
} elseif ($val -like "FAIL*") {
|
||||
Write-Host " [FAIL] " -NoNewline -ForegroundColor Red
|
||||
Write-Host "$key : $val"
|
||||
$totalFail++
|
||||
} else {
|
||||
Write-Host " [SKIP] " -NoNewline -ForegroundColor Yellow
|
||||
Write-Host "$key : $val"
|
||||
$totalSkip++
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host " $(('=' * 60))" -ForegroundColor DarkGray
|
||||
Write-Host (" Total: {0} | Pass: {1} | Fail: {2} | Skip: {3} | Time: {4}s" -f ($totalPass + $totalFail + $totalSkip), $totalPass, $totalFail, $totalSkip, $TotalTime) -ForegroundColor White
|
||||
Write-Host ""
|
||||
|
||||
# 生成JSON报告
|
||||
$ReportPath = "$RootDir\test-results\summary-$(Get-Date -Format 'yyyyMMdd-HHmmss').json"
|
||||
$ReportDir = Split-Path $ReportPath -Parent
|
||||
if (-not (Test-Path $ReportDir)) { New-Item -ItemType Directory -Path $ReportDir -Force | Out-Null }
|
||||
|
||||
$Report = @{
|
||||
timestamp = (Get-Date -Format "yyyy-MM-ddTHH:mm:ss")
|
||||
totalTimeSeconds = $TotalTime
|
||||
results = $Results
|
||||
summary = @{
|
||||
total = $totalPass + $totalFail + $totalSkip
|
||||
pass = $totalPass
|
||||
fail = $totalFail
|
||||
skip = $totalSkip
|
||||
}
|
||||
}
|
||||
|
||||
$Report | ConvertTo-Json -Depth 3 | Out-File -FilePath $ReportPath -Encoding UTF8
|
||||
Write-Success "Report saved to: $ReportPath"
|
||||
|
||||
# =============================================
|
||||
# 阶段4: 清理
|
||||
# =============================================
|
||||
Write-Step "阶段4: 清理"
|
||||
|
||||
# 如果后端是我们启动的,停止它
|
||||
if (-not $backendWasRunning -and $backendJob) {
|
||||
Write-Info "Stopping backend..."
|
||||
Stop-Job $backendJob -ErrorAction SilentlyContinue
|
||||
Remove-Job $backendJob -ErrorAction SilentlyContinue
|
||||
Write-Success "Backend stopped"
|
||||
}
|
||||
|
||||
if ($totalFail -gt 0) {
|
||||
Write-Host "`n Some tests FAILED. Check reports for details." -ForegroundColor Red
|
||||
exit 1
|
||||
} else {
|
||||
Write-Host "`n All tests PASSED!" -ForegroundColor Green
|
||||
exit 0
|
||||
}
|
||||
Reference in New Issue
Block a user