mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-31 21:39:41 +08:00
fix:修改SqlResponseObject继承关系;添加thriftpy2依赖
This commit is contained in:
@@ -43,7 +43,8 @@ class TestCompat(unittest.TestCase):
|
||||
"body.data.buildings[0].building_id",
|
||||
)
|
||||
self.assertEqual(
|
||||
compat._convert_jmespath("body.users[-1]"), "body.users[-1]",
|
||||
compat._convert_jmespath("body.users[-1]"),
|
||||
"body.users[-1]",
|
||||
)
|
||||
self.assertEqual(
|
||||
compat._convert_jmespath("body.result.WorkNode_-1"),
|
||||
|
||||
@@ -97,7 +97,11 @@ class TestLoader(unittest.TestCase):
|
||||
)
|
||||
|
||||
def test_load_env_path_not_exist(self):
|
||||
dot_env_path = os.path.join(os.getcwd(), "tests", "data",)
|
||||
dot_env_path = os.path.join(
|
||||
os.getcwd(),
|
||||
"tests",
|
||||
"data",
|
||||
)
|
||||
env_variables_mapping = loader.load_dot_env_file(dot_env_path)
|
||||
self.assertEqual(env_variables_mapping, {})
|
||||
|
||||
|
||||
@@ -534,7 +534,8 @@ def main_make(tests_paths: List[Text]) -> List[Text]:
|
||||
def init_make_parser(subparsers):
|
||||
"""make testcases: parse command line options and run commands."""
|
||||
parser = subparsers.add_parser(
|
||||
"make", help="Convert YAML/JSON testcases to pytest cases.",
|
||||
"make",
|
||||
help="Convert YAML/JSON testcases to pytest cases.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"testcase_path", nargs="*", help="Specify YAML/JSON testcase file/folder path"
|
||||
|
||||
@@ -73,7 +73,8 @@ from request_methods.request_with_functions_test import (
|
||||
content,
|
||||
)
|
||||
self.assertIn(
|
||||
".call(RequestWithFunctions)", content,
|
||||
".call(RequestWithFunctions)",
|
||||
content,
|
||||
)
|
||||
|
||||
def test_make_testcase_folder(self):
|
||||
@@ -111,7 +112,8 @@ from request_methods.request_with_functions_test import (
|
||||
)
|
||||
loader.project_meta = None
|
||||
self.assertEqual(
|
||||
ensure_file_abs_path_valid(os.getcwd()), os.getcwd(),
|
||||
ensure_file_abs_path_valid(os.getcwd()),
|
||||
os.getcwd(),
|
||||
)
|
||||
loader.project_meta = None
|
||||
self.assertEqual(
|
||||
@@ -122,11 +124,17 @@ from request_methods.request_with_functions_test import (
|
||||
def test_convert_testcase_path(self):
|
||||
self.assertEqual(
|
||||
convert_testcase_path(os.path.join(self.data_dir, "a-b.c", "2 3.yml")),
|
||||
(os.path.join(self.data_dir, "a_b_c", "T2_3_test.py"), "T23",),
|
||||
(
|
||||
os.path.join(self.data_dir, "a_b_c", "T2_3_test.py"),
|
||||
"T23",
|
||||
),
|
||||
)
|
||||
self.assertEqual(
|
||||
convert_testcase_path(os.path.join(self.data_dir, "a-b.c", "中文case.yml")),
|
||||
(os.path.join(self.data_dir, "a_b_c", "中文case_test.py"), "中文Case",),
|
||||
(
|
||||
os.path.join(self.data_dir, "a_b_c", "中文case_test.py"),
|
||||
"中文Case",
|
||||
),
|
||||
)
|
||||
|
||||
def test_make_config_chain_style(self):
|
||||
@@ -145,7 +153,11 @@ from request_methods.request_with_functions_test import (
|
||||
def test_make_teststep_chain_style(self):
|
||||
step = {
|
||||
"name": "get with params",
|
||||
"variables": {"foo1": "bar1", "foo2": 123, "sum_v": "${sum_two(1, 2)}",},
|
||||
"variables": {
|
||||
"foo1": "bar1",
|
||||
"foo2": 123,
|
||||
"sum_v": "${sum_two(1, 2)}",
|
||||
},
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"url": "/get",
|
||||
|
||||
@@ -76,7 +76,7 @@ class TransportEnum(Text, Enum):
|
||||
|
||||
|
||||
class TThriftRequest(BaseModel):
|
||||
""" rpc request model"""
|
||||
"""rpc request model"""
|
||||
|
||||
method: Text = ""
|
||||
params: Dict = {}
|
||||
@@ -106,7 +106,7 @@ class SqlMethodEnum(Text, Enum):
|
||||
|
||||
|
||||
class TSqlRequest(BaseModel):
|
||||
""" sql request model"""
|
||||
"""sql request model"""
|
||||
|
||||
db_config: TConfigDB = TConfigDB()
|
||||
method: SqlMethodEnum = None
|
||||
|
||||
@@ -476,7 +476,9 @@ def parse_variables_mapping(
|
||||
return parsed_variables
|
||||
|
||||
|
||||
def parse_parameters(parameters: Dict,) -> List[Dict]:
|
||||
def parse_parameters(
|
||||
parameters: Dict,
|
||||
) -> List[Dict]:
|
||||
"""parse parameters and generate cartesian product.
|
||||
|
||||
Args:
|
||||
|
||||
@@ -11,7 +11,7 @@ from httprunner.parser import parse_string_value, Parser
|
||||
|
||||
|
||||
def get_uniform_comparator(comparator: Text):
|
||||
""" convert comparator alias to uniform name"""
|
||||
"""convert comparator alias to uniform name"""
|
||||
if comparator in ["eq", "equals", "equal"]:
|
||||
return "equal"
|
||||
elif comparator in ["lt", "less_than"]:
|
||||
@@ -114,7 +114,7 @@ def uniform_validator(validator):
|
||||
|
||||
class ResponseObjectBase(object):
|
||||
def __init__(self, resp_obj, parser: Parser):
|
||||
""" initialize with a response object
|
||||
"""initialize with a response object
|
||||
|
||||
Args:
|
||||
resp_obj (instance): requests.Response instance
|
||||
@@ -125,7 +125,9 @@ class ResponseObjectBase(object):
|
||||
self.validation_results: Dict = {}
|
||||
|
||||
def extract(
|
||||
self, extractors: Dict[Text, Text], variables_mapping: VariablesMapping = None,
|
||||
self,
|
||||
extractors: Dict[Text, Text],
|
||||
variables_mapping: VariablesMapping = None,
|
||||
) -> Dict[Text, Any]:
|
||||
if not extractors:
|
||||
return {}
|
||||
@@ -142,10 +144,22 @@ class ResponseObjectBase(object):
|
||||
return extract_mapping
|
||||
|
||||
def _search_jmespath(self, expr: Text) -> Any:
|
||||
raise NotImplementedError("_search_jmespath not override")
|
||||
try:
|
||||
check_value = jmespath.search(expr, self.resp_obj)
|
||||
except JMESPathError as ex:
|
||||
logger.error(
|
||||
f"failed to search with jmespath\n"
|
||||
f"expression: {expr}\n"
|
||||
f"data: {self.resp_obj}\n"
|
||||
f"exception: {ex}"
|
||||
)
|
||||
raise
|
||||
return check_value
|
||||
|
||||
def validate(
|
||||
self, validators: Validators, variables_mapping: VariablesMapping = None,
|
||||
self,
|
||||
validators: Validators,
|
||||
variables_mapping: VariablesMapping = None,
|
||||
):
|
||||
|
||||
variables_mapping = variables_mapping or {}
|
||||
@@ -277,19 +291,8 @@ class ResponseObject(ResponseObjectBase):
|
||||
|
||||
|
||||
class ThriftResponseObject(ResponseObjectBase):
|
||||
def _search_jmespath(self, expr: Text) -> Any:
|
||||
try:
|
||||
check_value = jmespath.search(expr, self.resp_obj)
|
||||
except JMESPathError as ex:
|
||||
logger.error(
|
||||
f"failed to search with jmespath\n"
|
||||
f"expression: {expr}\n"
|
||||
f"data: {self.resp_obj}\n"
|
||||
f"exception: {ex}"
|
||||
)
|
||||
raise
|
||||
return check_value
|
||||
|
||||
|
||||
class SqlResponseObject(ThriftResponseObject):
|
||||
pass
|
||||
|
||||
|
||||
class SqlResponseObject(ResponseObjectBase):
|
||||
pass
|
||||
|
||||
@@ -61,6 +61,9 @@ class TestResponse(unittest.TestCase):
|
||||
def test_validate_functions(self):
|
||||
variables_mapping = {"index": 1}
|
||||
self.resp_obj.validate(
|
||||
[{"eq": ["${get_num(0)}", 0]}, {"eq": ["${get_num($index)}", 1]},],
|
||||
[
|
||||
{"eq": ["${get_num(0)}", 0]},
|
||||
{"eq": ["${get_num($index)}", 1]},
|
||||
],
|
||||
variables_mapping=variables_mapping,
|
||||
)
|
||||
|
||||
@@ -67,7 +67,10 @@ def call_hooks(
|
||||
|
||||
def run_step_request(runner: HttpRunner, step: TStep) -> StepResult:
|
||||
"""run teststep: request"""
|
||||
step_result = StepResult(name=step.name, success=False,)
|
||||
step_result = StepResult(
|
||||
name=step.name,
|
||||
success=False,
|
||||
)
|
||||
start_time = time.time()
|
||||
|
||||
step.variables = runner.merge_step_variables(step.variables)
|
||||
@@ -79,7 +82,8 @@ def run_step_request(runner: HttpRunner, step: TStep) -> StepResult:
|
||||
request_dict.pop("upload", None)
|
||||
parsed_request_dict = runner.parser.parse_data(request_dict, step.variables)
|
||||
parsed_request_dict["headers"].setdefault(
|
||||
"HRUN-Request-ID", f"HRUN-{runner.case_id}-{str(int(time.time() * 1000))[-6:]}",
|
||||
"HRUN-Request-ID",
|
||||
f"HRUN-{runner.case_id}-{str(int(time.time() * 1000))[-6:]}",
|
||||
)
|
||||
step.variables["request"] = parsed_request_dict
|
||||
|
||||
|
||||
@@ -23,7 +23,10 @@ def run_step_sql_request(runner: HttpRunner, step: TStep) -> StepResult:
|
||||
"""run teststep:sql request"""
|
||||
start_time = time.time()
|
||||
|
||||
step_result = StepResult(name=step.name, success=False,)
|
||||
step_result = StepResult(
|
||||
name=step.name,
|
||||
success=False,
|
||||
)
|
||||
step.variables = runner.merge_step_variables(step.variables)
|
||||
# parse
|
||||
request_dict = step.sql_request.dict()
|
||||
@@ -48,11 +51,7 @@ def run_step_sql_request(runner: HttpRunner, step: TStep) -> StepResult:
|
||||
parsed_request_dict["db_config"]["database"] or config.db.database
|
||||
)
|
||||
|
||||
if parsed_request_dict["db_config"]["psm"]:
|
||||
runner.db_engine = DBEngine(
|
||||
f'mysql+pymysql://:@/?charset=utf8mb4&db_psm={parsed_request_dict["psm"]}'
|
||||
)
|
||||
else:
|
||||
if not runner.db_engine:
|
||||
runner.db_engine = DBEngine(
|
||||
f'mysql+pymysql://{parsed_request_dict["db_config"]["user"]}:'
|
||||
f'{parsed_request_dict["db_config"]["password"]}@{parsed_request_dict["db_config"]["ip"]}:'
|
||||
@@ -171,10 +170,8 @@ class RunSqlRequest(IStep):
|
||||
return self
|
||||
|
||||
def with_db_config(
|
||||
self, psm=None, user=None, password=None, ip=None, port=None, database=None
|
||||
self, user=None, password=None, ip=None, port=None, database=None, psm=None
|
||||
):
|
||||
if psm:
|
||||
self.__step.sql_request.db_config.psm = psm
|
||||
if user:
|
||||
self.__step.sql_request.db_config.user = user
|
||||
if password:
|
||||
@@ -185,6 +182,8 @@ class RunSqlRequest(IStep):
|
||||
self.__step.sql_request.db_config.port = port
|
||||
if database:
|
||||
self.__step.sql_request.db_config.database = database
|
||||
if psm:
|
||||
self.__step.sql_request.db_config.psm = psm
|
||||
return self
|
||||
|
||||
def fetchone(self, sql) -> "RunSqlRequest":
|
||||
|
||||
@@ -22,7 +22,10 @@ def run_step_thrift_request(runner: HttpRunner, step: TStep) -> StepResult:
|
||||
"""run teststep:thrift request"""
|
||||
start_time = time.time()
|
||||
|
||||
step_result = StepResult(name=step.name, success=False,)
|
||||
step_result = StepResult(
|
||||
name=step.name,
|
||||
success=False,
|
||||
)
|
||||
step.variables = runner.merge_step_variables(step.variables)
|
||||
# parse
|
||||
request_dict = step.thrift_request.dict()
|
||||
@@ -65,17 +68,18 @@ def run_step_thrift_request(runner: HttpRunner, step: TStep) -> StepResult:
|
||||
step.variables["thrift_request"] = parsed_request_dict
|
||||
|
||||
psm = parsed_request_dict["psm"]
|
||||
|
||||
runner.thrift_client = parsed_request_dict["thrift_client"]
|
||||
if not runner.thrift_client:
|
||||
runner.thrift_client = parsed_request_dict["thrift_client"]
|
||||
if not runner.thrift_client:
|
||||
runner.thrift_client = ThriftClient(
|
||||
parsed_request_dict["idl_path"],
|
||||
parsed_request_dict["service_name"],
|
||||
parsed_request_dict["ip"],
|
||||
parsed_request_dict["port"],
|
||||
parsed_request_dict["timeout"],
|
||||
parsed_request_dict["proto_type"],
|
||||
parsed_request_dict["trans_port"],
|
||||
thrift_file=parsed_request_dict["idl_path"],
|
||||
service_name=parsed_request_dict["service_name"],
|
||||
ip=parsed_request_dict["ip"],
|
||||
port=parsed_request_dict["port"],
|
||||
include_dirs=parsed_request_dict["include_dirs"],
|
||||
timeout=parsed_request_dict["timeout"],
|
||||
proto_type=parsed_request_dict["proto_type"],
|
||||
trans_type=parsed_request_dict["trans_port"],
|
||||
)
|
||||
|
||||
# setup hooks
|
||||
|
||||
@@ -78,9 +78,7 @@ def unicode_2_utf8_keep_native(para):
|
||||
|
||||
|
||||
def encode_basestring(s):
|
||||
"""Return a JSON representation of a Python string
|
||||
|
||||
"""
|
||||
"""Return a JSON representation of a Python string"""
|
||||
|
||||
def replace(match):
|
||||
return ESCAPE_DCT[match.group(0)]
|
||||
@@ -89,9 +87,7 @@ def encode_basestring(s):
|
||||
|
||||
|
||||
def py_encode_basestring_ascii(s):
|
||||
"""Return an ASCII-only JSON representation of a Python string
|
||||
|
||||
"""
|
||||
"""Return an ASCII-only JSON representation of a Python string"""
|
||||
if isinstance(s, str) and HAS_UTF8.search(s) is not None:
|
||||
s = s.decode("utf-8")
|
||||
|
||||
@@ -289,10 +285,10 @@ class MyJSONEncoder(json.JSONEncoder):
|
||||
|
||||
def encode(self, o):
|
||||
"""Return a JSON string representation of a Python data structure.
|
||||
JSONEncoder().encode({"foo": ["bar", "baz"]})
|
||||
'{"foo": ["bar", "baz"]}'
|
||||
JSONEncoder().encode({"foo": ["bar", "baz"]})
|
||||
'{"foo": ["bar", "baz"]}'
|
||||
|
||||
"""
|
||||
"""
|
||||
# This is for extremely simple cases and benchmarks.
|
||||
|
||||
if isinstance(o, str):
|
||||
@@ -363,7 +359,7 @@ class ThriftJSONEncoder(json.JSONEncoder):
|
||||
JSONEncoder().encode({"foo": ["bar", "baz"]})
|
||||
'{"foo": ["bar", "baz"]}'
|
||||
|
||||
"""
|
||||
"""
|
||||
# This is for extremely simple cases and benchmarks.
|
||||
|
||||
if isinstance(o, str):
|
||||
|
||||
Reference in New Issue
Block a user