You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

执行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()时触发「不能对空值表达式调用方法」的错误,具体诱因:

  1. 参数开头多余空格:生成的$args开头有空格(示例中为 run --variables ...),导致Artillery无法正确识别命令参数,进程启动失败。
  2. 未配置流重定向:默认ProcessStartInfo不捕获标准输出/错误流,直接调用ReadToEnd()也会引发问题,但本次报错的直接触发点是进程启动失败。
  3. 目录创建方式不可靠: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 19:10:32