【问题标题】:Karate framework retry until not working as expected空手道框架重试,直到无法按预期工作
【发布时间】:2019-04-23 23:27:10
【问题描述】:

我在 JUnit 中使用空手道框架。

使用此功能:

Given path 'save_token'
And request
"""
{
  "token": "test_token"
}
"""
And retry until response.tokens ==
"""
[
    "test_token"
]
"""
When method POST

我遇到了这个异常:

java.lang.ArrayIndexOutOfBoundsException: 1
    at com.intuit.karate.core.MethodMatch.convertArgs(MethodMatch.java:60)
    at com.intuit.karate.core.Engine.executeStep(Engine.java:141)
    at com.intuit.karate.core.ScenarioExecutionUnit.execute(ScenarioExecutionUnit.java:171)

当 response.tokens 列表为空时:

{
    "tokens": []
}

我不明白为什么 == 在这种情况下不起作用(它应该返回 false,并继续重试)。

提前致谢!

【问题讨论】:

    标签: karate


    【解决方案1】:

    retry until 表达式必须是纯 JavaScript,并且不支持特殊的空手道匹配关键字,例如 contains,并且您不能像您尝试的那样执行“深度相等”,因为那也不行可以在 JS 中使用。

    编辑:在 0.9.6 中。之后你可以在 JS 中做一个复杂的matchhttps://stackoverflow.com/a/50350442/143475

    另请注意,JsonPath 受支持,这意味着*.. 不能出现在表达式中。

    所以如果你的回复是{ "tokens": [ "value1" ] },你可以这样做:

    And retry until response.tokens.contains('value1')
    

    或者:

    And retry until response.tokens[0] == 'value1'
    

    要进行实验,您可以尝试如下表达式:

    * def response = { "tokens": [ "value1" ] }
    * assert response.tokens.contains('value1')
    

    在运行时,您可以在轮询时使用 JS 处理响应尚未准备好的情况:

    And retry until response.tokens && response.tokens.length
    

    编辑:实际上,执行上述操作的一种更优雅的方法如下所示,因为karate.get() 优雅地处理了 JS 或 JsonPath 评估失败并返回 null

    And retry until karate.get('response.tokens.length')
    

    或者如果您正在处理 XML,您可以使用 karate.xmlPath() API:

    And retry until karate.xmlPath(response, '//result') == 5
    

    如果你真的想使用空手道match 语法的强大功能,你可以使用JS API

    And retry until karate.match(response, { tokens: '##[_ > 0]' }).pass
    

    注意,如果你有更复杂的逻辑,你总是可以把它包装成一个可重用的函数:

    * def isValid = function(x){ return karate.match(x, { tokens: '##[_ > 0]' }).pass }
    # ...
    And retry until isValid(response)
    

    最后,如果以上都不起作用,您可以随时切换到自定义轮询例程:polling.feature

    编辑:有关如何使用 karate.filter() 而不是 JsonPath 的示例,另请参阅此答案:https://stackoverflow.com/a/60537602/143475

    编辑:从 0.9.6 版开始,空手道可以在 JS 中做一个match,这可以简化上面的一些:https://stackoverflow.com/a/50350442/143475

    【讨论】:

    • response.tokens 是什么样的对象,可以应用 contains() 方法?我正在寻找 javascript 数组文档,他们使用包含()。我正在寻找类似 containsAll() 的东西。
    • 其实是一个javaList。也许您只需要这样做And retry until karate.match(response, { tokens: '#(^^expected)' }).pass - 请参阅文档中的“包含快捷方式”
    • 太棒了。最后一个问题,你怎么能打破重试直到表达式?行太长,输入无效。
    • 我知道我可以写一个单独的函数,但我想把它放在一个多行的表达式中。
    • @italktothewind 你不能。但请记住,“开源”;P
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    • 2021-03-30
    相关资源
    最近更新 更多