#29: refactor validator:

1, relocate validate functions;
2, add unittest for custom defined validators.
This commit is contained in:
debugtalk
2017-12-12 23:59:54 +08:00
parent 044a93d1ff
commit d079f014d9
9 changed files with 139 additions and 117 deletions

View File

@@ -4,7 +4,7 @@ import re
import sys
from collections import OrderedDict
from httprunner import utils
from httprunner import exception, utils
from httprunner.testcase import TestcaseParser
@@ -165,10 +165,47 @@ class Context(object):
def get_testcase_variables_mapping(self):
return self.testcase_variables_mapping
def get_testcase_functions_mapping(self):
return self.testcase_functions_config
def exec_content_functions(self, content):
""" execute functions in content.
"""
self.testcase_parser.eval_content_functions(content)
def do_validation(self, validator_dict):
""" validate with functions
"""
comparator = utils.get_uniform_comparator(validator_dict["comparator"])
validate_func = self.testcase_parser.get_bind_item("function", comparator)
if not validate_func:
raise exception.FunctionNotFound("comparator not found: {}".format(comparator))
check_item = validator_dict["check_item"]
check_value = validator_dict["check_value"]
expect_value = validator_dict["expect_value"]
try:
if check_value is None or expect_value is None:
assert comparator in ["is", "eq", "equals", "=="]
validate_func(validator_dict["check_value"], validator_dict["expect_value"])
except (AssertionError, TypeError):
err_msg = "\n" + "\n".join([
"\tcheck item name: %s;" % check_item,
"\tcheck item value: %s (%s);" % (check_value, type(check_value).__name__),
"\tcomparator: %s;" % comparator,
"\texpected value: %s (%s)." % (expect_value, type(expect_value).__name__)
])
raise exception.ValidationError(err_msg)
def validate(self, validators, resp_obj):
""" check validators with the context variable mapping.
@param (list) validators
@param (object) resp_obj
"""
variables_mapping = self.get_testcase_variables_mapping()
for validator in validators:
validator_dict = resp_obj.parse_validator(validator, variables_mapping)
self.do_validation(validator_dict)
return True

View File

@@ -189,39 +189,3 @@ class ResponseObject(object):
"comparator": comparator
}
return validator_dict
def do_validation(self, validator_dict, functions_mapping):
""" validate with functions
"""
comparator = utils.get_uniform_comparator(validator_dict["comparator"])
validate_func = functions_mapping.get(comparator)
if not validate_func:
raise exception.FunctionNotFound("comparator not found: {}".format(comparator))
check_item = validator_dict["check_item"]
check_value = validator_dict["check_value"]
expect_value = validator_dict["expect_value"]
try:
if check_value is None or expect_value is None:
assert comparator in ["is", "eq", "equals", "=="]
validate_func(validator_dict["check_value"], validator_dict["expect_value"])
except (AssertionError, TypeError):
err_msg = "\n" + "\n".join([
"\tcheck item name: %s;" % check_item,
"\tcheck item value: %s (%s);" % (check_value, type(check_value).__name__),
"\tcomparator: %s;" % comparator,
"\texpected value: %s (%s)." % (expect_value, type(expect_value).__name__)
])
raise exception.ValidationError(err_msg)
def validate(self, validators, variables_mapping, functions_mapping):
""" check validators with the context variable mapping.
"""
for validator in validators:
validator_dict = self.parse_validator(validator, variables_mapping)
self.do_validation(validator_dict, functions_mapping)
return True

View File

@@ -129,11 +129,7 @@ class Runner(object):
self.context.bind_extracted_variables(extracted_variables_mapping)
try:
resp_obj.validate(
validators,
self.context.get_testcase_variables_mapping(),
self.context.get_testcase_functions_mapping()
)
self.context.validate(validators, resp_obj)
except (exception.ParamsError, exception.ResponseError, exception.ValidationError):
err_msg = u"Exception occured.\n"
err_msg += u"HTTP request url: {}\n".format(url)

View File

@@ -30,3 +30,13 @@ get_sign_lambda = lambda *args: hmac.new(
def gen_md5(*args):
return hashlib.md5("".join(args).encode('utf-8')).hexdigest()
def sum_status_code(status_code, expect_sum):
""" sum status code digits
e.g. 400 => 4, 201 => 3
"""
sum_value = 0
for digit in str(status_code):
sum_value += int(digit)
assert sum_value == expect_sum

View File

@@ -25,6 +25,7 @@
{"eq": ["status_code", 200]},
{"len_eq": ["content.token", 16]},
{"check": "status_code", "comparator": "eq", "expect": 200},
{"sum_status_code": ["status_code", 2]},
{"check": "content.token", "comparator": "len_eq", "expect": 16}
]
}
@@ -49,6 +50,7 @@
{"eq": ["status_code", 201]},
{"eq": ["content.success", true]},
{"check": "status_code", "comparator": "eq", "expect": 201},
{"sum_status_code": ["status_code", 3]},
{"check": "content.success", "comparator": "eq", "expect": true}
]
}
@@ -73,6 +75,7 @@
{"eq": ["status_code", 500]},
{"eq": ["content.success", false]},
{"check": "status_code", "comparator": "eq", "expect": 500},
{"sum_status_code": ["status_code", 5]},
{"check": "content.success", "comparator": "eq", "expect": false}
]
}

View File

@@ -15,9 +15,11 @@
- token: content.token
validate:
- eq: ["status_code", 200]
- len_eq: ["token", 16]
- len_eq: ["content.token", 16]
- {"check": "status_code", "comparator": "eq", "expect": 200}
- {"check": "content.token", "comparator": "len_eq", "expect": 16}
- sum_status_code: ["status_code", 2]
- {"check": "token", "comparator": "len_eq", "expect": 16}
- test:
name: create user which does not exist
@@ -33,6 +35,7 @@
password: "123456"
validate:
- eq: ["status_code", 201]
- sum_status_code: ["status_code", 3]
- eq: ["content.success", True]
- {"check": "status_code", "comparator": "eq", "expect": 201}
- {"check": "content.success", "comparator": "eq", "expect": true}
@@ -51,6 +54,7 @@
password: "123456"
validate:
- "eq": ["status_code", 500]
- sum_status_code: ["status_code", 5]
- "eq": ["content.success", false]
- {"check": "status_code", "comparator": "eq", "expect": 500}
- {"check": "content.success", "comparator": "eq", "expect": false}

View File

@@ -1,13 +1,13 @@
import os
import time
import unittest
from httprunner import runner, testcase, utils
import requests
from httprunner import exception, response, runner, testcase, utils
from httprunner.context import Context
from httprunner.exception import ParamsError
from tests.base import ApiServerUnittest
class VariableBindsUnittest(unittest.TestCase):
class VariableBindsUnittest(ApiServerUnittest):
def setUp(self):
self.context = Context()
@@ -217,3 +217,72 @@ class VariableBindsUnittest(unittest.TestCase):
end_time = time.time()
elapsed_time = end_time - start_time
self.assertGreater(elapsed_time, 1)
def test_do_validation(self):
self.context.do_validation(
{"check_item": "check_item", "check_value": 1, "expect_value": 1, "comparator": "eq"}
)
self.context.do_validation(
{"check_item": "check_item", "check_value": "abc", "expect_value": "abc", "comparator": "=="}
)
config_dict = {
"path": 'tests/data/demo_testset_hardcode.yml'
}
self.context.config_context(config_dict, "testset")
self.context.do_validation(
{"check_item": "status_code", "check_value": "201", "expect_value": 3, "comparator": "sum_status_code"}
)
def test_validate(self):
url = "http://127.0.0.1:5000/"
resp = requests.get(url)
resp_obj = response.ResponseObject(resp)
validators = [
{"eq": ["resp_status_code", 201]},
{"check": "resp_status_code", "comparator": "eq", "expect": 201},
{"check": "resp_body_success", "comparator": "eq", "expect": True}
]
variables = [
{"resp_status_code": 200},
{"resp_body_success": True}
]
self.context.bind_variables(variables)
with self.assertRaises(exception.ValidationError):
self.context.validate(validators, resp_obj)
variables = [
{"resp_status_code": 201},
{"resp_body_success": True}
]
self.context.bind_variables(variables)
self.assertTrue(self.context.validate(validators, resp_obj))
def test_validate_exception(self):
url = "http://127.0.0.1:5000/"
resp = requests.get(url)
resp_obj = response.ResponseObject(resp)
# expected value missed in validators
validators = [
{"eq": ["resp_status_code", 201]},
{"check": "resp_status_code", "comparator": "eq", "expect": 201},
{"check": "resp_body_success", "comparator": "eq", "expect": True}
]
variables = []
self.context.bind_variables(variables)
with self.assertRaises(exception.ParamsError):
self.context.validate(validators, resp_obj)
# expected value missed in variables mapping
variables = [
{"resp_status_code": 200}
]
self.context.bind_variables(variables)
with self.assertRaises(exception.ValidationError):
self.context.validate(validators, resp_obj)

View File

@@ -230,70 +230,3 @@ class TestResponse(ApiServerUnittest):
resp_obj = response.ResponseObject(resp)
with self.assertRaises(exception.ParamsError):
resp_obj.extract_response(extract_binds_list)
def test_do_validation(self):
url = "http://127.0.0.1:5000/"
resp = requests.get(url)
resp_obj = response.ResponseObject(resp)
resp_obj.do_validation(
{"check_item": "check_item", "check_value": 1, "expect_value": 1, "comparator": "eq"},
self.functions_mapping
)
resp_obj.do_validation(
{"check_item": "check_item", "check_value": "abc", "expect_value": "abc", "comparator": "=="},
self.functions_mapping
)
def test_validate(self):
url = "http://127.0.0.1:5000/"
resp = requests.get(url)
resp_obj = response.ResponseObject(resp)
validators = [
{"check": "resp_status_code", "comparator": "eq", "expect": 201},
{"check": "resp_body_success", "comparator": "eq", "expect": True}
]
variables_mapping = {
"resp_status_code": 200,
"resp_body_success": True
}
with self.assertRaises(exception.ValidationError):
resp_obj.validate(validators, variables_mapping, self.functions_mapping)
validators = [
{"check": "resp_status_code", "comparator": "eq", "expect": 201},
{"check": "resp_body_success", "comparator": "eq", "expect": True}
]
variables_mapping = {
"resp_status_code": 201,
"resp_body_success": True
}
self.assertTrue(resp_obj.validate(validators, variables_mapping, self.functions_mapping))
def test_validate_exception(self):
url = "http://127.0.0.1:5000/"
resp = requests.get(url)
resp_obj = response.ResponseObject(resp)
# expected value missed in validators
validators = [
{"check": "status_code", "comparator": "eq", "expect": 201},
{"check": "body_success", "comparator": "eq"}
]
variables_mapping = {}
with self.assertRaises(exception.ValidationError):
resp_obj.validate(validators, variables_mapping, self.functions_mapping)
# expected value missed in variables mapping
validators = [
{"check": "resp_status_code", "comparator": "eq", "expect": 201},
{"check": "body_success", "comparator": "eq"}
]
variables_mapping = {
"resp_status_code": 200
}
with self.assertRaises(exception.ValidationError):
resp_obj.validate(validators, variables_mapping, self.functions_mapping)

View File

@@ -27,6 +27,12 @@ class TestRunner(ApiServerUnittest):
def test_run_single_testcase(self):
for testcase_file_path in self.testcase_file_path_list:
testcases = testcase._load_file(testcase_file_path)
config_dict = {
"path": testcase_file_path
}
self.test_runner.init_config(config_dict, "testset")
test = testcases[0]["test"]
self.assertTrue(self.test_runner._run_test(test))