执行Artillery.io测试时Diagnostics.ProcessStartInfo空值表达式错误排查
Socket.IO压测脚本执行报错排查
问题描述
使用Artillery.io编写Socket.IO压测YAML脚本,同时编写PowerShell脚本批量执行多场景测试。运行PowerShell脚本时出现「You cannot call a method on a null-valued expression」错误,但将生成的命令直接在控制台执行却正常,需排查问题原因。
压测YAML脚本
config: target: "http://localhost:3000/" phases: - duration: "{{duration}}" #//10 arrivalRate: 1 scenarios: - name: "Emit an event" engine: socketio flow: - loop: - emit: channel: "chat message" data: "{{data}}" - think: 1 count: "{{count}}"
PowerShell批量执行脚本
##ArtilleryIo platform test $no_of_requests = 1,2,25,100,500 $no_of_users = 1,2,10,100,500,1000 $content_length = 1,2,10,100,500,1000,10000 $args="" foreach($request in $no_of_requests){ foreach($len in $content_length) { foreach($user in $no_of_users) { try{ $integer_len = [int]$len $generatedData = -join ((65..90)+(97..122) | Get-Random -Count $integer_len | % {[char]$_}) $path = "artillery run --output test-run-report.json C:\Users\patryk\socket_io\server\tests\load-test.yml" $waitForExit = $true $psi = new-object "Diagnostics.ProcessStartInfo" $psi.FileName = "artillery" $integer_user = [int]$user $integer_req = [int]$request $pathToSave = "C:\Users\patryk\socket_io\server\tests\req_$request\len_$len-user_$user" $dirComm = "mkdir $pathToSave" #Write-Host "dir comm: " $dirComm Invoke-Expression $dirComm $args = ' run --variables ''{ \"duration\": '+$integer_user+', \"data\": \"'+$generatedData+'\", \"count\": '+$integer_req+ '}'' --output '+$pathToSave+'\test-run-report.json C:\Users\patryk\socket_io\server\tests\load-test.yml' #-f $integer_user,$generatedData,$integer_req,$pathToSave $psi.Arguments = $args $proc = [Diagnostics.Process]::Start($psi) if ( $waitForExit ) { #Write-Host $PWD $proc.WaitForExit(); $stdout = $proc.StandardOutput.ReadToEnd() $stderr = $proc.StandardError.ReadToEnd() Write-Host "stdout: $stdout" Write-Host "stderr: $stderr" } } catch { Write-Host "An error occurred:" Write-Host $_ Write-Host "Error occured with: user: $user, data: $generatedData, noOfRequests: $request, args: $args" } } } }
错误信息
An error occurred: You cannot call a method on a null-valued expression. Error occured with: user: 1, data: b, noOfRequests: 1, args: run --variables '{ \"duration\": 1, \"data\": \"b\", \"count\": 1}' --output C:\Users\patryk\socket_io\server\tests\req_1\len_1-user_1\test-run-report.json C:\Users\patryk\socket_io\server\tests\load-test.yml
错误原因分析
报错核心是[Diagnostics.Process]::Start($psi)返回了$null,后续调用$proc.WaitForExit()时触发「不能对空值表达式调用方法」的错误,具体诱因:
- 参数开头多余空格:生成的
$args开头有空格(示例中为run --variables ...),导致Artillery无法正确识别命令参数,进程启动失败。 - 未配置流重定向:默认
ProcessStartInfo不捕获标准输出/错误流,直接调用ReadToEnd()也会引发问题,但本次报错的直接触发点是进程启动失败。 - 目录创建方式不可靠:
Invoke-Expression $dirComm创建目录时,若目录已存在会报错,可能中断后续流程。
修复方案
1. 修正参数开头的空格
移除$args定义开头的空格:
$args = 'run --variables ''{ \"duration\": '+$integer_user+', \"data\": \"'+$generatedData+'\", \"count\": '+$integer_req+ '}'' --output '+$pathToSave+'\test-run-report.json C:\Users\patryk\socket_io\server\tests\load-test.yml'
2. 配置ProcessStartInfo流捕获
创建$psi后添加以下配置,确保能正确捕获输出:
$psi.RedirectStandardOutput = $true $psi.RedirectStandardError = $true $psi.UseShellExecute = $false
3. 替换目录创建方式
用PowerShell原生命令替代Invoke-Expression,避免目录已存在时报错:
New-Item -ItemType Directory -Force -Path $pathToSave | Out-Null
4. 优化变量拼接(可选)
用PowerShell的JSON转换语法简化变量拼接,避免转义错误:
$variables = @{ duration = $integer_user data = $generatedData count = $integer_req } | ConvertTo-Json -Compress $args = "run --variables '$variables' --output '$pathToSave\test-run-report.json' 'C:\Users\patryk\socket_io\server\tests\load-test.yml'"
内容的提问来源于stack exchange,提问作者The Trainer
相关产品推荐
相关产品推荐

