Karate 空手道-预期JSON模式中的自定义断言

Karate 空手道-预期JSON模式中的自定义断言,karate,Karate,我希望对从文件加载的JSON中的字段执行自定义断言 我知道我们有模糊匹配,但我想执行一些更自定义的操作,例如,有一个将日期解析为LocalDateTime的函数: public class DateUtil { public static boolean matchesMyDateFormat(String dateStr) { try { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yy

我希望对从文件加载的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()类似:)

有几个理由希望这样做:

  • 我需要断言的一些有效负载返回了许多具有不同格式的日期字段。像上面这样的断言将与空手道验证模式的优秀方式紧密结合。但是,在功能文件中执行此操作需要大量代码,即每个日期都有一行代码(我知道可以使用匹配每个,但即使这样也会变得复杂,这取决于字段的嵌套情况。)
  • 我可以将这个函数添加到我的公共utils功能文件中,这样它就可以在整个项目的预期响应模式中重复使用
  • 除此之外,我还想做其他事情,比如检查一个日期是否出现在另一个日期之前(但我想使用Java中的各种类型来做这件事,例如考虑时区)
  • 我还将寻找另一个参数中的格式匹配方法,该参数允许测试人员指定自定义格式字符串
注:我已经阅读了文档和其他与日期断言相关的答案,相信这是一个稍微不同的问题


目前在空手道中是否可以实现上述功能?

您可以在
Karate config.js
中添加“全局”功能。例如:

var config = {};
config.isValidDate = read('classpath:is-valid-date.js');
return config;
现在您可以在任何功能中使用
isValidDate(41;
。请注意,JS函数可以接受多个参数,例如:

* match foo == { bar: "#? isValidDate(_, 'MYFORMAT')" }
在0.9.6.RC4中,我们进行了改进,以便您可以将复杂的条件逻辑,甚至是
匹配
操作移动到可重用的JS文件中:

请注意,大量这样做可能会导致不可读的测试:

有一个提示,您可以使用
karate.forEach()
将所有日期字段提取到一个数组中,然后使用单个
匹配每个
即可


最后,如果您仍然觉得“功能文件中的代码太多”,我不知道,也许您需要咨询魔术师。

我所尝试的实际上是一个有效的用例(正如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
致:


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

这有助于我在功能文件本身中执行匹配,即json是“串联”的。我想我考虑的特定用例更类似于从文件读取JSON中的模糊匹配器。例如#regex。您可以将其视为“myCustomFunction”(“格式”)。我担心这可能行不通。附言:不需要魔术师;)完全支持空手道的使命。我正在空手道的基础上编写一个框架,并推动我的团队加入进来。顺便说一句,我100%同意潮湿>干燥。我只是觉得这样做是补充模式验证的一个好方法。好吧,忽略上面的内容。事实证明,这可以在JSON文件本身中完成——但断言失败了,因为我“预期”和“实际”的方式是错误的:D我将在回答中充分说明这一点。谢谢你的帮助,Peter。@karatekid5088
我正在空手道之上编写一个框架,并推动我的团队加入进来
-太好了。我的建议是不要太过火,也要读这篇文章:非常感谢这篇文章——非常有用。是的,我完全同意——我之所以开始研究空手道,是因为我在以前的一个项目中留下了疤痕,在那里我一直保持着你所警告的方法:)这些习惯性的普通自由体操弊大于利。我喜欢把空手道看作是“普通的自由体操”。很高兴这是一个简单的解决办法;)
* match actual == expected