使用Python3.6 unittest assertRaisesRegex
验证某些JSON时,在JSON oneOf
关键字下验证代码与不验证代码之间生成的输出存在差异。我正在测试required
属性的删除。
问题是用户需要一种类型的错误消息,但收到另一种错误消息,而assertRaisesRegex
失败,因为它与正则表达式不匹配。
使用http://json-schema-validator.herokuapp.com验证JSON我看到预期的实际错误消息已经嵌套得更深。
我可以通过在测试oneOf
属性时搜索新消息来解决问题,但想知道是否有更好的方法来处理与我的其他测试一致的问题,即使用我希望的消息格式相同吗?
下面是一些输出的示例,用于测试要移除的required
JSON属性。预期的邮件格式标有=>
意外的**
示例1(herokuapp.com
):删除required
属性时(不在oneOf
下)
[ {
"level" : "error",
"schema" : {
"loadingURI" : "#",
"pointer" : "/properties/Attr_B"
},
"instance" : {
"pointer" : "/Attr_B"
},
"domain" : "validation",
"keyword" : "required",
=>"message" : "object has missing required properties ([\"alpha\"])",
"required" : [ "alpha", "beta" ],
"missing" : [ "alpha" ]
} ]
示例2(herokuapp.com
):删除oneOf
嵌套required
属性时
[ {
"level" : "error",
"schema" : {
"loadingURI" : "#",
"pointer" : "/properties/Attr_B/properties/beta"
},
"instance" : {
"pointer" : "/Attr_B/beta"
},
"domain" : "validation",
"keyword" : "oneOf",
**"message" : "instance failed to match exactly one schema (matched 0 out of 1)",
"matched" : 0,
"nrSchemas" : 1,
"reports" : {
"/properties/Attr_B/properties/beta/oneOf/0" : [ {
"level" : "error",
"schema" : {
"loadingURI" : "#",
"pointer" : "/properties/Attr_B/properties/beta/oneOf/0"
},
"instance" : {
"pointer" : "/Attr_B/beta"
},
"domain" : "validation",
"keyword" : "required",
=> "message" : "object has missing required properties ([\"min_percentage\"])",
"required" : [ "max_percentage", "min_percentage" ],
"missing" : [ "min_percentage" ]
} ]
}
} ]
在我使用jsonschema
的单元测试中,消息有所不同,但问题是相同的。
示例1(jsonschema
):删除required
属性时(不在oneOf
下)
E
======================================================================
ERROR: test_valid__JSON_against_schema (__main__.SchemaTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test.py", line 42, in test_valid__JSON_against_schema
validate(test_json, test_schema)
File "/local_scratch/tools/PACKAGES/Python-3.6.1/lib/python3.6/site-packages/jsonschema/validators.py", line 541, in validate
cls(schema, *args, **kwargs).validate(instance)
File "/local_scratch/tools/PACKAGES/Python-3.6.1/lib/python3.6/site-packages/jsonschema/validators.py", line 130, in validate
raise error
=> jsonschema.exceptions.ValidationError: 'alpha' is a required property
Failed validating 'required' in schema['properties']['Attr_B']:
{'additionalProperties': False,
'properties': {'alpha': {'enum': ['a', 'b'], 'type': 'string'},
'beta': {'oneOf': [{'additionalProperties': False,
'properties': {'max_percentage': {'additionalProperties': False,
'maximum': 150,
'minimum': 10,
'type': 'integer'},
'min_percentage': {'additionalProperties': False,
'maximum': 50,
'minimum': 1,
'type': 'integer'}},
'required': ['min_percentage',
'max_percentage'],
'type': 'object'}]}},
'required': ['alpha', 'beta'],
'type': 'object'}
On instance['Attr_B']:
{'beta': {'max_percentage': 24, 'min_percentage': 24}}
----------------------------------------------------------------------
Ran 1 test in 0.004s
FAILED (errors=1)
示例2(jsonschema
):删除oneOf
嵌套required
属性时
E
======================================================================
ERROR: test_valid__JSON_against_schema (__main__.SchemaTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test.py", line 42, in test_valid__JSON_against_schema
validate(test_json, test_schema)
File "/local_scratch/tools/PACKAGES/Python-3.6.1/lib/python3.6/site-packages/jsonschema/validators.py", line 541, in validate
cls(schema, *args, **kwargs).validate(instance)
File "/local_scratch/tools/PACKAGES/Python-3.6.1/lib/python3.6/site-packages/jsonschema/validators.py", line 130, in validate
raise error
** jsonschema.exceptions.ValidationError: {'max_percentage': 24} is not valid under any of the given schemas
Failed validating 'oneOf' in schema['properties']['Attr_B']['properties']['beta']:
{'oneOf': [{'additionalProperties': False,
'properties': {'max_percentage': {'additionalProperties': False,
'maximum': 150,
'minimum': 10,
'type': 'integer'},
'min_percentage': {'additionalProperties': False,
'maximum': 50,
'minimum': 1,
'type': 'integer'}},
'required': ['min_percentage', 'max_percentage'],
'type': 'object'}]}
On instance['Attr_B']['beta']:
{'max_percentage': 24}
----------------------------------------------------------------------
Ran 1 test in 0.005s
FAILED (errors=1)
我正在验证此架构
{
"id": "a-schema",
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "my schema",
"type": "object",
"properties": {
"Attr_A": {
"type": "integer",
"minimum" : 1,
"maximum" : 200,
"additionalProperties": false
},
"Attr_B": {
"type": "object",
"properties": {
"alpha": {
"type": "string",
"enum": ["a", "b"]
},
"beta": {
"oneOf": [
{
"type": "object",
"properties": {
"min_percentage": {
"type": "integer",
"minimum" : 1,
"maximum" : 50,
"additionalProperties": false
},
"max_percentage": {
"type": "integer",
"minimum" : 10,
"maximum" : 150,
"additionalProperties": false
}
},
"additionalProperties": false,
"required": ["min_percentage", "max_percentage"]
}
]
}
},
"additionalProperties": false,
"required": ["alpha", "beta"]
},
"Attr_C": {
"type": "object",
"properties": {
"min_percentage": {
"type": "integer",
"minimum" : 1,
"maximum" : 50,
"additionalProperties": false
},
"max_percentage": {
"type": "integer",
"minimum": 10,
"maximum": 150,
"additionalProperties": false
}
},
"additionalProperties": false,
"required": ["min_percentage", "max_percentage"]
}
},
"additionalProperties": false,
"required": ["Attr_A", "Attr_B", "Attr_C"]
}
这是我的实例数据
{
"Attr_A": 123,
"Attr_B": {
"alpha": "a",
"beta": {
"min_percentage": 20,
"max_percentage": 24
}
},
"Attr_C": {
"min_percentage": 20,
"max_percentage": 24
}
}
这些是我的测试
with open("schema.json") as schema_file:
test_schema = json.load(schema_file)
schema_file.close()
with open("test.json") as json_file:
test_json = json.load(json_file)
json_file.close()
### Test the whole JSON is valid against the Schema
def test_valid__JSON_against_schema(self):
global test_schema
global test_json
validate(test_json, test_schema)
### 'Attr_B.alpha' test
def test_missing__Attr_B_alpha(self):
global test_schema
global test_json
dict_copy = copy.deepcopy(test_json)
dict_copy.pop("alpha")
msg = "'alpha' is a required property"
with self.assertRaisesRegex(ValidationError, msg):
validate(dict_copy, test_schema)
### 'Attr_B.beta.min_percentage' test
def test_missing__Attr_B_beta_min_percentage(self):
global test_schema
global test_json
dict_copy = copy.deepcopy(test_json)
test_info = dict_copy["Attr_B"]
beta= test_info["beta"]
beta.pop("min_percentage")
msg = "'min_percentage' is a required property"
with self.assertRaisesRegex(ValidationError, msg):
validate(dict_copy, test_schema)