如何在Karate报告中按JSON响应属性分组匹配失败用例
问题描述
我正在对比两个服务的JSON响应,二者应返回相似结果,但部分测试用例会因属性不匹配而失败。我希望按失败用例的属性(如数组索引ID、账号等)分组,查看具体差异元素。我写了一段按serialNumber属性分组不匹配元素的Karate代码,但无法正常运行,代码如下:
Feature: Compare Cache getEquipment and SPC getEquipment Service Responses for Multiple Accounts Background: # configure truststore # Group the mismatched elements based on serialNumber * def mismatchedElements = {} * def cacheItems = cacheResponse.response * def spcItems = spcResponse.response * def cacheSize = cacheItems.length * def spcSize = spcItems.length * def loopSize = Math.min(cacheSize, spcSize) * karate.repeat(loopSize, function(index) { * def cacheItem = cacheItems[index] * def spcItem = spcItems[index] # Compare serialNumber attribute * if (cacheItem.serialNumber != spcItem.serialNumber) { * def mismatchedKey = cacheItem.serialNumber * def mismatchedValue = { cacheResponse: cacheItem, spcResponse: spcItem } * karate.set(mismatchedElements, mismatchedKey, mismatchedValue) } }) # Log the grouped mismatched elements * print 'Grouped Mismatched Elements:', mismatchedElements
问题原因
原代码核心问题是在karate.repeat的回调函数中混用了Karate DSL关键字(比如* def、* if)。karate.repeat的回调是纯JavaScript执行环境,不支持直接使用Karate的DSL语法,导致代码无法正常执行。
修复后的代码
Feature: 对比缓存服务与SPC服务的getEquipment接口多账号响应 Background: # 配置信任库 # 初始化存储不匹配元素的对象 * def mismatchedElements = {} * def cacheItems = cacheResponse.response * def spcItems = spcResponse.response * def cacheSize = cacheItems.length * def spcSize = spcItems.length * def loopSize = Math.min(cacheSize, spcSize) # 用纯JS逻辑实现遍历与对比,避免混用Karate DSL * def processMismatches = function() { for (var i = 0; i < loopSize; i++) { var cacheItem = cacheItems[i]; var spcItem = spcItems[i]; if (cacheItem.serialNumber !== spcItem.serialNumber) { var mismatchedKey = cacheItem.serialNumber; mismatchedElements[mismatchedKey] = { cacheResponse: cacheItem, spcResponse: spcItem }; } } } * call processMismatches # 可选:处理两个数组长度不一致的情况,避免遗漏元素 * if (cacheSize !== spcSize) { * def extraItems = cacheSize > spcSize ? cacheItems.slice(loopSize) : spcItems.slice(loopSize) * def sourceService = cacheSize > spcSize ? 'cacheResponse' : 'spcResponse' * extraItems.forEach(function(item) { // 为无serialNumber的元素生成唯一键,防止覆盖 var key = item.serialNumber || '无serialNumber_' + Date.now() + Math.random(); mismatchedElements[key] = { [sourceService]: item }; }) } # 打印分组后的不匹配元素 * print '分组后的不匹配元素:', mismatchedElements
关键修复点
- 分离JS逻辑与Karate DSL:把遍历对比逻辑封装成纯JS函数,通过
call关键字调用,确保逻辑在正确的执行环境中运行。 - 兼容数组长度不一致场景:新增逻辑处理其中一方响应数组更长的情况,避免遗漏多出的元素。
- 键名容错处理:对没有
serialNumber的元素生成唯一键名,防止对象属性被覆盖。
内容的提问来源于stack exchange,提问作者Reyhaneh Hussaini
相关产品推荐
相关产品推荐

