Karate Schema验证中可选变量的意外求值问题
Karate嵌套可选Schema解析问题:原因与解决方案
是否该提交Bug?
这不是Bug,是Karate变量解析的预期行为:
- 先定义
nestedSchema再定义outerSchema时,##(nestedSchema)会被立即解析为具体的Schema结构,此时outerSchema里的nested字段会被当作必填属性检查——你的测试负载sut里没有nested字段,自然验证失败。 - 先定义
outerSchema时,nestedSchema还未存在,##(nestedSchema)会被保留为“可选占位符”,Karate执行match contains时只会检查已存在的字段,不会强制要求nested出现,因此验证通过。
实际场景(用read()加载Schema)的解决方案
如果通过read()从外部文件加载Schema,可通过以下方式实现可选嵌套属性定义:
方法一:用
#?标记可选属性
在嵌套Schema引用前加上#?,明确标记该属性为可选,即使引用的变量已存在,也不会强制验证字段存在:* def nestedSchema = read('classpath:nested-schema.json') * def outerSchema = { "id": "#uuid", "nested": "#? ##(nestedSchema)" }方法二:用函数延迟Schema解析
将嵌套Schema定义为函数,仅当目标字段存在时才执行解析:* def nestedSchema = () => read('classpath:nested-schema.json') * def outerSchema = { "id": "#uuid", "nested": "##(nestedSchema())" }这种方式下,
nested字段不存在时函数不会被调用,不会触发嵌套Schema的验证。方法三:直接在外部Schema中结合
read()与#?
跳过变量定义,直接在外部Schema里引用文件并标记可选,适合不需要重复使用嵌套Schema的场景:* def outerSchema = { "id": "#uuid", "nested": "#? read('classpath:nested-schema.json')" }
修正后的测试示例
以下两种修正后的场景均可通过验证:
Feature: Nested optional schema (fixed) Background: * def sut = { "id": "123e4567-e89b-12d3-a456-426614174000" } Scenario: Fixed with #? marker * def nestedSchema = { "attribute": "#string" } * def outerSchema = { "id": "#uuid", "nested": "#? ##(nestedSchema)" } * karate.log(outerSchema) Then match sut contains outerSchema Scenario: Fixed with function * def nestedSchema = () => { "attribute": "#string" } * def outerSchema = { "id": "#uuid", "nested": "##(nestedSchema())" } * karate.log(outerSchema) Then match sut contains outerSchema
内容的提问来源于stack exchange,提问作者Bastian Friedrich
相关产品推荐
相关产品推荐

