mirror of
https://github.com/httprunner/httprunner.git
synced 2026-07-07 07:21:23 +08:00
validator: check item support reference variable
This commit is contained in:
@@ -1 +1 @@
|
|||||||
__version__ = '0.8.4'
|
__version__ = '0.8.5'
|
||||||
@@ -4,8 +4,7 @@ import re
|
|||||||
import sys
|
import sys
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from httprunner import exception, utils
|
from httprunner import exception, testcase, utils
|
||||||
from httprunner.testcase import TestcaseParser
|
|
||||||
|
|
||||||
|
|
||||||
class Context(object):
|
class Context(object):
|
||||||
@@ -15,7 +14,7 @@ class Context(object):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.testset_shared_variables_mapping = OrderedDict()
|
self.testset_shared_variables_mapping = OrderedDict()
|
||||||
self.testcase_variables_mapping = OrderedDict()
|
self.testcase_variables_mapping = OrderedDict()
|
||||||
self.testcase_parser = TestcaseParser()
|
self.testcase_parser = testcase.TestcaseParser()
|
||||||
self.init_context()
|
self.init_context()
|
||||||
|
|
||||||
def init_context(self, level='testset'):
|
def init_context(self, level='testset'):
|
||||||
@@ -170,6 +169,75 @@ class Context(object):
|
|||||||
"""
|
"""
|
||||||
self.testcase_parser.eval_content_functions(content)
|
self.testcase_parser.eval_content_functions(content)
|
||||||
|
|
||||||
|
def parse_validator(self, validator, resp_obj):
|
||||||
|
""" parse validator, validator maybe in two format
|
||||||
|
@param (dict) validator
|
||||||
|
format1: this is kept for compatiblity with the previous versions.
|
||||||
|
{"check": "status_code", "comparator": "eq", "expect": 201}
|
||||||
|
{"check": "$resp_body_success", "comparator": "eq", "expect": True}
|
||||||
|
format2: recommended new version
|
||||||
|
{'eq': ['status_code', 201]}
|
||||||
|
{'eq': ['$resp_body_success', True]}
|
||||||
|
@param (object) resp_obj
|
||||||
|
@return (dict) validator info
|
||||||
|
{
|
||||||
|
"check_item": check_item,
|
||||||
|
"check_value": check_value,
|
||||||
|
"expect_value": expect_value,
|
||||||
|
"comparator": comparator
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
if not isinstance(validator, dict):
|
||||||
|
raise exception.ParamsError("invalid validator: {}".format(validator))
|
||||||
|
|
||||||
|
if "check" in validator and len(validator) > 1:
|
||||||
|
# format1
|
||||||
|
check_item = validator.get("check")
|
||||||
|
|
||||||
|
if "expect" in validator:
|
||||||
|
expect_value = validator.get("expect")
|
||||||
|
elif "expected" in validator:
|
||||||
|
expect_value = validator.get("expected")
|
||||||
|
else:
|
||||||
|
raise exception.ParamsError("invalid validator: {}".format(validator))
|
||||||
|
|
||||||
|
comparator = validator.get("comparator", "eq")
|
||||||
|
|
||||||
|
elif len(validator) == 1:
|
||||||
|
# format2
|
||||||
|
comparator = list(validator.keys())[0]
|
||||||
|
compare_values = validator[comparator]
|
||||||
|
|
||||||
|
if not isinstance(compare_values, list) or len(compare_values) != 2:
|
||||||
|
raise exception.ParamsError("invalid validator: {}".format(validator))
|
||||||
|
|
||||||
|
check_item, expect_value = compare_values
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise exception.ParamsError("invalid validator: {}".format(validator))
|
||||||
|
|
||||||
|
# check_item should only be in 3 type:
|
||||||
|
# 1, variable reference, e.g. $token
|
||||||
|
# 2, string joined by delimiter. e.g. "status_code", "headers.content-type"
|
||||||
|
# 3, regex string, e.g. "LB[\d]*(.*)RB[\d]*"
|
||||||
|
if testcase.extract_variables(check_item):
|
||||||
|
# type 1
|
||||||
|
check_value = self.testcase_parser.eval_content_variables(check_item)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
# type 2 or type 3
|
||||||
|
check_value = resp_obj.extract_field(check_item)
|
||||||
|
except exception.ParseResponseError:
|
||||||
|
raise exception.ParseResponseError("failed to extract check item in response!")
|
||||||
|
|
||||||
|
validator_dict = {
|
||||||
|
"check_item": check_item,
|
||||||
|
"check_value": check_value,
|
||||||
|
"expect_value": expect_value,
|
||||||
|
"comparator": comparator
|
||||||
|
}
|
||||||
|
return validator_dict
|
||||||
|
|
||||||
def do_validation(self, validator_dict):
|
def do_validation(self, validator_dict):
|
||||||
""" validate with functions
|
""" validate with functions
|
||||||
"""
|
"""
|
||||||
@@ -202,10 +270,8 @@ class Context(object):
|
|||||||
@param (list) validators
|
@param (list) validators
|
||||||
@param (object) resp_obj
|
@param (object) resp_obj
|
||||||
"""
|
"""
|
||||||
variables_mapping = self.get_testcase_variables_mapping()
|
|
||||||
|
|
||||||
for validator in validators:
|
for validator in validators:
|
||||||
validator_dict = resp_obj.parse_validator(validator, variables_mapping)
|
validator_dict = self.parse_validator(validator, resp_obj)
|
||||||
self.do_validation(validator_dict)
|
self.do_validation(validator_dict)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import logging
|
|||||||
import re
|
import re
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from httprunner import exception, utils
|
from httprunner import exception, utils, testcase
|
||||||
from requests.structures import CaseInsensitiveDict
|
from requests.structures import CaseInsensitiveDict
|
||||||
|
|
||||||
text_extractor_regexp_compile = re.compile(r".*\(.*\).*")
|
text_extractor_regexp_compile = re.compile(r".*\(.*\).*")
|
||||||
@@ -123,69 +123,3 @@ class ResponseObject(object):
|
|||||||
extracted_variables_mapping[key] = self.extract_field(field)
|
extracted_variables_mapping[key] = self.extract_field(field)
|
||||||
|
|
||||||
return extracted_variables_mapping
|
return extracted_variables_mapping
|
||||||
|
|
||||||
def parse_validator(self, validator, variables_mapping):
|
|
||||||
""" parse validator, validator maybe in two format
|
|
||||||
@param (dict) validator
|
|
||||||
format1: this is kept for compatiblity with the previous versions.
|
|
||||||
{"check": "status_code", "comparator": "eq", "expect": 201}
|
|
||||||
{"check": "resp_body_success", "comparator": "eq", "expect": True}
|
|
||||||
format2: recommended new version
|
|
||||||
{'eq': ['status_code', 201]}
|
|
||||||
{'eq': ['resp_body_success', True]}
|
|
||||||
@param (dict) variables_mapping
|
|
||||||
{
|
|
||||||
"resp_body_success": True
|
|
||||||
}
|
|
||||||
@return (dict) validator info
|
|
||||||
{
|
|
||||||
"check_item": check_item,
|
|
||||||
"check_value": check_value,
|
|
||||||
"expect_value": expect_value,
|
|
||||||
"comparator": comparator
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
if not isinstance(validator, dict):
|
|
||||||
raise exception.ParamsError("invalid validator: {}".format(validator))
|
|
||||||
|
|
||||||
if "check" in validator and len(validator) > 1:
|
|
||||||
# format1
|
|
||||||
check_item = validator.get("check")
|
|
||||||
|
|
||||||
if "expect" in validator:
|
|
||||||
expect_value = validator.get("expect")
|
|
||||||
elif "expected" in validator:
|
|
||||||
expect_value = validator.get("expected")
|
|
||||||
else:
|
|
||||||
raise exception.ParamsError("invalid validator: {}".format(validator))
|
|
||||||
|
|
||||||
comparator = validator.get("comparator", "eq")
|
|
||||||
|
|
||||||
elif len(validator) == 1:
|
|
||||||
# format2
|
|
||||||
comparator = list(validator.keys())[0]
|
|
||||||
compare_values = validator[comparator]
|
|
||||||
|
|
||||||
if not isinstance(compare_values, list) or len(compare_values) != 2:
|
|
||||||
raise exception.ParamsError("invalid validator: {}".format(validator))
|
|
||||||
|
|
||||||
check_item, expect_value = compare_values
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise exception.ParamsError("invalid validator: {}".format(validator))
|
|
||||||
|
|
||||||
if check_item in variables_mapping:
|
|
||||||
check_value = variables_mapping[check_item]
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
check_value = self.extract_field(check_item)
|
|
||||||
except exception.ParseResponseError:
|
|
||||||
raise exception.ParseResponseError("failed to extract check item in response!")
|
|
||||||
|
|
||||||
validator_dict = {
|
|
||||||
"check_item": check_item,
|
|
||||||
"check_value": check_value,
|
|
||||||
"expect_value": expect_value,
|
|
||||||
"comparator": comparator
|
|
||||||
}
|
|
||||||
return validator_dict
|
|
||||||
|
|||||||
@@ -15,11 +15,11 @@
|
|||||||
- token: content.token
|
- token: content.token
|
||||||
validate:
|
validate:
|
||||||
- eq: ["status_code", 200]
|
- eq: ["status_code", 200]
|
||||||
- len_eq: ["token", 16]
|
- len_eq: ["$token", 16]
|
||||||
- len_eq: ["content.token", 16]
|
- len_eq: ["content.token", 16]
|
||||||
- {"check": "status_code", "comparator": "eq", "expect": 200}
|
- {"check": "status_code", "comparator": "eq", "expect": 200}
|
||||||
- sum_status_code: ["status_code", 2]
|
- sum_status_code: ["status_code", 2]
|
||||||
- {"check": "token", "comparator": "len_eq", "expect": 16}
|
- {"check": "$token", "comparator": "len_eq", "expect": 16}
|
||||||
|
|
||||||
- test:
|
- test:
|
||||||
name: create user which does not exist
|
name: create user which does not exist
|
||||||
@@ -33,10 +33,13 @@
|
|||||||
json:
|
json:
|
||||||
name: "user1"
|
name: "user1"
|
||||||
password: "123456"
|
password: "123456"
|
||||||
|
extract:
|
||||||
|
- success: content.success
|
||||||
validate:
|
validate:
|
||||||
- eq: ["status_code", 201]
|
- eq: ["status_code", 201]
|
||||||
- sum_status_code: ["status_code", 3]
|
- sum_status_code: ["status_code", 3]
|
||||||
- eq: ["content.success", True]
|
- eq: ["$success", True]
|
||||||
|
- eq: ["abc$success", "abcTrue"]
|
||||||
- {"check": "status_code", "comparator": "eq", "expect": 201}
|
- {"check": "status_code", "comparator": "eq", "expect": 201}
|
||||||
- {"check": "content.success", "comparator": "eq", "expect": true}
|
- {"check": "content.success", "comparator": "eq", "expect": true}
|
||||||
|
|
||||||
|
|||||||
@@ -240,9 +240,9 @@ class VariableBindsUnittest(ApiServerUnittest):
|
|||||||
resp_obj = response.ResponseObject(resp)
|
resp_obj = response.ResponseObject(resp)
|
||||||
|
|
||||||
validators = [
|
validators = [
|
||||||
{"eq": ["resp_status_code", 201]},
|
{"eq": ["$resp_status_code", 201]},
|
||||||
{"check": "resp_status_code", "comparator": "eq", "expect": 201},
|
{"check": "$resp_status_code", "comparator": "eq", "expect": 201},
|
||||||
{"check": "resp_body_success", "comparator": "eq", "expect": True}
|
{"check": "$resp_body_success", "comparator": "eq", "expect": True}
|
||||||
]
|
]
|
||||||
variables = [
|
variables = [
|
||||||
{"resp_status_code": 200},
|
{"resp_status_code": 200},
|
||||||
@@ -268,9 +268,9 @@ class VariableBindsUnittest(ApiServerUnittest):
|
|||||||
|
|
||||||
# expected value missed in validators
|
# expected value missed in validators
|
||||||
validators = [
|
validators = [
|
||||||
{"eq": ["resp_status_code", 201]},
|
{"eq": ["$resp_status_code", 201]},
|
||||||
{"check": "resp_status_code", "comparator": "eq", "expect": 201},
|
{"check": "$resp_status_code", "comparator": "eq", "expect": 201},
|
||||||
{"check": "resp_body_success", "comparator": "eq", "expect": True}
|
{"check": "$resp_body_success", "comparator": "eq", "expect": True}
|
||||||
]
|
]
|
||||||
variables = []
|
variables = []
|
||||||
self.context.bind_variables(variables)
|
self.context.bind_variables(variables)
|
||||||
|
|||||||
Reference in New Issue
Block a user