JMeter中如何同时忽略Transaction Controller的父样本与子样本?
问题原因
勾选「Generate parent sample」的事务控制器会聚合其下所有子样本的结果,当你用JSR223后置处理器把所有子样本标记为忽略后,父样本因没有有效子数据,就会生成空样本(Load Time/Connect Time/Latency均为0),进而影响报告指标。
解决方案
方案1:自动忽略空的事务父样本
在事务控制器下新增一个JSR223 PostProcessor(需放在所有子采样器的后置处理器之后),用以下代码检查所有子样本是否都被忽略,若是则直接标记父样本为忽略:
def allChildrenIgnored = true sampleResult.subResults.each { child -> if (!child.ignore) { allChildrenIgnored = false } } if (allChildrenIgnored) { sampleResult.setIgnore(true) }
这样空的父样本会直接从结果中移除,不会出现在监听器和Dashboard里。
方案2:提前跳过首尾1分钟的采样(更高效)
与其执行后再忽略,不如直接在采样前判断是否需要执行,从根源避免生成无效样本:
- 在测试计划层级加一个JSR223 PreProcessor,记录测试启动时间:
if (!vars.containsKey("testStartTime")) { vars.put("testStartTime", String.valueOf(System.currentTimeMillis())) }
- 在事务控制器前加一个JSR223 PreProcessor,判断当前是否在首尾1分钟范围内,若是则跳过执行:
long testStart = Long.parseLong(vars.get("testStartTime")) long current = System.currentTimeMillis() long elapsed = current - testStart // 读取测试计划设置的总时长(秒转毫秒),需先在测试计划中配置Duration long totalDuration = Long.parseLong(props.get("jmeter.testplan.duration")) * 1000 // 跳过首60秒和末60秒的采样 if (elapsed < 60000 || (totalDuration - elapsed) < 60000) { sampler.setSkip(true) }
若你的测试用线程组循环次数控制而非Duration,可去掉末60秒的判断,或手动预估总时长替换
totalDuration的值。
这种方式下,首尾1分钟内的事务控制器和子采样器都不会执行,自然不会产生空样本。
方案3:同步标记父样本
如果你想保留原有后置处理器逻辑,可以在子采样器的脚本中添加标记,再在事务控制器的脚本中根据标记忽略父样本:
- 在子采样器的JSR223 PostProcessor中,忽略子样本时设置变量:
// 你的原有时间判断逻辑 long current = System.currentTimeMillis() long testStart = Long.parseLong(vars.get("testStartTime")) if (current - testStart < 60000 || ...) { // 替换为你的实际条件 sampleResult.setIgnore(true) vars.put("ignoreParent", "true") }
- 在事务控制器的JSR223 PostProcessor中读取标记并忽略父样本:
if (vars.get("ignoreParent") == "true") { sampleResult.setIgnore(true) vars.remove("ignoreParent") // 清除标记,避免影响下一轮循环 }
内容的提问来源于stack exchange,提问作者JustNatural
相关产品推荐
相关产品推荐

