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

如何在Karate中结合retry until与compareImage实现缩略图重试校验?

Karate中retry until结合compareImage重试失败的解决方法

问题描述

需要测试获取的缩略图是否正确,因首次获取可能不正确,希望每隔几秒重试。尝试结合Karate的retry until与compareImage功能,但首次校验失败、后续重试成功时,场景仍会因compareImage抛出异常而失败。

当前代码

@getThumnailAndCompare
Scenario: Get thumbnail and compare to reference file
  * configure imageComparison = { engine: 'ssim', failureThreshold: 0.5 }
  * configure retry = { count: 3, interval: 2000 }

  Given url 'https://127.0.0.1:8443'
  And header Accept = 'image/jpeg'
  And path 'api/thumbnail'

  * def expectedThumbnail = 'classpath:thumbnails/expected.jpg'
  And retry until responseStatus == 200 && karate.match("karate.compareImage(expectedThumbnail, response) == '#present'").pass

  When method GET

错误日志

08:26:05.519 [main] INFO  c.intuit.karate.core.FeatureRuntime - classpath:com/barco/nexxis/nmsplus/common/thumbnail.feature - call by tag at line 22: getThumbnailAndCompare
08:26:10.941 [main] ERROR com.intuit.karate - image comparison failed: latest image differed from baseline more than allowable threshold: 55.89009307671784% >= 0.5%
08:26:11.010 [main] WARN  com.intuit.karate - retry condition evaluation failed: js failed:
>>>>
01: responseStatus == 200 && karate.match("karate.compareImage(expectedThumbnail, response) == '#present'").pass
<<<<
org.graalvm.polyglot.PolyglotException: js failed:
>>>>
01: karate.compareImage(expectedThumbnail, response)
<<<<
org.graalvm.polyglot.PolyglotException: latest image differed from baseline more than allowable threshold: 55.89009307671784% >= 0.5%
- com.intuit.karate.ImageComparison.checkMismatch(ImageComparison.java:211)
- com.intuit.karate.ImageComparison.compare(ImageComparison.java:196)
- com.intuit.karate.core.ScenarioEngine.compareImageInternal(ScenarioEngine.java:1068)
- com.intuit.karate.core.ScenarioBridge.compareImage(ScenarioBridge.java:293)
- <js>.:program(Unnamed:1)

- com.intuit.karate.graal.JsEngine.fromJsEvalException(JsEngine.java:224)
- com.intuit.karate.core.ScenarioEngine.evalJs(ScenarioEngine.java:1192)
- com.intuit.karate.core.ScenarioEngine.evalKarateExpression(ScenarioEngine.java:2143)
- com.intuit.karate.core.ScenarioEngine.evalKarateExpression(ScenarioEngine.java:2062)
- com.intuit.karate.core.ScenarioEngine.match(ScenarioEngine.java:1729)
- com.intuit.karate.core.ScenarioBridge.match(ScenarioBridge.java:643)
- java.base/java.lang.invoke.SpreadHandle.invokeExact_thunkArchetype_X(SpreadHandle.java:100)

问题根源

karate.compareImage在图片不匹配时会直接抛出异常,导致retry until的判断表达式执行中断,Karate会认为重试条件评估失败,进而终止重试流程,即使后续重试能成功匹配也无法继续。

解决方案

自定义一个图片匹配判断函数,用try-catch捕获compareImage的异常,返回布尔值表示是否匹配;然后在retry until中调用该函数,确保判断逻辑不会因异常中断。

修改后的代码

@getThumnailAndCompare
Scenario: Get thumbnail and compare to reference file
  * configure imageComparison = { engine: 'ssim', failureThreshold: 0.5 }
  * configure retry = { count: 3, interval: 2000 }

  Given url 'https://127.0.0.1:8443'
  And header Accept = 'image/jpeg'
  And path 'api/thumbnail'

  * def expectedThumbnail = 'classpath:thumbnails/expected.jpg'
  # 自定义判断图片匹配的函数,捕获异常返回布尔值
  * def isImageMatched = function(expected, actual) {
      try {
        karate.compareImage(expected, actual);
        return true;
      } catch (e) {
        karate.log('图片匹配失败,错误信息:', e.message);
        return false;
      }
    }

  # 重试条件:状态码200且图片匹配成功
  And retry until responseStatus == 200 && isImageMatched(expectedThumbnail, response)

  When method GET

代码说明

  1. 自定义isImageMatched函数:通过try-catch包裹karate.compareImage,匹配成功时返回true,失败时捕获异常并返回false,避免中断重试判断逻辑。
  2. 调整重试条件:直接调用自定义函数判断图片匹配状态,结合responseStatus == 200作为重试终止条件。
  3. 日志输出:在捕获异常时打印日志,方便排查每次重试失败的原因。

额外优化建议

  • 可根据需求调整retry配置的count(重试次数)和interval(间隔毫秒数),适配业务场景的等待时长。
  • 如果需要保留每次重试的图片用于排查,可以在catch块中添加karate.write(response, 'failed-thumbnail-' + karate.retryCount + '.jpg'),将失败的缩略图写入本地。

内容的提问来源于stack exchange,提问作者Stan Allosserie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:43:09