You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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。

验证步骤

  1. 运行父Feature的Scenario Outline,确认每条测试数据的变量都能正确解析
  2. 对比1.3.0版本修复后的测试报告与1.2.0版本的报告,确保测试结果一致
  3. 运行Debugging Scenario,验证单条数据的参数传递和处理逻辑正常

内容的提问来源于stack exchange,提问作者Ģirts Miķelsons

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 13:15:33