# SSA 端到端测试脚本 (PowerShell) # 使用方法: .\tests\ssa-e2e-test.ps1 $ErrorActionPreference = "Stop" $BaseUrl = "http://localhost:3001/api/v1" Write-Host "========================================" -ForegroundColor Cyan Write-Host "SSA 智能统计分析 - 端到端测试" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan # Step 0: 检查 R 服务健康状态 Write-Host "`n[Step 0] 检查 R 服务健康状态..." -ForegroundColor Yellow try { $rHealth = Invoke-RestMethod -Uri "http://localhost:8082/health" -Method GET Write-Host "✅ R 服务状态: $($rHealth.status)" -ForegroundColor Green Write-Host " 版本: $($rHealth.version), DEV_MODE: $($rHealth.dev_mode)" -ForegroundColor Gray } catch { Write-Host "❌ R 服务不可用: $_" -ForegroundColor Red exit 1 } # Step 1: 登录获取 Token Write-Host "`n[Step 1] 登录获取认证 Token..." -ForegroundColor Yellow $loginBody = @{ phone = "13800000001" password = "123456" } | ConvertTo-Json try { $loginResult = Invoke-RestMethod -Uri "$BaseUrl/auth/login/password" ` -Method POST ` -ContentType "application/json" ` -Body $loginBody $token = $loginResult.data.tokens.accessToken Write-Host "✅ 登录成功,获取 Token" -ForegroundColor Green Write-Host " 用户: $($loginResult.data.user.name) ($($loginResult.data.user.role))" -ForegroundColor Gray } catch { Write-Host "❌ 登录失败: $_" -ForegroundColor Red Write-Host " 请确保 13800000001 / 123456 账户存在" -ForegroundColor Gray exit 1 } $headers = @{ "Authorization" = "Bearer $token" "Content-Type" = "application/json" } # Step 2: 检查 SSA 路由是否可用(通过 R 服务健康检查接口) Write-Host "`n[Step 2] 检查 SSA 后端路由..." -ForegroundColor Yellow try { $ssaHealth = Invoke-RestMethod -Uri "$BaseUrl/ssa/sessions/r-service/health" ` -Method GET ` -Headers $headers Write-Host "✅ SSA 路由已注册,R 服务状态: $($ssaHealth.r_service)" -ForegroundColor Green } catch { Write-Host "❌ SSA 路由不可用: $_" -ForegroundColor Red Write-Host " 请检查后端是否已重启并加载 SSA 模块" -ForegroundColor Gray exit 1 } # Step 3: 创建分析会话 Write-Host "`n[Step 3] 创建 SSA 分析会话..." -ForegroundColor Yellow try { $session = Invoke-RestMethod -Uri "$BaseUrl/ssa/sessions" ` -Method POST ` -Headers $headers ` -Body "{}" $sessionId = $session.id Write-Host "✅ 会话创建成功" -ForegroundColor Green Write-Host " 会话 ID: $sessionId" -ForegroundColor Gray } catch { Write-Host "❌ 创建会话失败: $_" -ForegroundColor Red exit 1 } # Step 4: 上传测试数据 Write-Host "`n[Step 4] 上传测试 CSV 文件..." -ForegroundColor Yellow $testFile = "..\r-statistics-service\tests\fixtures\sample_t_test.csv" if (-not (Test-Path $testFile)) { Write-Host "❌ 测试文件不存在: $testFile" -ForegroundColor Red exit 1 } try { # 使用 multipart/form-data 上传 $fileBytes = [System.IO.File]::ReadAllBytes((Resolve-Path $testFile)) $fileContent = [System.Text.Encoding]::GetEncoding("iso-8859-1").GetString($fileBytes) $boundary = [System.Guid]::NewGuid().ToString() $LF = "`r`n" $bodyLines = @( "--$boundary", "Content-Disposition: form-data; name=`"file`"; filename=`"sample_t_test.csv`"", "Content-Type: text/csv", "", $fileContent, "--$boundary--" ) -join $LF $uploadHeaders = @{ "Authorization" = "Bearer $token" "Content-Type" = "multipart/form-data; boundary=$boundary" } $uploadResult = Invoke-RestMethod -Uri "$BaseUrl/ssa/sessions/$sessionId/upload" ` -Method POST ` -Headers $uploadHeaders ` -Body $bodyLines Write-Host "✅ 文件上传成功" -ForegroundColor Green Write-Host " 存储 Key: $($uploadResult.storageKey)" -ForegroundColor Gray } catch { Write-Host "⚠️ 文件上传失败(可能需要检查 multipart 处理): $_" -ForegroundColor Yellow Write-Host " 继续使用 inline 数据模式测试..." -ForegroundColor Gray } # Step 5: 执行分析(使用 inline 数据) Write-Host "`n[Step 5] 执行 T 检验分析..." -ForegroundColor Yellow $executePlan = @{ plan = @{ tool_code = "ST_T_TEST_IND" params = @{ group_var = "group" value_var = "score" } guardrails = @{ check_normality = $true } data_source = @{ type = "inline" data = @{ group = @("A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "B", "B") score = @(23, 25, 27, 22, 24, 26, 21, 28, 30, 32, 28, 31, 29, 33, 27, 35) } } } } | ConvertTo-Json -Depth 10 try { $result = Invoke-RestMethod -Uri "$BaseUrl/ssa/sessions/$sessionId/execute" ` -Method POST ` -Headers $headers ` -Body $executePlan Write-Host "✅ API 调用成功!" -ForegroundColor Green Write-Host "" Write-Host "========== 分析结果 ==========" -ForegroundColor Cyan Write-Host "状态: $($result.status)" -ForegroundColor White # 如果是错误,打印错误信息 if ($result.status -eq "error") { Write-Host "错误码: $($result.error_code)" -ForegroundColor Red Write-Host "错误信息: $($result.message)" -ForegroundColor Red Write-Host "用户提示: $($result.user_hint)" -ForegroundColor Yellow } Write-Host "方法: $($result.results.method)" -ForegroundColor White Write-Host "t 统计量: $($result.results.statistic)" -ForegroundColor White Write-Host "自由度: $($result.results.df)" -ForegroundColor White Write-Host "p 值: $($result.results.p_value) ($($result.results.p_value_fmt))" -ForegroundColor White if ($result.results.group_stats) { Write-Host "" Write-Host "组统计:" -ForegroundColor White foreach ($g in $result.results.group_stats) { Write-Host " - 组 $($g.group): n=$($g.n), 均值=$($g.mean), SD=$([math]::Round($g.sd, 2))" -ForegroundColor Gray } } if ($result.plots -and $result.plots.Count -gt 0) { Write-Host "" Write-Host "📊 包含 $($result.plots.Count) 个图表(Base64 编码)" -ForegroundColor Gray } Write-Host "================================" -ForegroundColor Cyan } catch { Write-Host "❌ 分析执行失败: $_" -ForegroundColor Red exit 1 } Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "🎉 SSA 端到端测试完成!" -ForegroundColor Green Write-Host "========================================" -ForegroundColor Cyan