如何在Karate中验证API响应键值对存在且值含指定子串?
Karate API测试:验证数组对象的键存在及值包含子串的问题
问题场景
我用Karate编写API测试时遇到一个问题:需要验证响应数组中的每个对象都包含指定键,且该键的值包含特定子串。
例如响应结构如下:
[ { "Name-1": "Value-1", "Name-2": "Value-2", "Name-3": "Value-3", "Name-4": "Value-4" } ]
我需要验证每个对象都有Name-2键,且其值包含"2"。原本用* match each response[*].Name-2 contains "2"可以正常通过验证,但当响应中原来的Old-Name-2键被移除后,用* match each response[*].Old-Name-2 contains "2"测试竟然误判通过,而直接访问单个元素* match response[0].Old-Name-2 contains "2"时却能正确报错。
问题原因
之所以出现误判,是因为当访问不存在的键时,response[*].Old-Name-2会生成一个包含null的数组,而Karate的match each ... contains操作符对null不会触发验证失败;但直接访问单个元素时,Karate会检查路径是否存在,因此能正确报错。
解决方案
要同时验证键存在和值包含子串,避免误判,可以用以下几种写法:
写法1:分开验证键存在与值规则
先确保每个对象都包含目标键,再验证键对应的值符合要求:
# 验证每个对象都包含Name-2键 * match each response has key 'Name-2' # 验证Name-2的值包含"2" * match each response[*].Name-2 contains "2"
写法2:用Schema合并验证(更简洁)
通过Karate的Schema断言,在一个match语句中同时完成键存在和值验证:
* match each response == { 'Name-2': '#? it.contains("2")' }
这里的#?是Karate的脚本断言标记,it代表当前字段的值,既确保了Name-2键存在,又验证了其值包含"2"。
写法3:自定义函数遍历验证
如果需要更灵活的逻辑,可以编写自定义函数,遍历每个对象执行验证:
* def validateItem = function(item) { karate.match(item, 'has key "Name-2"'); karate.match(item['Name-2'], 'contains "2"'); } * call each response validateItem
以上三种写法都会在键不存在时立即抛出错误,避免误判情况。
内容的提问来源于stack exchange,提问作者jsmith
相关产品推荐
相关产品推荐

