From cab54c9c9a347c9d18db02783ef554c26b6e2c2c Mon Sep 17 00:00:00 2001 From: debugtalk Date: Thu, 5 Dec 2019 19:55:35 +0800 Subject: [PATCH] fix: fix compatibility for Python 2.7, circle import of parser and validator --- httprunner/loader.py | 2 +- httprunner/parser.py | 171 ++++++++++++++++++++++++++++++++++++++-- httprunner/validator.py | 166 -------------------------------------- tests/test_parser.py | 98 +++++++++++++++++++++++ tests/test_validator.py | 98 +---------------------- 5 files changed, 266 insertions(+), 269 deletions(-) diff --git a/httprunner/loader.py b/httprunner/loader.py index 428d318a..0bc7a663 100644 --- a/httprunner/loader.py +++ b/httprunner/loader.py @@ -8,7 +8,7 @@ import types import yaml -from httprunner import built_in, exceptions, logger, utils, validator +from httprunner import built_in, exceptions, logger, utils try: # PyYAML version >= 5.1 diff --git a/httprunner/parser.py b/httprunner/parser.py index 29b0a666..506783c3 100644 --- a/httprunner/parser.py +++ b/httprunner/parser.py @@ -2,9 +2,11 @@ import ast import builtins +import collections +import json import re -from httprunner import exceptions, utils, validator +from httprunner import exceptions, utils from httprunner.compat import basestring, numeric_types, str # use $$ to escape $ notation @@ -218,6 +220,165 @@ def parse_parameters(parameters, variables_mapping=None, functions_mapping=None) return utils.gen_cartesian_product(*parsed_parameters_list) +def get_uniform_comparator(comparator): + """ convert comparator alias to uniform name + """ + if comparator in ["eq", "equals", "==", "is"]: + return "equals" + elif comparator in ["lt", "less_than"]: + return "less_than" + elif comparator in ["le", "less_than_or_equals"]: + return "less_than_or_equals" + elif comparator in ["gt", "greater_than"]: + return "greater_than" + elif comparator in ["ge", "greater_than_or_equals"]: + return "greater_than_or_equals" + elif comparator in ["ne", "not_equals"]: + return "not_equals" + elif comparator in ["str_eq", "string_equals"]: + return "string_equals" + elif comparator in ["len_eq", "length_equals", "count_eq"]: + return "length_equals" + elif comparator in ["len_gt", "count_gt", "length_greater_than", "count_greater_than"]: + return "length_greater_than" + elif comparator in ["len_ge", "count_ge", "length_greater_than_or_equals", + "count_greater_than_or_equals"]: + return "length_greater_than_or_equals" + elif comparator in ["len_lt", "count_lt", "length_less_than", "count_less_than"]: + return "length_less_than" + elif comparator in ["len_le", "count_le", "length_less_than_or_equals", + "count_less_than_or_equals"]: + return "length_less_than_or_equals" + else: + return comparator + + +def uniform_validator(validator): + """ unify validator + + Args: + validator (dict): validator maybe in two formats: + + 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, {comparator: [check_item, expected_value]} + {'eq': ['status_code', 201]} + {'eq': ['$resp_body_success', True]} + + Returns + dict: validator info + + { + "check": "status_code", + "expect": 201, + "comparator": "equals" + } + + """ + if not isinstance(validator, dict): + raise exceptions.ParamsError("invalid validator: {}".format(validator)) + + if "check" in validator and "expect" in validator: + # format1 + check_item = validator["check"] + expect_value = validator["expect"] + 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 exceptions.ParamsError("invalid validator: {}".format(validator)) + + check_item, expect_value = compare_values + + else: + raise exceptions.ParamsError("invalid validator: {}".format(validator)) + + # uniform comparator, e.g. lt => less_than, eq => equals + comparator = get_uniform_comparator(comparator) + + return { + "check": check_item, + "expect": expect_value, + "comparator": comparator + } + + +def _convert_validators_to_mapping(validators): + """ convert validators list to mapping. + + Args: + validators (list): validators in list + + Returns: + dict: validators mapping, use (check, comparator) as key. + + Examples: + >>> validators = [ + {"check": "v1", "expect": 201, "comparator": "eq"}, + {"check": {"b": 1}, "expect": 200, "comparator": "eq"} + ] + >>> print(_convert_validators_to_mapping(validators)) + { + ("v1", "eq"): {"check": "v1", "expect": 201, "comparator": "eq"}, + ('{"b": 1}', "eq"): {"check": {"b": 1}, "expect": 200, "comparator": "eq"} + } + + """ + validators_mapping = {} + + for validator in validators: + if not isinstance(validator["check"], collections.Hashable): + check = json.dumps(validator["check"]) + else: + check = validator["check"] + + key = (check, validator["comparator"]) + validators_mapping[key] = validator + + return validators_mapping + + +def extend_validators(raw_validators, override_validators): + """ extend raw_validators with override_validators. + override_validators will merge and override raw_validators. + + Args: + raw_validators (dict): + override_validators (dict): + + Returns: + list: extended validators + + Examples: + >>> raw_validators = [{'eq': ['v1', 200]}, {"check": "s2", "expect": 16, "comparator": "len_eq"}] + >>> override_validators = [{"check": "v1", "expect": 201}, {'len_eq': ['s3', 12]}] + >>> extend_validators(raw_validators, override_validators) + [ + {"check": "v1", "expect": 201, "comparator": "eq"}, + {"check": "s2", "expect": 16, "comparator": "len_eq"}, + {"check": "s3", "expect": 12, "comparator": "len_eq"} + ] + + """ + + if not raw_validators: + return override_validators + + elif not override_validators: + return raw_validators + + else: + def_validators_mapping = _convert_validators_to_mapping(raw_validators) + ref_validators_mapping = _convert_validators_to_mapping(override_validators) + + def_validators_mapping.update(ref_validators_mapping) + return list(def_validators_mapping.values()) + ############################################################################### ## parse content with variables and functions mapping ############################################################################### @@ -410,7 +571,7 @@ class LazyFunction(object): return "LazyFunction({}({}))".format(self.func_name, args_string) def __prepare_cache_key(self, args, kwargs): - return (self.func_name, repr(args), repr(kwargs)) + return self.func_name, repr(args), repr(kwargs) def to_value(self, variables_mapping=None): """ parse lazy data with evaluated variables mapping. @@ -786,11 +947,11 @@ def _extend_with_api(test_dict, api_def_dict): # merge & override validators TODO: relocate def_raw_validators = api_def_dict.pop("validate", []) def_validators = [ - validator.uniform_validator(_validator) + uniform_validator(_validator) for _validator in def_raw_validators ] ref_validators = test_dict.pop("validate", []) - test_dict["validate"] = validator.extend_validators( + test_dict["validate"] = extend_validators( def_validators, ref_validators ) @@ -946,7 +1107,7 @@ def __prepare_testcase_tests(tests, config, project_mapping, session_variables_s if "validate" in test_dict: ref_raw_validators = test_dict.pop("validate", []) test_dict["validate"] = [ - validator.uniform_validator(_validator) + uniform_validator(_validator) for _validator in ref_raw_validators ] diff --git a/httprunner/validator.py b/httprunner/validator.py index 153eeb61..3a821047 100644 --- a/httprunner/validator.py +++ b/httprunner/validator.py @@ -1,174 +1,8 @@ # encoding: utf-8 -import collections -import json from httprunner import exceptions, logger, parser -############################################################################### -## testcase validator utils -############################################################################### - -def get_uniform_comparator(comparator): - """ convert comparator alias to uniform name - """ - if comparator in ["eq", "equals", "==", "is"]: - return "equals" - elif comparator in ["lt", "less_than"]: - return "less_than" - elif comparator in ["le", "less_than_or_equals"]: - return "less_than_or_equals" - elif comparator in ["gt", "greater_than"]: - return "greater_than" - elif comparator in ["ge", "greater_than_or_equals"]: - return "greater_than_or_equals" - elif comparator in ["ne", "not_equals"]: - return "not_equals" - elif comparator in ["str_eq", "string_equals"]: - return "string_equals" - elif comparator in ["len_eq", "length_equals", "count_eq"]: - return "length_equals" - elif comparator in ["len_gt", "count_gt", "length_greater_than", "count_greater_than"]: - return "length_greater_than" - elif comparator in ["len_ge", "count_ge", "length_greater_than_or_equals", - "count_greater_than_or_equals"]: - return "length_greater_than_or_equals" - elif comparator in ["len_lt", "count_lt", "length_less_than", "count_less_than"]: - return "length_less_than" - elif comparator in ["len_le", "count_le", "length_less_than_or_equals", - "count_less_than_or_equals"]: - return "length_less_than_or_equals" - else: - return comparator - - -def uniform_validator(validator): - """ unify validator - - Args: - validator (dict): validator maybe in two formats: - - 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, {comparator: [check_item, expected_value]} - {'eq': ['status_code', 201]} - {'eq': ['$resp_body_success', True]} - - Returns - dict: validator info - - { - "check": "status_code", - "expect": 201, - "comparator": "equals" - } - - """ - if not isinstance(validator, dict): - raise exceptions.ParamsError("invalid validator: {}".format(validator)) - - if "check" in validator and "expect" in validator: - # format1 - check_item = validator["check"] - expect_value = validator["expect"] - 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 exceptions.ParamsError("invalid validator: {}".format(validator)) - - check_item, expect_value = compare_values - - else: - raise exceptions.ParamsError("invalid validator: {}".format(validator)) - - # uniform comparator, e.g. lt => less_than, eq => equals - comparator = get_uniform_comparator(comparator) - - return { - "check": check_item, - "expect": expect_value, - "comparator": comparator - } - - -def _convert_validators_to_mapping(validators): - """ convert validators list to mapping. - - Args: - validators (list): validators in list - - Returns: - dict: validators mapping, use (check, comparator) as key. - - Examples: - >>> validators = [ - {"check": "v1", "expect": 201, "comparator": "eq"}, - {"check": {"b": 1}, "expect": 200, "comparator": "eq"} - ] - >>> print(_convert_validators_to_mapping(validators)) - { - ("v1", "eq"): {"check": "v1", "expect": 201, "comparator": "eq"}, - ('{"b": 1}', "eq"): {"check": {"b": 1}, "expect": 200, "comparator": "eq"} - } - - """ - validators_mapping = {} - - for validator in validators: - if not isinstance(validator["check"], collections.Hashable): - check = json.dumps(validator["check"]) - else: - check = validator["check"] - - key = (check, validator["comparator"]) - validators_mapping[key] = validator - - return validators_mapping - - -def extend_validators(raw_validators, override_validators): - """ extend raw_validators with override_validators. - override_validators will merge and override raw_validators. - - Args: - raw_validators (dict): - override_validators (dict): - - Returns: - list: extended validators - - Examples: - >>> raw_validators = [{'eq': ['v1', 200]}, {"check": "s2", "expect": 16, "comparator": "len_eq"}] - >>> override_validators = [{"check": "v1", "expect": 201}, {'len_eq': ['s3', 12]}] - >>> extend_validators(raw_validators, override_validators) - [ - {"check": "v1", "expect": 201, "comparator": "eq"}, - {"check": "s2", "expect": 16, "comparator": "len_eq"}, - {"check": "s3", "expect": 12, "comparator": "len_eq"} - ] - - """ - - if not raw_validators: - return override_validators - - elif not override_validators: - return raw_validators - - else: - def_validators_mapping = _convert_validators_to_mapping(raw_validators) - ref_validators_mapping = _convert_validators_to_mapping(override_validators) - - def_validators_mapping.update(ref_validators_mapping) - return list(def_validators_mapping.values()) - - class Validator(object): """Validate tests diff --git a/tests/test_parser.py b/tests/test_parser.py index 6f76148e..1861f0cf 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -806,6 +806,104 @@ class TestParserBasic(unittest.TestCase): self.assertEqual(parsed_variables["var2"], "abc$123") self.assertEqual(parsed_variables["var3"], "abc$$num0") + def test_get_uniform_comparator(self): + self.assertEqual(parser.get_uniform_comparator("eq"), "equals") + self.assertEqual(parser.get_uniform_comparator("=="), "equals") + self.assertEqual(parser.get_uniform_comparator("lt"), "less_than") + self.assertEqual(parser.get_uniform_comparator("le"), "less_than_or_equals") + self.assertEqual(parser.get_uniform_comparator("gt"), "greater_than") + self.assertEqual(parser.get_uniform_comparator("ge"), "greater_than_or_equals") + self.assertEqual(parser.get_uniform_comparator("ne"), "not_equals") + + self.assertEqual(parser.get_uniform_comparator("str_eq"), "string_equals") + self.assertEqual(parser.get_uniform_comparator("len_eq"), "length_equals") + self.assertEqual(parser.get_uniform_comparator("count_eq"), "length_equals") + + self.assertEqual(parser.get_uniform_comparator("len_gt"), "length_greater_than") + self.assertEqual(parser.get_uniform_comparator("count_gt"), "length_greater_than") + self.assertEqual(parser.get_uniform_comparator("count_greater_than"), "length_greater_than") + + self.assertEqual(parser.get_uniform_comparator("len_ge"), "length_greater_than_or_equals") + self.assertEqual(parser.get_uniform_comparator("count_ge"), "length_greater_than_or_equals") + self.assertEqual(parser.get_uniform_comparator("count_greater_than_or_equals"), "length_greater_than_or_equals") + + self.assertEqual(parser.get_uniform_comparator("len_lt"), "length_less_than") + self.assertEqual(parser.get_uniform_comparator("count_lt"), "length_less_than") + self.assertEqual(parser.get_uniform_comparator("count_less_than"), "length_less_than") + + self.assertEqual(parser.get_uniform_comparator("len_le"), "length_less_than_or_equals") + self.assertEqual(parser.get_uniform_comparator("count_le"), "length_less_than_or_equals") + self.assertEqual(parser.get_uniform_comparator("count_less_than_or_equals"), "length_less_than_or_equals") + + def test_parse_validator(self): + _validator = {"check": "status_code", "comparator": "eq", "expect": 201} + self.assertEqual( + parser.uniform_validator(_validator), + {"check": "status_code", "comparator": "equals", "expect": 201} + ) + + _validator = {'eq': ['status_code', 201]} + self.assertEqual( + parser.uniform_validator(_validator), + {"check": "status_code", "comparator": "equals", "expect": 201} + ) + + def test_extend_validators(self): + def_validators = [ + {'eq': ['v1', 200]}, + {"check": "s2", "expect": 16, "comparator": "len_eq"} + ] + current_validators = [ + {"check": "v1", "expect": 201}, + {'len_eq': ['s3', 12]} + ] + def_validators = [ + parser.uniform_validator(_validator) + for _validator in def_validators + ] + ref_validators = [ + parser.uniform_validator(_validator) + for _validator in current_validators + ] + + extended_validators = parser.extend_validators(def_validators, ref_validators) + self.assertIn( + {"check": "v1", "expect": 201, "comparator": "equals"}, + extended_validators + ) + self.assertIn( + {"check": "s2", "expect": 16, "comparator": "length_equals"}, + extended_validators + ) + self.assertIn( + {"check": "s3", "expect": 12, "comparator": "length_equals"}, + extended_validators + ) + + def test_extend_validators_with_dict(self): + def_validators = [ + {'eq': ["a", {"v": 1}]}, + {'eq': [{"b": 1}, 200]} + ] + current_validators = [ + {'len_eq': ['s3', 12]}, + {'eq': [{"b": 1}, 201]} + ] + def_validators = [ + parser.uniform_validator(_validator) + for _validator in def_validators + ] + ref_validators = [ + parser.uniform_validator(_validator) + for _validator in current_validators + ] + + extended_validators = parser.extend_validators(def_validators, ref_validators) + self.assertEqual(len(extended_validators), 3) + self.assertIn({'check': {'b': 1}, 'expect': 201, 'comparator': 'equals'}, extended_validators) + self.assertNotIn({'check': {'b': 1}, 'expect': 200, 'comparator': 'equals'}, extended_validators) + + class TestParser(unittest.TestCase): def test_parse_parameters_raw_list(self): diff --git a/tests/test_validator.py b/tests/test_validator.py index 312a9e74..039c3960 100644 --- a/tests/test_validator.py +++ b/tests/test_validator.py @@ -4,100 +4,4 @@ from httprunner import validator class TestValidator(unittest.TestCase): - - def test_get_uniform_comparator(self): - self.assertEqual(validator.get_uniform_comparator("eq"), "equals") - self.assertEqual(validator.get_uniform_comparator("=="), "equals") - self.assertEqual(validator.get_uniform_comparator("lt"), "less_than") - self.assertEqual(validator.get_uniform_comparator("le"), "less_than_or_equals") - self.assertEqual(validator.get_uniform_comparator("gt"), "greater_than") - self.assertEqual(validator.get_uniform_comparator("ge"), "greater_than_or_equals") - self.assertEqual(validator.get_uniform_comparator("ne"), "not_equals") - - self.assertEqual(validator.get_uniform_comparator("str_eq"), "string_equals") - self.assertEqual(validator.get_uniform_comparator("len_eq"), "length_equals") - self.assertEqual(validator.get_uniform_comparator("count_eq"), "length_equals") - - self.assertEqual(validator.get_uniform_comparator("len_gt"), "length_greater_than") - self.assertEqual(validator.get_uniform_comparator("count_gt"), "length_greater_than") - self.assertEqual(validator.get_uniform_comparator("count_greater_than"), "length_greater_than") - - self.assertEqual(validator.get_uniform_comparator("len_ge"), "length_greater_than_or_equals") - self.assertEqual(validator.get_uniform_comparator("count_ge"), "length_greater_than_or_equals") - self.assertEqual(validator.get_uniform_comparator("count_greater_than_or_equals"), "length_greater_than_or_equals") - - self.assertEqual(validator.get_uniform_comparator("len_lt"), "length_less_than") - self.assertEqual(validator.get_uniform_comparator("count_lt"), "length_less_than") - self.assertEqual(validator.get_uniform_comparator("count_less_than"), "length_less_than") - - self.assertEqual(validator.get_uniform_comparator("len_le"), "length_less_than_or_equals") - self.assertEqual(validator.get_uniform_comparator("count_le"), "length_less_than_or_equals") - self.assertEqual(validator.get_uniform_comparator("count_less_than_or_equals"), "length_less_than_or_equals") - - def test_parse_validator(self): - _validator = {"check": "status_code", "comparator": "eq", "expect": 201} - self.assertEqual( - validator.uniform_validator(_validator), - {"check": "status_code", "comparator": "equals", "expect": 201} - ) - - _validator = {'eq': ['status_code', 201]} - self.assertEqual( - validator.uniform_validator(_validator), - {"check": "status_code", "comparator": "equals", "expect": 201} - ) - - def test_extend_validators(self): - def_validators = [ - {'eq': ['v1', 200]}, - {"check": "s2", "expect": 16, "comparator": "len_eq"} - ] - current_validators = [ - {"check": "v1", "expect": 201}, - {'len_eq': ['s3', 12]} - ] - def_validators = [ - validator.uniform_validator(_validator) - for _validator in def_validators - ] - ref_validators = [ - validator.uniform_validator(_validator) - for _validator in current_validators - ] - - extended_validators = validator.extend_validators(def_validators, ref_validators) - self.assertIn( - {"check": "v1", "expect": 201, "comparator": "equals"}, - extended_validators - ) - self.assertIn( - {"check": "s2", "expect": 16, "comparator": "length_equals"}, - extended_validators - ) - self.assertIn( - {"check": "s3", "expect": 12, "comparator": "length_equals"}, - extended_validators - ) - - def test_extend_validators_with_dict(self): - def_validators = [ - {'eq': ["a", {"v": 1}]}, - {'eq': [{"b": 1}, 200]} - ] - current_validators = [ - {'len_eq': ['s3', 12]}, - {'eq': [{"b": 1}, 201]} - ] - def_validators = [ - validator.uniform_validator(_validator) - for _validator in def_validators - ] - ref_validators = [ - validator.uniform_validator(_validator) - for _validator in current_validators - ] - - extended_validators = validator.extend_validators(def_validators, ref_validators) - self.assertEqual(len(extended_validators), 3) - self.assertIn({'check': {'b': 1}, 'expect': 201, 'comparator': 'equals'}, extended_validators) - self.assertNotIn({'check': {'b': 1}, 'expect': 200, 'comparator': 'equals'}, extended_validators) + pass