validator: check item support reference variable

This commit is contained in:
debugtalk
2017-12-13 01:12:57 +08:00
parent d079f014d9
commit cd89157fa6
5 changed files with 86 additions and 83 deletions

View File

@@ -1 +1 @@
__version__ = '0.8.4' __version__ = '0.8.5'

View File

@@ -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

View File

@@ -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

View File

@@ -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}

View File

@@ -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)