mirror of
https://github.com/httprunner/httprunner.git
synced 2026-07-11 15:31:37 +08:00
display validators in report log
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
__title__ = 'HttpRunner'
|
__title__ = 'HttpRunner'
|
||||||
__description__ = 'One-stop solution for HTTP(S) testing.'
|
__description__ = 'One-stop solution for HTTP(S) testing.'
|
||||||
__url__ = 'https://github.com/HttpRunner/HttpRunner'
|
__url__ = 'https://github.com/HttpRunner/HttpRunner'
|
||||||
__version__ = '1.5.0'
|
__version__ = '1.5.1'
|
||||||
__author__ = 'debugtalk'
|
__author__ = 'debugtalk'
|
||||||
__author_email__ = 'mail@debugtalk.com'
|
__author_email__ = 'mail@debugtalk.com'
|
||||||
__license__ = 'MIT'
|
__license__ = 'MIT'
|
||||||
|
|||||||
@@ -216,6 +216,7 @@ class Context(object):
|
|||||||
# 2, actual value, e.g. 200
|
# 2, actual value, e.g. 200
|
||||||
expect_value = self.eval_content(validator["expect"])
|
expect_value = self.eval_content(validator["expect"])
|
||||||
validator["expect"] = expect_value
|
validator["expect"] = expect_value
|
||||||
|
validator["check_result"] = "unchecked"
|
||||||
return validator
|
return validator
|
||||||
|
|
||||||
def do_validation(self, validator_dict):
|
def do_validation(self, validator_dict):
|
||||||
@@ -237,6 +238,7 @@ class Context(object):
|
|||||||
raise exception.ParamsError("Null value can only be compared with comparator: eq/equals/==")
|
raise exception.ParamsError("Null value can only be compared with comparator: eq/equals/==")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
validator_dict["check_result"] = "passed"
|
||||||
validate_func(validator_dict["check_value"], validator_dict["expect"])
|
validate_func(validator_dict["check_value"], validator_dict["expect"])
|
||||||
except (AssertionError, TypeError):
|
except (AssertionError, TypeError):
|
||||||
err_msg = "\n" + "\n".join([
|
err_msg = "\n" + "\n".join([
|
||||||
@@ -245,18 +247,22 @@ class Context(object):
|
|||||||
"\tcomparator: %s;" % comparator,
|
"\tcomparator: %s;" % comparator,
|
||||||
"\texpected value: %s (%s)." % (expect_value, type(expect_value).__name__)
|
"\texpected value: %s (%s)." % (expect_value, type(expect_value).__name__)
|
||||||
])
|
])
|
||||||
|
validator_dict["check_result"] = "failed"
|
||||||
raise exception.ValidationError(err_msg)
|
raise exception.ValidationError(err_msg)
|
||||||
|
|
||||||
def validate(self, validators, resp_obj):
|
def eval_validators(self, validators, resp_obj):
|
||||||
""" check validators with the context variable mapping.
|
""" evaluate validators with context variable mapping.
|
||||||
@param (list) validators
|
|
||||||
@param (object) resp_obj
|
|
||||||
"""
|
"""
|
||||||
for validator in validators:
|
return [
|
||||||
validator_dict = self.eval_check_item(
|
self.eval_check_item(
|
||||||
testcase.parse_validator(validator),
|
testcase.parse_validator(validator),
|
||||||
resp_obj
|
resp_obj
|
||||||
)
|
)
|
||||||
self.do_validation(validator_dict)
|
for validator in validators
|
||||||
|
]
|
||||||
|
|
||||||
return True
|
def validate(self, validators):
|
||||||
|
""" make validations
|
||||||
|
"""
|
||||||
|
for validator_dict in validators:
|
||||||
|
self.do_validation(validator_dict)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class Runner(object):
|
|||||||
|
|
||||||
def __init__(self, config_dict=None, http_client_session=None):
|
def __init__(self, config_dict=None, http_client_session=None):
|
||||||
self.http_client_session = http_client_session
|
self.http_client_session = http_client_session
|
||||||
|
self.evaluated_validators = []
|
||||||
self.context = Context()
|
self.context = Context()
|
||||||
|
|
||||||
config_dict = config_dict or {}
|
config_dict = config_dict or {}
|
||||||
@@ -178,11 +179,12 @@ class Runner(object):
|
|||||||
extractors = testcase_dict.get("extract", []) or testcase_dict.get("extractors", [])
|
extractors = testcase_dict.get("extract", []) or testcase_dict.get("extractors", [])
|
||||||
extracted_variables_mapping = resp_obj.extract_response(extractors)
|
extracted_variables_mapping = resp_obj.extract_response(extractors)
|
||||||
self.context.bind_extracted_variables(extracted_variables_mapping)
|
self.context.bind_extracted_variables(extracted_variables_mapping)
|
||||||
|
|
||||||
# validate
|
# validate
|
||||||
validators = testcase_dict.get("validate", []) or testcase_dict.get("validators", [])
|
validators = testcase_dict.get("validate", []) or testcase_dict.get("validators", [])
|
||||||
try:
|
try:
|
||||||
self.context.validate(validators, resp_obj)
|
self.evaluated_validators = self.context.eval_validators(validators, resp_obj)
|
||||||
|
self.context.validate(self.evaluated_validators)
|
||||||
except (exception.ParamsError, exception.ResponseError, \
|
except (exception.ParamsError, exception.ResponseError, \
|
||||||
exception.ValidationError, exception.ParseResponseError):
|
exception.ValidationError, exception.ParseResponseError):
|
||||||
# log request
|
# log request
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class TestCase(unittest.TestCase):
|
|||||||
finally:
|
finally:
|
||||||
if hasattr(self.test_runner.http_client_session, "meta_data"):
|
if hasattr(self.test_runner.http_client_session, "meta_data"):
|
||||||
self.meta_data = self.test_runner.http_client_session.meta_data
|
self.meta_data = self.test_runner.http_client_session.meta_data
|
||||||
|
self.meta_data["validators"] = self.test_runner.evaluated_validators
|
||||||
self.test_runner.http_client_session.init_meta_data()
|
self.test_runner.http_client_session.init_meta_data()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,15 @@
|
|||||||
background-color: skyblue;
|
background-color: skyblue;
|
||||||
padding: 5px 12px;
|
padding: 5px 12px;
|
||||||
}
|
}
|
||||||
|
.details tr .passed {
|
||||||
|
background-color: lightgreen;
|
||||||
|
}
|
||||||
|
.details tr .failed {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
.details tr .unchecked {
|
||||||
|
background-color: gray;
|
||||||
|
}
|
||||||
.details td {
|
.details td {
|
||||||
background-color: lightblue;
|
background-color: lightblue;
|
||||||
padding: 5px 12px;
|
padding: 5px 12px;
|
||||||
@@ -277,6 +286,34 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h3>Validators:</h3>
|
||||||
|
<div style="overflow: auto">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>check</th>
|
||||||
|
<th>comparator</th>
|
||||||
|
<th>expect value</th>
|
||||||
|
<th>actual value</th>
|
||||||
|
</tr>
|
||||||
|
{% for validator in record.meta_data.validators %}
|
||||||
|
<tr>
|
||||||
|
{% if validator.check_result == "passed" %}
|
||||||
|
<td class="passed">
|
||||||
|
{% elif validator.check_result == "failed" %}
|
||||||
|
<td class="failed">
|
||||||
|
{% elif validator.check_result == "unchecked" %}
|
||||||
|
<td class="unchecked">
|
||||||
|
{% endif %}
|
||||||
|
{{validator.check}}
|
||||||
|
</td>
|
||||||
|
<td>{{validator.comparator}}</td>
|
||||||
|
<td>{{validator.expect}}</td>
|
||||||
|
<td>{{validator.check_value}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h3>Statistics:</h3>
|
<h3>Statistics:</h3>
|
||||||
<div style="overflow: auto">
|
<div style="overflow: auto">
|
||||||
<table>
|
<table>
|
||||||
|
|||||||
@@ -262,8 +262,7 @@ class VariableBindsUnittest(ApiServerUnittest):
|
|||||||
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}
|
||||||
{"check": "${is_status_code_200($resp_status_code)}", "comparator": "eq", "expect": False}
|
|
||||||
]
|
]
|
||||||
variables = [
|
variables = [
|
||||||
{"resp_status_code": 200},
|
{"resp_status_code": 200},
|
||||||
@@ -272,8 +271,15 @@ class VariableBindsUnittest(ApiServerUnittest):
|
|||||||
self.context.bind_variables(variables)
|
self.context.bind_variables(variables)
|
||||||
|
|
||||||
with self.assertRaises(exception.ValidationError):
|
with self.assertRaises(exception.ValidationError):
|
||||||
self.context.validate(validators, resp_obj)
|
evaluated_validators = self.context.eval_validators(validators, resp_obj)
|
||||||
|
self.context.validate(evaluated_validators)
|
||||||
|
|
||||||
|
validators = [
|
||||||
|
{"eq": ["$resp_status_code", 201]},
|
||||||
|
{"check": "$resp_status_code", "comparator": "eq", "expect": 201},
|
||||||
|
{"check": "$resp_body_success", "comparator": "eq", "expect": True},
|
||||||
|
{"check": "${is_status_code_200($resp_status_code)}", "comparator": "eq", "expect": False}
|
||||||
|
]
|
||||||
variables = [
|
variables = [
|
||||||
{"resp_status_code": 201},
|
{"resp_status_code": 201},
|
||||||
{"resp_body_success": True}
|
{"resp_body_success": True}
|
||||||
@@ -285,7 +291,8 @@ class VariableBindsUnittest(ApiServerUnittest):
|
|||||||
}
|
}
|
||||||
self.context.bind_functions(functions)
|
self.context.bind_functions(functions)
|
||||||
|
|
||||||
self.assertTrue(self.context.validate(validators, resp_obj))
|
evaluated_validators = self.context.eval_validators(validators, resp_obj)
|
||||||
|
self.context.validate(evaluated_validators)
|
||||||
|
|
||||||
def test_validate_exception(self):
|
def test_validate_exception(self):
|
||||||
url = "http://127.0.0.1:5000/"
|
url = "http://127.0.0.1:5000/"
|
||||||
@@ -295,14 +302,14 @@ 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}
|
|
||||||
]
|
]
|
||||||
variables = []
|
variables = []
|
||||||
self.context.bind_variables(variables)
|
self.context.bind_variables(variables)
|
||||||
|
|
||||||
with self.assertRaises(exception.ParamsError):
|
with self.assertRaises(exception.ParamsError):
|
||||||
self.context.validate(validators, resp_obj)
|
evaluated_validators = self.context.eval_validators(validators, resp_obj)
|
||||||
|
self.context.validate(evaluated_validators)
|
||||||
|
|
||||||
# expected value missed in variables mapping
|
# expected value missed in variables mapping
|
||||||
variables = [
|
variables = [
|
||||||
@@ -311,4 +318,5 @@ class VariableBindsUnittest(ApiServerUnittest):
|
|||||||
self.context.bind_variables(variables)
|
self.context.bind_variables(variables)
|
||||||
|
|
||||||
with self.assertRaises(exception.ValidationError):
|
with self.assertRaises(exception.ValidationError):
|
||||||
self.context.validate(validators, resp_obj)
|
evaluated_validators = self.context.eval_validators(validators, resp_obj)
|
||||||
|
self.context.validate(evaluated_validators)
|
||||||
|
|||||||
Reference in New Issue
Block a user