# nl-video-api 系统测试脚本 # 执行完整的功能测试、性能测试和错误处理测试 param( [string]$BaseUrl = "http://localhost:8000", [string]$TestMode = "all" # all, function, performance, error ) # 测试结果统计 $TestResults = @{ Total = 0 Passed = 0 Failed = 0 Errors = @() } # 颜色输出函数 function Write-ColorOutput { param( [string]$Message, [string]$Color = "White" ) switch ($Color) { "Green" { Write-Host $Message -ForegroundColor Green } "Red" { Write-Host $Message -ForegroundColor Red } "Yellow" { Write-Host $Message -ForegroundColor Yellow } "Blue" { Write-Host $Message -ForegroundColor Blue } "Cyan" { Write-Host $Message -ForegroundColor Cyan } default { Write-Host $Message } } } # HTTP请求函数 function Invoke-ApiRequest { param( [string]$Method, [string]$Url, [hashtable]$Headers = @{}, [string]$Body = $null, [string]$TestName ) $TestResults.Total++ try { $params = @{ Uri = $Url Method = $Method Headers = $Headers ContentType = "application/json" } if ($Body) { $params.Body = $Body } $startTime = Get-Date $response = Invoke-RestMethod @params $endTime = Get-Date $duration = ($endTime - $startTime).TotalMilliseconds if ($response.code -eq 0) { Write-ColorOutput "✓ $TestName - 通过 (${duration}ms)" "Green" $TestResults.Passed++ return @{ Success = $true; Response = $response; Duration = $duration } } else { Write-ColorOutput "✗ $TestName - 失败: $($response.message)" "Red" $TestResults.Failed++ $TestResults.Errors += "$TestName - $($response.message)" return @{ Success = $false; Response = $response; Duration = $duration } } } catch { Write-ColorOutput "✗ $TestName - 错误: $($_.Exception.Message)" "Red" $TestResults.Failed++ $TestResults.Errors += "$TestName - $($_.Exception.Message)" return @{ Success = $false; Error = $_.Exception.Message; Duration = 0 } } } # 获取管理员Token function Get-AdminToken { Write-ColorOutput "`n=== 获取管理员Token ===" "Blue" $loginData = @{ username = "admin" password = "123456" } | ConvertTo-Json $result = Invoke-ApiRequest -Method "POST" -Url "$BaseUrl/api/v1/auth/admin/login" -Body $loginData -TestName "管理员登录" if ($result.Success) { return $result.Response.data.token } return $null } # 功能测试 function Test-Functions { Write-ColorOutput "`n=== 开始功能测试 ===" "Cyan" # 获取管理员Token $adminToken = Get-AdminToken if (-not $adminToken) { Write-ColorOutput "无法获取管理员Token,跳过需要认证的测试" "Yellow" return } $authHeaders = @{ "Authorization" = "Bearer $adminToken" } # 测试影片管理 Write-ColorOutput "`n--- 影片管理测试 ---" "Blue" # 获取影片列表 Invoke-ApiRequest -Method "GET" -Url "$BaseUrl/api/v1/movies?page=1&page_size=10" -TestName "获取影片列表" # 创建影片 $movieData = @{ title = "测试电影_$(Get-Date -Format 'yyyyMMddHHmmss')" type = 1 category_id = 1 year = 2024 country = "中国" director = "测试导演" actors = "测试演员" description = "这是一部测试电影" duration = 120 status = 1 } | ConvertTo-Json $createResult = Invoke-ApiRequest -Method "POST" -Url "$BaseUrl/api/v1/admin/movies" -Headers $authHeaders -Body $movieData -TestName "创建影片" if ($createResult.Success) { $movieId = $createResult.Response.data.id # 获取影片详情 Invoke-ApiRequest -Method "GET" -Url "$BaseUrl/api/v1/movies/$movieId" -TestName "获取影片详情" # 更新影片 $updateData = @{ title = "更新后的测试电影" description = "更新后的描述" } | ConvertTo-Json Invoke-ApiRequest -Method "PUT" -Url "$BaseUrl/api/v1/admin/movies/$movieId" -Headers $authHeaders -Body $updateData -TestName "更新影片" # 删除影片 Invoke-ApiRequest -Method "DELETE" -Url "$BaseUrl/api/v1/admin/movies/$movieId" -Headers $authHeaders -TestName "删除影片" } # 测试用户管理 Write-ColorOutput "`n--- 用户管理测试 ---" "Blue" # 获取用户列表 Invoke-ApiRequest -Method "GET" -Url "$BaseUrl/api/v1/admin/users?page=1&page_size=10" -Headers $authHeaders -TestName "获取用户列表" # 创建用户 $userData = @{ username = "testuser_$(Get-Date -Format 'yyyyMMddHHmmss')" phone = "138$(Get-Random -Minimum 10000000 -Maximum 99999999)" email = "test$(Get-Date -Format 'yyyyMMddHHmmss')@example.com" password = "123456" nickname = "测试用户" gender = 1 status = 1 } | ConvertTo-Json $userResult = Invoke-ApiRequest -Method "POST" -Url "$BaseUrl/api/v1/admin/users" -Headers $authHeaders -Body $userData -TestName "创建用户" if ($userResult.Success) { $userId = $userResult.Response.data.id # 获取用户详情 Invoke-ApiRequest -Method "GET" -Url "$BaseUrl/api/v1/admin/users/$userId" -Headers $authHeaders -TestName "获取用户详情" # 更新用户VIP $vipData = @{ vip_level = 2 days = 30 } | ConvertTo-Json Invoke-ApiRequest -Method "POST" -Url "$BaseUrl/api/v1/admin/users/$userId/vip" -Headers $authHeaders -Body $vipData -TestName "升级用户VIP" # 更新用户余额 $balanceData = @{ amount = 100.50 type = 1 remark = "测试充值" } | ConvertTo-Json Invoke-ApiRequest -Method "PUT" -Url "$BaseUrl/api/v1/admin/users/$userId/balance" -Headers $authHeaders -Body $balanceData -TestName "更新用户余额" } # 测试权限管理 Write-ColorOutput "`n--- 权限管理测试 ---" "Blue" # 获取角色列表 Invoke-ApiRequest -Method "GET" -Url "$BaseUrl/api/v1/admin/roles" -Headers $authHeaders -TestName "获取角色列表" # 获取权限列表 Invoke-ApiRequest -Method "GET" -Url "$BaseUrl/api/v1/admin/permissions" -Headers $authHeaders -TestName "获取权限列表" # 获取权限树 Invoke-ApiRequest -Method "GET" -Url "$BaseUrl/api/v1/admin/permissions/tree" -Headers $authHeaders -TestName "获取权限树" } # 性能测试 function Test-Performance { Write-ColorOutput "`n=== 开始性能测试 ===" "Cyan" $concurrentRequests = 10 $testDuration = 30 # 秒 $requestCount = 0 $successCount = 0 $failureCount = 0 $responseTimes = @() Write-ColorOutput "并发请求数: $concurrentRequests" "Yellow" Write-ColorOutput "测试持续时间: $testDuration 秒" "Yellow" $startTime = Get-Date $endTime = $startTime.AddSeconds($testDuration) # 并发测试 $jobs = @() for ($i = 1; $i -le $concurrentRequests; $i++) { $job = Start-Job -ScriptBlock { param($BaseUrl, $EndTime) $results = @{ RequestCount = 0 SuccessCount = 0 FailureCount = 0 ResponseTimes = @() } while ((Get-Date) -lt $EndTime) { try { $startRequest = Get-Date $response = Invoke-RestMethod -Uri "$BaseUrl/api/v1/movies?page=1&page_size=10" -Method GET $endRequest = Get-Date $duration = ($endRequest - $startRequest).TotalMilliseconds $results.RequestCount++ $results.ResponseTimes += $duration if ($response.code -eq 0) { $results.SuccessCount++ } else { $results.FailureCount++ } } catch { $results.RequestCount++ $results.FailureCount++ } Start-Sleep -Milliseconds 100 } return $results } -ArgumentList $BaseUrl, $endTime $jobs += $job } # 等待所有任务完成 Write-ColorOutput "等待性能测试完成..." "Yellow" $allResults = $jobs | Wait-Job | Receive-Job $jobs | Remove-Job # 汇总结果 $totalRequests = ($allResults | Measure-Object -Property RequestCount -Sum).Sum $totalSuccess = ($allResults | Measure-Object -Property SuccessCount -Sum).Sum $totalFailure = ($allResults | Measure-Object -Property FailureCount -Sum).Sum $allResponseTimes = $allResults | ForEach-Object { $_.ResponseTimes } | Where-Object { $_ -ne $null } if ($allResponseTimes.Count -gt 0) { $avgResponseTime = ($allResponseTimes | Measure-Object -Average).Average $minResponseTime = ($allResponseTimes | Measure-Object -Minimum).Minimum $maxResponseTime = ($allResponseTimes | Measure-Object -Maximum).Maximum $qps = [math]::Round($totalRequests / $testDuration, 2) $successRate = [math]::Round(($totalSuccess / $totalRequests) * 100, 2) Write-ColorOutput "`n--- 性能测试结果 ---" "Blue" Write-ColorOutput "总请求数: $totalRequests" "White" Write-ColorOutput "成功请求: $totalSuccess" "Green" Write-ColorOutput "失败请求: $totalFailure" "Red" Write-ColorOutput "成功率: $successRate%" "White" Write-ColorOutput "QPS: $qps" "White" Write-ColorOutput "平均响应时间: $([math]::Round($avgResponseTime, 2))ms" "White" Write-ColorOutput "最小响应时间: $([math]::Round($minResponseTime, 2))ms" "White" Write-ColorOutput "最大响应时间: $([math]::Round($maxResponseTime, 2))ms" "White" # 性能评估 if ($avgResponseTime -lt 200) { Write-ColorOutput "性能评估: 优秀" "Green" } elseif ($avgResponseTime -lt 500) { Write-ColorOutput "性能评估: 良好" "Yellow" } else { Write-ColorOutput "性能评估: 需要优化" "Red" } } } # 错误处理测试 function Test-ErrorHandling { Write-ColorOutput "`n=== 开始错误处理测试 ===" "Cyan" # 测试无效的API端点 Write-ColorOutput "`n--- 无效端点测试 ---" "Blue" try { Invoke-RestMethod -Uri "$BaseUrl/api/v1/invalid-endpoint" -Method GET Write-ColorOutput "✗ 无效端点测试 - 应该返回404错误" "Red" } catch { if ($_.Exception.Response.StatusCode -eq 404) { Write-ColorOutput "✓ 无效端点测试 - 正确返回404错误" "Green" } else { Write-ColorOutput "✗ 无效端点测试 - 返回了意外的错误: $($_.Exception.Message)" "Red" } } # 测试无效的请求参数 Write-ColorOutput "`n--- 无效参数测试 ---" "Blue" $invalidData = @{ invalid_field = "invalid_value" } | ConvertTo-Json try { $response = Invoke-RestMethod -Uri "$BaseUrl/api/v1/auth/admin/login" -Method POST -Body $invalidData -ContentType "application/json" if ($response.code -ne 0) { Write-ColorOutput "✓ 无效参数测试 - 正确返回参数错误" "Green" } else { Write-ColorOutput "✗ 无效参数测试 - 应该返回参数错误" "Red" } } catch { Write-ColorOutput "✓ 无效参数测试 - 正确处理了无效参数" "Green" } # 测试未授权访问 Write-ColorOutput "`n--- 未授权访问测试 ---" "Blue" try { $response = Invoke-RestMethod -Uri "$BaseUrl/api/v1/admin/users" -Method GET Write-ColorOutput "✗ 未授权访问测试 - 应该返回认证错误" "Red" } catch { if ($_.Exception.Response.StatusCode -eq 401) { Write-ColorOutput "✓ 未授权访问测试 - 正确返回401错误" "Green" } else { Write-ColorOutput "✗ 未授权访问测试 - 返回了意外的错误: $($_.Exception.Message)" "Red" } } # 测试SQL注入防护 Write-ColorOutput "`n--- SQL注入防护测试 ---" "Blue" $sqlInjectionData = @{ username = "admin'; DROP TABLE users; --" password = "123456" } | ConvertTo-Json try { $response = Invoke-RestMethod -Uri "$BaseUrl/api/v1/auth/admin/login" -Method POST -Body $sqlInjectionData -ContentType "application/json" if ($response.code -ne 0) { Write-ColorOutput "✓ SQL注入防护测试 - 正确阻止了SQL注入攻击" "Green" } else { Write-ColorOutput "✗ SQL注入防护测试 - 可能存在SQL注入漏洞" "Red" } } catch { Write-ColorOutput "✓ SQL注入防护测试 - 正确处理了恶意输入" "Green" } } # 生成测试报告 function Generate-TestReport { Write-ColorOutput "`n=== 测试报告 ===" "Cyan" Write-ColorOutput "测试时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" "White" Write-ColorOutput "总测试数: $($TestResults.Total)" "White" Write-ColorOutput "通过测试: $($TestResults.Passed)" "Green" Write-ColorOutput "失败测试: $($TestResults.Failed)" "Red" if ($TestResults.Total -gt 0) { $passRate = [math]::Round(($TestResults.Passed / $TestResults.Total) * 100, 2) Write-ColorOutput "通过率: $passRate%" "White" if ($passRate -ge 90) { Write-ColorOutput "测试评估: 优秀" "Green" } elseif ($passRate -ge 80) { Write-ColorOutput "测试评估: 良好" "Yellow" } else { Write-ColorOutput "测试评估: 需要改进" "Red" } } if ($TestResults.Errors.Count -gt 0) { Write-ColorOutput "`n失败的测试:" "Red" foreach ($error in $TestResults.Errors) { Write-ColorOutput " - $error" "Red" } } # 保存测试报告到文件 $reportPath = "test-report-$(Get-Date -Format 'yyyyMMdd-HHmmss').txt" $reportContent = @" nl-video-api 系统测试报告 ======================== 测试时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') 测试模式: $TestMode 基础URL: $BaseUrl 测试结果统计: - 总测试数: $($TestResults.Total) - 通过测试: $($TestResults.Passed) - 失败测试: $($TestResults.Failed) - 通过率: $([math]::Round(($TestResults.Passed / $TestResults.Total) * 100, 2))% 失败的测试: $($TestResults.Errors -join "`n") 测试建议: 1. 定期执行系统测试以确保功能稳定性 2. 关注性能指标,及时优化慢查询 3. 加强错误处理和异常情况的测试覆盖 4. 建议集成到CI/CD流程中自动执行 "@ $reportContent | Out-File -FilePath $reportPath -Encoding UTF8 Write-ColorOutput "`n测试报告已保存到: $reportPath" "Blue" } # 主函数 function Main { Write-ColorOutput "nl-video-api 系统测试工具" "Cyan" Write-ColorOutput "========================" "Cyan" Write-ColorOutput "基础URL: $BaseUrl" "White" Write-ColorOutput "测试模式: $TestMode" "White" Write-ColorOutput "开始时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" "White" # 检查服务器是否可访问 try { $response = Invoke-RestMethod -Uri "$BaseUrl/api/v1/movies?page=1&page_size=1" -Method GET -TimeoutSec 10 Write-ColorOutput "✓ 服务器连接正常" "Green" } catch { Write-ColorOutput "✗ 无法连接到服务器: $BaseUrl" "Red" Write-ColorOutput "请确保服务器正在运行并且URL正确" "Yellow" return } # 根据测试模式执行相应测试 switch ($TestMode.ToLower()) { "function" { Test-Functions } "performance" { Test-Performance } "error" { Test-ErrorHandling } "all" { Test-Functions Test-Performance Test-ErrorHandling } default { Write-ColorOutput "无效的测试模式: $TestMode" "Red" Write-ColorOutput "支持的模式: all, function, performance, error" "Yellow" return } } # 生成测试报告 Generate-TestReport Write-ColorOutput "`n测试完成!" "Green" } # 执行主函数 Main