NBomber负载测试如何实现步骤仅执行一次(或精确N次)
NBomber 固定次数执行场景、StopScenario不生效问题
问题现象
使用NBomber做负载测试时,需要实现测试步骤仅执行1次(或精确执行N次)的效果。查阅资料得知可通过调用context.StopScenario(context.ScenarioInfo.ScenarioName, "Stop Reason");方法主动停止场景,但实际使用时该方法未达到预期,运行统计结果显示请求数为0,无法确认是否为代码编写问题。
复现代码
[Test] public void METHOD() { var step2 = Step.Create("step 2", timeout: TimeSpan.FromHours(1), execute: async context => { try { await Task.Delay(TimeSpan.FromSeconds(1)); context.Logger.Information("step 2 is invoked!!!"); return Response.Ok(); } finally { context.StopScenario(context.ScenarioInfo.ScenarioName, "Executed 1 time ended"); } }); var scenario = ScenarioBuilder.CreateScenario("hello_world", step2).WithoutWarmUp() .WithLoadSimulations(Simulation.KeepConstant(1, TimeSpan.FromSeconds(50))); NBomberRunner.RegisterScenarios(scenario).Run(); }
运行统计结果

问题原因与解决方案
问题原因
StopScenario的停止指令是异步下发的,把停止逻辑写在finally块中,会在步骤第一次执行完返回响应的瞬间触发场景停止,此时NBomber还没完成本次步骤执行结果的统计上报,就会出现统计面板请求数为0的问题。
另外要实现精确执行N次的需求,完全不需要手动调用停止方法,NBomber原生提供了对应负载仿真模型,稳定性比手动停止高很多。
推荐方案(原生API实现固定执行次数)
直接使用迭代次数控制的负载模拟策略即可,不需要在步骤里写任何停止逻辑:
var scenario = ScenarioBuilder.CreateScenario("hello_world", step2) .WithoutWarmUp() // 参数说明:并发数1,总迭代次数1,无预热时间 .WithLoadSimulations(Simulation.IterationsForConstant( copies: 1, iterations: 1, during: TimeSpan.Zero ));
如果需要执行N次,把iterations参数改成对应数值即可。
手动调用StopScenario的修正写法
如果确实有特殊场景需要手动触发停止,不要把停止逻辑放在finally块里,留足够的时间让步骤结果完成上报再触发停止:
var step2 = Step.Create("step 2", timeout: TimeSpan.FromHours(1), execute: async context => { await Task.Delay(TimeSpan.FromSeconds(1)); context.Logger.Information("step 2 is invoked!!!"); var okRes = Response.Ok(); // 后台触发延迟停止,避免阻塞步骤结果上报 _ = Task.Run(async () => { await Task.Delay(100); context.StopScenario(context.ScenarioInfo.ScenarioName, "Executed 1 time ended"); }); return okRes; });
内容的提问来源于stack exchange,提问作者satellite satellite
相关产品推荐
相关产品推荐

