【问题标题】:Karate - custom assertion in expected JSON schema空手道 - 预期 JSON 模式中的自定义断言
【发布时间】:2020-11-04 02:12:08
【问题描述】:

我希望对从文件加载的 JSON 中的字段执行自定义断言。

我知道我们有模糊匹配,但我想执行一些更自定义的操作,例如具有将日期解析为 LocalDateTime 的函数:

public class DateUtil {
public static boolean matchesMyDateFormat(String dateStr) {
    try {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        LocalDateTime.parse(dateStr, formatter);
    } catch (DateTimeParseException e) {
        return false;
    }
    return true;
}

}

这将被以下调用:

* def matchesMyDateFormat =
"""
function fn(dateX){
  return Java.type('com.karate.DateUtil').matchesMyDateFormat(dateX);
}
"""

* def expected = read('expected.json')
* def actual = read('actual.json')
* match expected == actual

expected.json 看起来像这样:

{
   "date1" : "#? matchesMyDateFormat(_)"
}

注意,这专门用于从文件加载的 JSON,而不是在功能文件本身中指定的 JSON(例如,这里的 isValidTime():https://github.com/intuit/karate/blob/master/karate-junit4/src/test/java/com/intuit/karate/junit4/demos/schema-like.feature)。

希望这样做的几个原因:

  • 我需要断言的一些有效负载有很多日期字段返回,格式不同。像上面这样断言将与空手道验证模式的出色方式很好地结合在一起。然而,在功能文件中执行此操作需要大量代码,即每个日期的一行代码(我意识到可以使用 ma​​tch each - 但即使这样也会变得复杂,具体取决于字段的嵌套。)
  • 我可以将此函数添加到我的常用 utils 功能文件中,以便在整个项目的预期响应架构中重复使用。
  • 除此之外,我还想做其他事情,例如检查一个日期是否先于另一个日期(但我想使用 Java 中的各种类型来执行此操作,例如考虑时区)。
  • 我还在寻找格式匹配方法来接收另一个参数,它可以让测试人员指定自定义格式字符串。

注意:我已通读文档和其他与日期断言相关的 SO 答案,并认为这是一个略有不同的问题。

目前可以在空手道中进行上述操作吗?

【问题讨论】:

    标签: karate


    【解决方案1】:

    您可以在karate-config.js 中添加“全局”函数。例如:

    var config = {};
    config.isValidDate = read('classpath:is-valid-date.js');
    return config;
    

    现在您可以在任何功能中使用isValidDate(_)。请注意,JS 函数可以接受多个参数,例如:

    * match foo == { bar: "#? isValidDate(_, 'MYFORMAT')" }
    

    在 0.9.6.RC4 中,我们进行了改进,以便您可以将复杂的条件逻辑甚至 match 操作移动到可重复使用的 JS 文件中:https://github.com/intuit/karate/issues/1202

    请注意,这样做可能会导致无法读取的测试:https://stackoverflow.com/a/54126724/143475

    一个提示,您可以使用karate.forEach() 将所有日期字段提取到一个数组中,然后单个match each 可能会起作用。

    最后,如果你还是觉得“你的功能文件中的代码太多”,我不知道,也许你需要请教魔术师。

    【讨论】:

    • 这有助于我在功能文件本身中执行匹配,即 JSON 是“内联”的。我想我想的特定用例更类似于我们在从文件中读取的 JSON 中的模糊匹配器。例如。 #正则表达式。您可以将其视为#myCustomFunction(_,'FORMAT')。我担心这可能不可行。 PS:不需要魔术师;)完全参与空手道的使命。我正在空手道之上编写一个框架,并推动我的团队接受。顺便说一句,我 100% 同意 DAMP > DRY。我只是认为做这样的事情会是补充架构验证的好方法。
    • OK - 忽略上述。事实证明它可以在 JSON 文件本身中完成 - 但断言失败,因为我“预期”和“实际”的方式错误:D 我将在答案中充分展示这一点。感谢彼得的帮助。
    • @karatekid5088 I'm writing a framework on top of Karate and pushing for buy in from my team - 太好了。我的建议是不要太过分,也请阅读以下内容:stackoverflow.com/a/58339662/143475
    • 非常感谢 - 非常有用。是的,我完全同意——我开始研究空手道的原因是因为我在以前的项目中仍然留下了伤疤,在那里我一直在维护你所警告的方法:) 这些自定义的公共库弊大于利。我喜欢将空手道视为“公共库”本身。
    【解决方案2】:

    我正在尝试的实际上是一个有效的用例(正如 Peter Thomas 在他的回答中所建议的替代解决方案)。

    我的特定变体不起作用的原因是这个错误:

    07:22:50.421 assertion failed: path: $.date1, actual: '#? matchesMyDateFormat(_)', expected: '2020-06-10T14:44:57.060Z', reason: not equal
    

    我用一双新鲜的眼睛注意到我应该从以下位置翻转比赛声明:

    * match expected == actual
    

    收件人:

    * match actual == expected
    

    为了让空手道发挥它的魔力并调用 expected.json 中的自定义函数,需要这种方式。

    【讨论】:

    • 啊。很高兴这是简单的修复;)
    猜你喜欢
    • 2019-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多