如何在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
代码说明
- 自定义
isImageMatched函数:通过try-catch包裹karate.compareImage,匹配成功时返回true,失败时捕获异常并返回false,避免中断重试判断逻辑。 - 调整重试条件:直接调用自定义函数判断图片匹配状态,结合
responseStatus == 200作为重试终止条件。 - 日志输出:在捕获异常时打印日志,方便排查每次重试失败的原因。
额外优化建议
- 可根据需求调整
retry配置的count(重试次数)和interval(间隔毫秒数),适配业务场景的等待时长。 - 如果需要保留每次重试的图片用于排查,可以在
catch块中添加karate.write(response, 'failed-thumbnail-' + karate.retryCount + '.jpg'),将失败的缩略图写入本地。
内容的提问来源于stack exchange,提问作者Stan Allosserie
相关产品推荐
相关产品推荐

