Karate框架如何循环执行场景遍历动态获取的端点列表
解决Karate接口测试中动态遍历端点的问题
问题场景
在Karate接口测试中,需要先发送endpoint为"list"的请求,获取动态返回的端点列表(如value 1、value 2等),再逐个遍历该列表执行测试场景。但当前使用Scenario Outline结合Examples的实现,会把整个端点数组作为endpoint值传入请求,导致请求体中的endpoint字段变成数组(如["value 1", "value 2", "value 3"]),请求内容错误。
相关代码片段
请求体模板(apigeeRequest.json):
{ "endpoint": "#(endpoint)", "propertyId": "XXXXXXXX-XXXXX-XXXX-XXXX", "payload_prospect": { "FirstName" :"Mike", "SpectrumPersonID" : "XXXXXXXX-XXXXX-XXXX-XXXX", "Phone1" :"555-555-5555" } }
获取端点的请求示例:
{ "endpoint": "List", "propertyId": "XXXXXXXX-XXXXX-XXXX-XXXX", "payload_prospect": { "FirstName" :"Mike", "SpectrumPersonID" : "XXXXXXXX-XXXXX-XXXX-XXXX", "Phone1" :"555-555-5555" } }
端点列表返回示例:
{ "value 1": { "foo1": "aaa", "foo2": "bbb", "foo3": "ccc" }, "value 2": { "foo1": "aaa", "foo2": "bbb", "foo3": "ccc" }, "value 3": { "foo1": "aaa", "foo2": "bbb", "foo3": "ccc" } }
当前错误的测试代码:
Feature: Endpoints Background: # 获取token Given def appToken= callonce read('classpath:utils/features/auth/appToken.feature') And def token = appToken.authToken # 获取可用端点列表 Given url baseUrl And path 'externalResourceClient' And header Authorization = 'Bearer ' + token And def endpoint = 'list' And def requestBody = read('classpath:jsonfiles/requests/curlcalls/apigee/apigeeRequest.json') And request requestBody And retry until responseStatus == 200 When method GET Then status 200 And def endpoints = jsonOperations.getJsonKeys(response) Scenario Outline: 测试端点 Given url baseUrl And path 'externalResourceClient' And header Authorization = 'Bearer ' + token # And def endpoint = <endpoint> And def requestBody = read('classpath:jsonfiles/requests/curlcalls/apigee/apigeeRequest.json') And request requestBody And retry until responseStatus == 200 When method GET Then status 200 Examples: | endpoint | | endpoints |
错误请求示例:
{ "endpoint": ["value 1", "value 2", "value 3"], "propertyId": "XXXXXXXX-XXXXX-XXXX-XXXX", "payload_prospect": { "FirstName" :"Mike", "SpectrumPersonID" : "XXXXXXXX-XXXXX-XXXX-XXXX", "Phone1" :"555-555-5555" } }
解决方案
Karate的Scenario Outline仅支持静态表格数据,无法直接处理动态数组。推荐使用循环遍历的方式实现动态端点测试,以下提供两种可行方案:
方案1:在Scenario中使用karate.forEach循环
直接在单个Scenario内遍历端点数组,逐个执行测试逻辑:
Feature: Endpoints Background: # 获取token Given def appToken= callonce read('classpath:utils/features/auth/appToken.feature') And def token = appToken.authToken # 获取可用端点列表 Given url baseUrl And path 'externalResourceClient' And header Authorization = 'Bearer ' + token And def endpoint = 'list' And def requestBody = read('classpath:jsonfiles/requests/curlcalls/apigee/apigeeRequest.json') And request requestBody And retry until responseStatus == 200 When method GET Then status 200 And def endpoints = jsonOperations.getJsonKeys(response) Scenario: 逐个测试所有端点 Given url baseUrl And path 'externalResourceClient' And header Authorization = 'Bearer ' + token # 遍历端点数组,逐个执行测试 * karate.forEach(endpoints, function(currentEndpoint) { Given def endpoint = currentEndpoint And def requestBody = read('classpath:jsonfiles/requests/curlcalls/apigee/apigeeRequest.json') And request requestBody And retry until responseStatus == 200 When method GET Then status 200 # 可添加额外断言,比如验证返回内容结构 And match response contains { foo1: 'aaa' } })
方案2:抽离单个端点测试逻辑,循环调用
将单个端点的测试逻辑抽成独立Feature,通过call循环调用:
- 创建独立测试Feature(
testSingleEndpoint.feature):
Feature: 测试单个端点 Scenario: 执行单个端点测试 Given url baseUrl And path 'externalResourceClient' And header Authorization = 'Bearer ' + token # 接收传入的端点参数 And def endpoint = __arg And def requestBody = read('classpath:jsonfiles/requests/curlcalls/apigee/apigeeRequest.json') And request requestBody And retry until responseStatus == 200 When method GET Then status 200
- 在主Feature中循环调用:
Feature: Endpoints Background: # 获取token Given def appToken= callonce read('classpath:utils/features/auth/appToken.feature') And def token = appToken.authToken # 获取可用端点列表 Given url baseUrl And path 'externalResourceClient' And header Authorization = 'Bearer ' + token And def endpoint = 'list' And def requestBody = read('classpath:jsonfiles/requests/curlcalls/apigee/apigeeRequest.json') And request requestBody And retry until responseStatus == 200 When method GET Then status 200 And def endpoints = jsonOperations.getJsonKeys(response) Scenario: 批量测试所有端点 # 遍历端点数组,调用单个端点测试Feature * def testResults = karate.map(endpoints, function(endpoint) { return call read('classpath:testSingleEndpoint.feature') endpoint }) # 可选:验证所有测试均通过 * match each testResults responseStatus == 200
说明
原来的Scenario Outline + Examples方式失效的原因是:Examples只能解析静态表格,无法将动态数组拆分为单个参数项,传入数组后会被当作单个值填充到请求体中,导致endpoint字段变为数组类型。而使用Karate的循环API(karate.forEach/karate.map)可以直接处理动态数组,实现逐个端点的测试。
内容的提问来源于stack exchange,提问作者JordanCarrillo
相关产品推荐
相关产品推荐

