Karate 1.3.0升级后Scenario Outline变量引用丢失问题及修复请求
解决Karate 1.3.0中Scenario Outline变量引用丢失的问题
问题背景
将Karate测试框架从1.2.0升级至1.3.0后,Scenario Outline中已定义的变量(如<removeParameter>、<systemId>等)出现引用丢失的问题,相同代码在1.2.0及更早版本可正常运行。核心表现为子Feature的Scenario Outline无法正确解析从父Feature传递的测试数据变量。
根因分析
Karate 1.3.0对Scenario Outline的变量绑定逻辑进行了调整:
- 1.2.0及更早版本支持隐式从Examples中传递的对象(如
eInvoiceTestData)提取属性作为<变量>使用 - 1.3.0中移除了这种隐式绑定机制,要求必须显式访问传递对象的属性,无法再通过
<变量>语法直接获取对象属性值
修复方案
方案1:重构子Feature,移除Scenario Outline改用普通Scenario
由于父Feature已经通过call传递单条测试数据,子Feature无需再使用Scenario Outline循环,直接改用普通Scenario并显式从__arg获取参数即可:
修改后的子Feature代码:
Feature: Send e-invoice standing order agreement with Space user process Scenario: Process e-invoice SOA request * def eInvoiceTestData = __arg * def soaRequest = {"input": {"agreement": {}}} # 显式从eInvoiceTestData中读取参数,替换原<变量>语法 Given eval if (eInvoiceTestData.removeParameter != 'x') karate.remove('soaRequest', eInvoiceTestData.removeParameter) Given eval if (eInvoiceTestData.systemId != 'x') karate.set('soaRequest', 'input.agreement.systemId', eInvoiceTestData.systemId) Given eval if (eInvoiceTestData.sellerRegistrationNumber != 'x') karate.set('soaRequest', 'input.agreement.sellerRegistrationNumber', eInvoiceTestData.sellerRegistrationNumber) Given eval if (eInvoiceTestData.serviceId != 'x') karate.set('soaRequest', 'input.agreement.serviceId', eInvoiceTestData.serviceId) Given eval if (eInvoiceTestData.payerIban != 'x') karate.set('soaRequest', 'input.agreement.payerIban', eInvoiceTestData.payerIban) Given eval if (eInvoiceTestData.payerCode != 'x') karate.set('soaRequest', 'input.agreement.payerCode', eInvoiceTestData.payerCode) Given eval if (eInvoiceTestData.payerName != 'x') karate.set('soaRequest', 'input.agreement.payerName', eInvoiceTestData.payerName) Given eval if (eInvoiceTestData.paymentLimit != 'x') karate.set('soaRequest', 'input.agreement.paymentLimit', eInvoiceTestData.paymentLimit) Given eval if (eInvoiceTestData.monthlyLimit != 'x') karate.set('soaRequest', 'input.agreement.monthlyLimit', eInvoiceTestData.monthlyLimit) Given eval if (eInvoiceTestData.startDate != 'x') karate.set('soaRequest', 'input.agreement.startDate', eInvoiceTestData.startDate) Given eval if (eInvoiceTestData.endDate != 'x') karate.set('soaRequest', 'input.agreement.endDate', eInvoiceTestData.endDate) Given eval if (eInvoiceTestData.signingDate != 'x') karate.set('soaRequest', 'input.agreement.signingDate', eInvoiceTestData.signingDate) * print soaRequest * set eInvoiceTestData.postSOA.request = soaRequest * def sendEInvoiceSoa = call read('classpath:e_invoice_adapter/space/soa/reuse-soa.feature@spaceSoaSend') eInvoiceTestData * set eInvoiceTestData.postSOA.requestUri = sendEInvoiceSoa.requestUri * set eInvoiceTestData.postSOA.response = sendEInvoiceSoa.response * print sendEInvoiceSoa.response # 动态读取预期响应文件 * def expectedResponse = read('classpath:e_invoice_adapter/space/soa/response/validation/' + eInvoiceTestData.expectedResponse) * match sendEInvoiceSoa.response == expectedResponse
方案2:保留子Feature的Scenario Outline,显式绑定参数
如果需要保留子Feature的Scenario Outline结构,需在Examples中明确列出所有需要的参数,而非传递整个eInvoiceTestData对象:
修改后的子Feature代码示例:
Feature: Send e-invoice standing order agreement with Space user process Scenario Outline: Process e-invoice SOA request * def soaRequest = {"input": {"agreement": {}}} Given eval if ('<removeParameter>' != 'x') karate.remove('soaRequest', '<removeParameter>') Given eval if (<systemId> != 'x') karate.set('soaRequest', 'input.agreement.systemId', <systemId>) # 其余参数绑定逻辑保持不变... * print soaRequest * def eInvoiceTestData = { postSOA: { request: soaRequest }, expectedResponse: '<expectedResponse>' } * def sendEInvoiceSoa = call read('classpath:e_invoice_adapter/space/soa/reuse-soa.feature@spaceSoaSend') eInvoiceTestData * set eInvoiceTestData.postSOA.requestUri = sendEInvoiceSoa.requestUri * set eInvoiceTestData.postSOA.response = sendEInvoiceSoa.response * print sendEInvoiceSoa.response * def expectedResponse = read('classpath:e_invoice_adapter/space/soa/response/validation/<expectedResponse>') * match sendEInvoiceSoa.response == expectedResponse Examples: | removeParameter | systemId | sellerRegistrationNumber | ... | expectedResponse | | x | 123 | SE123456789 | ... | success.json | | input.agreement | x | x | ... | missing_systemid.json |
同步修改父Feature,将CSV数据拆分为单个参数传递给子Feature的Scenario Outline。
验证步骤
- 运行父Feature的Scenario Outline,确认每条测试数据的变量都能正确解析
- 对比1.3.0版本修复后的测试报告与1.2.0版本的报告,确保测试结果一致
- 运行Debugging Scenario,验证单条数据的参数传递和处理逻辑正常
内容的提问来源于stack exchange,提问作者Ģirts Miķelsons
相关产品推荐
相关产品推荐

