478 lines
17 KiB
Go
478 lines
17 KiB
Go
# 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 |