Gatling中用户测试执行失败后能否运行自定义代码?如何触发失败钩子清理资源
问题解答
Gatling完全支持你提出的失败时清理工单的需求,相关实现方案如下:
失败触发钩子支持
Gatling没有内置名为after的全局失败钩子,但提供了两种完全可以覆盖你需求的回调实现路径:
- 方案1:在第2、3步的请求逻辑后附加失败分支,你可以把提交工单后生成的工单ID存在*用户会话(Session)*中,一旦请求返回超时、校验失败等异常状态,直接在分支中调用删除工单的接口。
- 方案2:在整个测试场景的末尾增加统一清理逻辑,无论单用户测试执行成功还是失败都会运行该逻辑,通过判断会话中的执行状态和当前步骤,匹配到符合条件的失败场景再执行删除。
失败具体步骤的获取
你可以通过给会话打步骤标记的方式轻松获取失败节点:
- 在每个核心步骤执行完成后,给会话写入对应的步骤标识,比如提交工单后写入
currentStep = "submit_done",工单进入处理队列等待步骤后写入currentStep = "wait_processing",工单进入处理中等待完成步骤后写入currentStep = "processing"。 - 清理逻辑执行时,读取会话内置的
isFailed状态判断执行是否失败,同时读取你写入的currentStep变量就能确定失败发生的位置,完全可以实现仅第2、3步失败时触发删除、第1步提交失败未生成有效工单时跳过清理的逻辑。
示例代码参考
原生Gatling DSL实现的逻辑示例如下:
val ticketTestScn = scenario("异步工单压测场景") // 第1步:提交工单,保存工单ID到会话 .exec( http("提交工单") .post("/api/ticket/submit") .body(StringBody("{\"your_param\": \"xxx\"}")) .check(jsonPath("$.data.ticket_id").saveAs("ticketId")) ) .exec(session => session.set("currentStep", "submit_done")) // 第2步:轮询等待工单进入处理状态 .tryMax(Int.MaxValue, "等待处理轮询") { exec( http("查询工单状态") .get("/api/ticket/${ticketId}") .check(jsonPath("$.data.status").in("processing", "finished")) ).pause(2) } .exec(session => session.set("currentStep", "wait_process_finish")) // 第3步:轮询等待工单处理完成 .tryMax(30, "处理完成轮询") { // 按处理耗时1分钟设置,每2秒轮询一次共30次 exec( http("查询工单处理结果") .get("/api/ticket/${ticketId}") .check(jsonPath("$.data.status").is("finished")) ).pause(2) } .exec(session => session.set("currentStep", "process_done")) // 第4步:校验处理结果 .exec(/* 你的结果校验逻辑 */) // 统一清理逻辑 .doIf(session => { val currentStep = session("currentStep").as[String] // 仅2、3步执行失败时触发删除 session.isFailed && Seq("submit_done", "wait_process_finish").contains(currentStep) })( exec( http("清理失败工单") .delete("/api/ticket/${ticketId}") ) )
如果你使用的是Karate封装的Gatling调度逻辑,只需要把删除工单的逻辑封装为独立的Karate Feature,在失败分支中调用对应Feature即可,逻辑和原生Gatling DSL完全兼容。
内容的提问来源于stack exchange,提问作者Milan Smolík
相关产品推荐
相关产品推荐

