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

如何解决跨Scenario调用子Schema定义变量时的未定义错误

问题原因

当你用karate.call调用@validateCommonSchema这个Scenario时,被调用Scenario里定义的bicyclesSchema变量仅存在于它自身的执行上下文,不会自动传递到调用方的上下文。而你返回的PIMSchema里引用了##(bicyclesSchema),当调用方使用这个PIMSchema时,当前上下文找不到该变量,就会抛出未定义的错误。

解决方案

下面提供几种可行的解决方式:

方法1:返回所有依赖的Schema变量

修改被调用的Scenario,最后返回一个包含所有需要复用的Schema的对象,调用方拿到后将所有变量定义到当前上下文:

@validateCommonSchema
Scenario: validate the Common Schema
  * def accountSchema =
  """
  {
  "displayName":'#string'
  }
  """
  * def bicyclesSchema =
  """
  {
  "status_Ext": '#string'
  }
  """
  * def PIMSchema =
  """
  {
  "PIM": {
  "bicycleExists": '#boolean',
  "totalDiscount":{
   "amount": '#string'
   },
  "bicycles": '#[] ##(bicyclesSchema)'
  }
  }
  """
  # 最后返回包含所有Schema的对象
  * return { accountSchema: accountSchema, bicyclesSchema: bicyclesSchema, PIMSchema: PIMSchema }

修改调用方代码,把所有返回的变量都定义到当前上下文:

@id=ValidateMainSchema
Scenario: Validate the Main Schema
  * def reqPayloadFile = sharedPath + 'SchemaValidationTrial.json'
  * def reqPayload = read(reqPayloadFile)
  * def commonSchemaRef=karate.call(sharedPath+'PPPPartnerEventsActions.feature'+'@validateCommonSchema')
  * def accountMainSchema = commonSchemaRef.accountSchema
  * def bicyclesMainSchema = commonSchemaRef.bicyclesSchema
  * def PIMMainSchema = commonSchemaRef.PIMSchema
  * def MainSchema =
  """
  {
  "accessedByMember": '#boolean',
  "account": '##(accountMainSchema)',
  "line": '##(PIMMainSchema)'
  }
  """
  * match reqPayload == '##(MainSchema)'

这样调用方上下文就有了bicyclesMainSchema,PIMMainSchema里的引用就能正常解析。

方法2:内嵌子Schema到父Schema中

如果bicyclesSchema仅被PIMSchema依赖,可以直接把它的内容内嵌到PIMSchema里,避免依赖外部变量:

@validateCommonSchema
Scenario: validate the Common Schema
  * def accountSchema =
  """
  {
  "displayName":'#string'
  }
  """
  * def PIMSchema =
  """
  {
  "PIM": {
  "bicycleExists": '#boolean',
  "totalDiscount":{
   "amount": '#string'
   },
  "bicycles": '#[] { "status_Ext": "#string" }'
  }
  }
  """
  * return { accountSchema: accountSchema, PIMSchema: PIMSchema }

这种方式让PIMSchema成为独立的Schema,调用方直接使用即可,不会出现变量未定义的问题。

方法3:使用公共背景定义全局Schema

如果这些Schema需要在多个Scenario中复用,更推荐把它们定义在.feature文件的Background里,或者单独的公共Schema文件中,用karate.callSingle加载,这样所有Scenario都能直接访问:

创建CommonSchemas.feature:

Feature: Common Schema Definitions

Background:
  * def accountSchema =
  """
  {
  "displayName":'#string'
  }
  """
  * def bicyclesSchema =
  """
  {
  "status_Ext": '#string'
  }
  """
  * def PIMSchema =
  """
  {
  "PIM": {
  "bicycleExists": '#boolean',
  "totalDiscount":{
   "amount": '#string'
   },
  "bicycles": '#[] ##(bicyclesSchema)'
  }
  }
  """

在需要的Scenario里加载这个文件:

@id=ValidateMainSchema
Scenario: Validate the Main Schema
  * def reqPayloadFile = sharedPath + 'SchemaValidationTrial.json'
  * def reqPayload = read(reqPayloadFile)
  # 加载公共Schema,所有变量会进入当前上下文
  * karate.callSingle(sharedPath+'CommonSchemas.feature')
  * def MainSchema =
  """
  {
  "accessedByMember": '#boolean',
  "account": '##(accountSchema)',
  "line": '##(PIMSchema)'
  }
  """
  * match reqPayload == '##(MainSchema)'

karate.callSingle只会加载一次,是Karate中复用公共逻辑的最佳实践之一。

内容的提问来源于stack exchange,提问作者THOKCHOM PREMJIT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:08:15