请求装饰器处理发送请求
This commit is contained in:
parent
76df35c96e
commit
9eea2cc951
|
@ -4,17 +4,7 @@
|
|||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="eded71e8-6551-463d-9bd4-cdbb3ffc536c" name="更改" comment="增加依赖装饰器,增加自动安装依赖文件,修改报告日志输出边距及颜色">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/OutPut/reports/report.html" beforeDir="false" afterPath="$PROJECT_DIR$/OutPut/reports/report.html" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/cases/cases/test_cases.xlsx" beforeDir="false" afterPath="$PROJECT_DIR$/cases/cases/test_cases.xlsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/common/core/testRunner.py" beforeDir="false" afterPath="$PROJECT_DIR$/common/core/testRunner.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/common/utils/decorators.py" beforeDir="false" afterPath="$PROJECT_DIR$/common/utils/decorators.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/common/utils/install_dependencies.py" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/output/reports/history.json" beforeDir="false" afterPath="$PROJECT_DIR$/output/reports/history.json" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/templates/dingtalk.md" beforeDir="false" afterPath="$PROJECT_DIR$/templates/dingtalk.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/templates/weChat.md" beforeDir="false" afterPath="$PROJECT_DIR$/templates/weChat.md" afterDir="false" />
|
||||
</list>
|
||||
<list default="true" id="eded71e8-6551-463d-9bd4-cdbb3ffc536c" name="更改" comment="优化钉钉报告样式" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
|
@ -194,8 +184,8 @@
|
|||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Python.run" />
|
||||
<item itemvalue="Python.run_script_main" />
|
||||
<item itemvalue="Python.comparators" />
|
||||
<item itemvalue="Python.run_script_main" />
|
||||
<item itemvalue="Python 测试.Python 测试 (test_executor.py 内)" />
|
||||
<item itemvalue="Python.dingding" />
|
||||
</list>
|
||||
|
@ -235,7 +225,8 @@
|
|||
<workItem from="1691638175448" duration="3625000" />
|
||||
<workItem from="1691657355432" duration="5387000" />
|
||||
<workItem from="1691667714661" duration="8686000" />
|
||||
<workItem from="1691973725101" duration="6000000" />
|
||||
<workItem from="1691973725101" duration="6601000" />
|
||||
<workItem from="1691980768817" duration="14005000" />
|
||||
</task>
|
||||
<task id="LOCAL-00001" summary="优化代码">
|
||||
<option name="closed" value="true" />
|
||||
|
@ -373,7 +364,15 @@
|
|||
<option name="project" value="LOCAL" />
|
||||
<updated>1691722760750</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="18" />
|
||||
<task id="LOCAL-00018" summary="优化钉钉报告样式">
|
||||
<option name="closed" value="true" />
|
||||
<created>1691980245927</created>
|
||||
<option name="number" value="00018" />
|
||||
<option name="presentableId" value="LOCAL-00018" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1691980245927</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="19" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
|
@ -393,7 +392,8 @@
|
|||
<MESSAGE value="更新说明文档" />
|
||||
<MESSAGE value="更友好的异常信息输出" />
|
||||
<MESSAGE value="增加依赖装饰器,增加自动安装依赖文件,修改报告日志输出边距及颜色" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="增加依赖装饰器,增加自动安装依赖文件,修改报告日志输出边距及颜色" />
|
||||
<MESSAGE value="优化钉钉报告样式" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="优化钉钉报告样式" />
|
||||
</component>
|
||||
<component name="com.github.evgenys91.machinet.common.dslhistory.DslHistoryState">
|
||||
<option name="historyDtoById">
|
||||
|
@ -414,7 +414,7 @@
|
|||
</component>
|
||||
<component name="com.intellij.coverage.CoverageDataManagerImpl">
|
||||
<SUITE FILE_PATH="coverage/apitest$load_modules_from_folder.coverage" NAME="load_modules_from_folder 覆盖结果" MODIFIED="1691398471049" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/common/validation" />
|
||||
<SUITE FILE_PATH="coverage/apitest$run.coverage" NAME="run 覆盖结果" MODIFIED="1691979676787" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
||||
<SUITE FILE_PATH="coverage/apitest$run.coverage" NAME="run 覆盖结果" MODIFIED="1692004486581" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
||||
<SUITE FILE_PATH="coverage/apitest$Unittest__test_api_py__.coverage" NAME="Unittest (test_api.py 内) 覆盖结果" MODIFIED="1689907531802" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test_script" />
|
||||
<SUITE FILE_PATH="coverage/apitest$dingding.coverage" NAME="dingding 覆盖结果" MODIFIED="1691483158998" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/common/notiction" />
|
||||
<SUITE FILE_PATH="coverage/apitest$assert_dict.coverage" NAME="assert_dict 覆盖结果" MODIFIED="1691034548959" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/common/data_extraction" />
|
||||
|
@ -436,7 +436,7 @@
|
|||
<SUITE FILE_PATH="coverage/apitest$resultPush.coverage" NAME="resultPush 覆盖结果" MODIFIED="1691465454364" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/unittestreportnew/core" />
|
||||
<SUITE FILE_PATH="coverage/apitest$.coverage" NAME=" 覆盖结果" MODIFIED="1691568903890" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test_script" />
|
||||
<SUITE FILE_PATH="coverage/apitest$method_chain.coverage" NAME="method_chain 覆盖结果" MODIFIED="1690967090148" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/debug" />
|
||||
<SUITE FILE_PATH="coverage/apitest$comparators.coverage" NAME="comparators 覆盖结果" MODIFIED="1691666161767" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/common/validation" />
|
||||
<SUITE FILE_PATH="coverage/apitest$comparators.coverage" NAME="comparators 覆盖结果" MODIFIED="1691996672342" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/common/validation" />
|
||||
<SUITE FILE_PATH="coverage/apitest$encryption_str.coverage" NAME="encryption_str 覆盖结果" MODIFIED="1690796164466" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/common/crypto" />
|
||||
<SUITE FILE_PATH="coverage/apitest$data_extractor.coverage" NAME="data_extractor 覆盖结果" MODIFIED="1691398486016" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/common/data_extraction" />
|
||||
<SUITE FILE_PATH="coverage/apitest$get_set.coverage" NAME="get_set 覆盖结果" MODIFIED="1689930576115" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/debug" />
|
||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -83,6 +83,8 @@ class HttpClient(LoadModulesFromFolder):
|
|||
[i.close() for i in fs if len(fs) > 0]
|
||||
try:
|
||||
self.response_json = self.response.json()
|
||||
self.update_environments("responseStatusCode", self.response.status_code)
|
||||
self.update_environments("responseTime", round(self.response.elapsed.total_seconds() * 1000, 2))
|
||||
except Exception as e:
|
||||
ResponseJsonConversionError(self.response.text, str(e))
|
||||
self.response_json = None
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -13,7 +13,7 @@ import time
|
|||
from common import bif_functions
|
||||
from common.crypto.encrypt_data import EncryptData
|
||||
from common.database.mysql_client import MysqlClient
|
||||
from common.utils.decorators import singleton
|
||||
from common.utils.decorators import singleton, send_request_decorator
|
||||
from common.utils.exceptions import *
|
||||
from common.validation.extractor import Extractor
|
||||
from common.validation.load_and_execute_script import LoadScript
|
||||
|
@ -46,13 +46,18 @@ class Action(Extractor, LoadScript, Validator):
|
|||
|
||||
return self.variables
|
||||
|
||||
@property
|
||||
def variables(self, key=None):
|
||||
return self.__variables if not key else self.__variables.get(key)
|
||||
@send_request_decorator
|
||||
def send_request(self, host, method, extract_request_data):
|
||||
|
||||
@variables.setter
|
||||
def variables(self, item):
|
||||
self.__variables = item
|
||||
url, kwargs = self.prepare_request(extract_request_data, self.variables)
|
||||
self.http_client(host, url, method, **kwargs)
|
||||
|
||||
def prepare_request(self, extract_request_data, item):
|
||||
item = self.replace_dependent_parameter(item)
|
||||
url, query_str, request_data, headers, request_data_type, h_crypto, r_crypto = self.request_info(item)
|
||||
headers, request_data = self.analysis_request(request_data, h_crypto, headers, r_crypto, extract_request_data)
|
||||
kwargs = {request_data_type: request_data, "headers": headers, "params": query_str}
|
||||
return url, kwargs
|
||||
|
||||
def analysis_request(self, request_data, headers_crypto, headers, request_crypto, extract_request_data):
|
||||
headers, request_data = self.encrypt.encrypts(headers_crypto, headers, request_crypto, request_data)
|
||||
|
@ -60,39 +65,6 @@ class Action(Extractor, LoadScript, Validator):
|
|||
self.substitute_data(request_data, jp_dict=extract_request_data)
|
||||
return headers, request_data
|
||||
|
||||
def send_request(self, host, url, method, teardown_script, **kwargs):
|
||||
self.http_client(host, url, method, **kwargs)
|
||||
self.update_environments("responseStatusCode", self.response.status_code)
|
||||
self.update_environments("responseTime", round(self.response.elapsed.total_seconds() * 1000, 2))
|
||||
self.execute_dynamic_code(self.response, teardown_script)
|
||||
|
||||
def analysis_response(self, sheet, iid, name, desc, regex, keys, deps, jp_dict):
|
||||
try:
|
||||
self.substitute_data(self.response_json, regex=regex, keys=keys, deps=deps, jp_dict=jp_dict)
|
||||
except Exception as err:
|
||||
msg = f"| 分析响应失败:{sheet}_{iid}_{name}_{desc}"
|
||||
f"\nregex={regex};"
|
||||
f" \nkeys={keys};"
|
||||
f"\ndeps={deps};"
|
||||
f"\njp_dict={jp_dict}"
|
||||
f"\n{err}"
|
||||
ParameterExtractionError(msg, err)
|
||||
|
||||
def execute_validation(self, excel, sheet, iid, name, desc, expected):
|
||||
try:
|
||||
self.run_validate(expected, self.response_json)
|
||||
result = "PASS"
|
||||
except Exception as e:
|
||||
result = "FAIL"
|
||||
error_info = f"| exception case:**{sheet}_{iid}_{name}_{desc},{self.assertions}"
|
||||
AssertionFailedError(error_info, e)
|
||||
raise e
|
||||
finally:
|
||||
print(f'| <span style="color:yellow">断言结果-->{self.assertions}</span>\n')
|
||||
print("-" * 50)
|
||||
response = self.response.text if self.response is not None else str(self.response)
|
||||
excel.write_back(sheet_name=sheet, i=iid, response=response, result=result, assertions=str(self.assertions))
|
||||
|
||||
@staticmethod
|
||||
def base_info(item):
|
||||
"""
|
||||
|
@ -104,11 +76,9 @@ class Action(Extractor, LoadScript, Validator):
|
|||
sleep_time = item.pop("Time")
|
||||
name = item.pop("Name")
|
||||
desc = item.pop("Description")
|
||||
headers_crypto = item.pop("HeadersCrypto")
|
||||
request_data_crypto = item.pop("RequestDataCrypto")
|
||||
method = item.pop("Method")
|
||||
expected = item.pop("Expected")
|
||||
return sheet, item_id, condition, sleep_time, name, desc, headers_crypto, request_data_crypto, method, expected
|
||||
return sheet, item_id, condition, sleep_time, name, desc, method, expected
|
||||
|
||||
@staticmethod
|
||||
def sql_info(item):
|
||||
|
@ -143,8 +113,10 @@ class Action(Extractor, LoadScript, Validator):
|
|||
request_data = item.pop("RequestData")
|
||||
headers = item.pop("Headers")
|
||||
request_data_type = item.pop("RequestDataType") if item.get("RequestDataType") else 'params'
|
||||
headers_crypto = item.pop("HeadersCrypto")
|
||||
request_data_crypto = item.pop("RequestDataCrypto")
|
||||
|
||||
return url, query_str, request_data, headers, request_data_type
|
||||
return url, query_str, request_data, headers, request_data_type, headers_crypto, request_data_crypto
|
||||
|
||||
@staticmethod
|
||||
def script(item):
|
||||
|
@ -168,6 +140,7 @@ class Action(Extractor, LoadScript, Validator):
|
|||
|
||||
def exc_sql(self, item):
|
||||
sql, sql_params_dict = self.sql_info(item)
|
||||
self.variables = item
|
||||
sql = self.replace_dependent_parameter(sql)
|
||||
if sql:
|
||||
client = MysqlClient(self.db_config)
|
||||
|
@ -176,6 +149,42 @@ class Action(Extractor, LoadScript, Validator):
|
|||
if execute_sql_results and sql_params_dict:
|
||||
self.substitute_data(execute_sql_results, jp_dict=sql_params_dict)
|
||||
|
||||
def analysis_response(self, sheet, iid, name, desc, regex, keys, deps, jp_dict):
|
||||
try:
|
||||
self.substitute_data(self.response_json, regex=regex, keys=keys, deps=deps, jp_dict=jp_dict)
|
||||
except Exception as err:
|
||||
msg = f"| 分析响应失败:{sheet}_{iid}_{name}_{desc}"
|
||||
f"\nregex={regex};"
|
||||
f" \nkeys={keys};"
|
||||
f"\ndeps={deps};"
|
||||
f"\njp_dict={jp_dict}"
|
||||
f"\n{err}"
|
||||
ParameterExtractionError(msg, err)
|
||||
|
||||
def execute_validation(self, excel, sheet, iid, name, desc, expected):
|
||||
expected = self.replace_dependent_parameter(expected)
|
||||
try:
|
||||
self.run_validate(expected, self.response_json)
|
||||
result = "PASS"
|
||||
except Exception as e:
|
||||
result = "FAIL"
|
||||
error_info = f"| exception case:**{sheet}_{iid}_{name}_{desc},{self.assertions}"
|
||||
AssertionFailedError(error_info, e)
|
||||
raise e
|
||||
finally:
|
||||
print(f'| <span style="color:yellow">断言结果-->{self.assertions}</span>\n')
|
||||
print("-" * 50 + "我是分割线" + "-" * 50)
|
||||
response = self.response.text if self.response is not None else str(self.response)
|
||||
excel.write_back(sheet_name=sheet, i=iid, response=response, result=result, assertions=str(self.assertions))
|
||||
|
||||
@property
|
||||
def variables(self, key=None):
|
||||
return self.__variables if not key else self.__variables.get(key)
|
||||
|
||||
@variables.setter
|
||||
def variables(self, item):
|
||||
self.__variables = item
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(Action())
|
||||
|
|
|
@ -20,7 +20,7 @@ from common.utils.exceptions import RequestSendingError
|
|||
def singleton(cls):
|
||||
"""
|
||||
Args:
|
||||
cls:被装饰类
|
||||
cls:Decorated class
|
||||
Returns:
|
||||
"""
|
||||
instance = {}
|
||||
|
@ -35,7 +35,7 @@ def singleton(cls):
|
|||
|
||||
|
||||
def request_retry_on_exception(retries=2, delay=1.5):
|
||||
"""失败请求重发"""
|
||||
"""Retry on Failed Requests"""
|
||||
|
||||
def request_decorator(func):
|
||||
e = None
|
||||
|
@ -54,7 +54,6 @@ def request_retry_on_exception(retries=2, delay=1.5):
|
|||
print(f"| 接口状态--> {response.status_code}")
|
||||
print(f"| 接口耗时--> {response.elapsed}")
|
||||
print(f"| 接口响应--> {response.text}")
|
||||
|
||||
except Exception as error:
|
||||
|
||||
e = error
|
||||
|
@ -70,7 +69,7 @@ def request_retry_on_exception(retries=2, delay=1.5):
|
|||
|
||||
def list_data(datas):
|
||||
"""
|
||||
:param datas: 测试数据
|
||||
:param datas: Test data
|
||||
:return:
|
||||
"""
|
||||
|
||||
|
@ -83,7 +82,7 @@ def list_data(datas):
|
|||
|
||||
def yaml_data(file_path):
|
||||
"""
|
||||
:param file_path: yaml文件路径
|
||||
:param file_path:YAML file path
|
||||
:return:
|
||||
"""
|
||||
|
||||
|
@ -102,7 +101,7 @@ def yaml_data(file_path):
|
|||
|
||||
def json_data(file_path):
|
||||
"""
|
||||
:param file_path: json文件路径
|
||||
:param file_path: YAML file path
|
||||
:return:
|
||||
"""
|
||||
|
||||
|
@ -123,7 +122,7 @@ import time
|
|||
|
||||
|
||||
def run_count(count, interval, func, *args, **kwargs):
|
||||
"""运行计数"""
|
||||
"""Run Count"""
|
||||
for i in range(count):
|
||||
try:
|
||||
func(*args, **kwargs)
|
||||
|
@ -141,9 +140,9 @@ def run_count(count, interval, func, *args, **kwargs):
|
|||
|
||||
def rerun(count, interval=2):
|
||||
"""
|
||||
单个测试用例重运行的装饰器,注意点,如果使用了ddt,那么该方法要在用在ddt之前
|
||||
:param count: 失败重运行次数
|
||||
:param interval: 每次重运行间隔时间,默认三秒钟
|
||||
Decorator for rerunning a single test case; note that if using ddt, this method should be used before ddt
|
||||
:param count: Number of retries on failure
|
||||
:param interval: Interval time between each retry, default is three seconds
|
||||
:return:
|
||||
"""
|
||||
|
||||
|
@ -157,13 +156,15 @@ def rerun(count, interval=2):
|
|||
|
||||
|
||||
def install_dependencies(func):
|
||||
"""Checking and Installing Dependencies"""
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
|
||||
try:
|
||||
print("---------------- 檢測并且安装依赖文件 ----------------")
|
||||
print("---------------- Checking and Installing Dependencies ----------------")
|
||||
subprocess.check_call(["pipenv", "install"])
|
||||
print("---------------- 成功安装所有依赖文件 ----------------")
|
||||
print("---------------- Successfully Installed All Dependencies ----------------")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Failed to install dependencies: {str(e)}")
|
||||
|
@ -172,3 +173,27 @@ def install_dependencies(func):
|
|||
return func(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def send_request_decorator(func):
|
||||
"""Decorator to handle the logic of sending requests."""
|
||||
|
||||
def decorator(self, host, method, extract_request_data):
|
||||
"""Handles setup, request execution, and teardown logic for sending requests.
|
||||
|
||||
Args:
|
||||
self: The instance of the class.
|
||||
host: The host for the request.
|
||||
method: The HTTP method for the request.
|
||||
extract_request_data: Data for extracting request details.
|
||||
|
||||
Returns:
|
||||
The response from the request.
|
||||
"""
|
||||
setup_script, teardown_script = self.script(self.variables)
|
||||
self.execute_dynamic_code(self.variables, setup_script)
|
||||
response = func(self, host, method, extract_request_data)
|
||||
self.execute_dynamic_code(self.response, teardown_script)
|
||||
return response
|
||||
|
||||
return decorator
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -175,10 +175,8 @@ def length_lte(actual_value, expect_value):
|
|||
Returns:
|
||||
|
||||
"""
|
||||
assert isinstance(expect_value, (
|
||||
int,)), p_string(actual_value, expect_value)
|
||||
assert len(
|
||||
actual_value) <= expect_value, p_string(actual_value, expect_value)
|
||||
assert isinstance(expect_value, (int,)), p_string(actual_value, expect_value)
|
||||
assert len(actual_value) <= expect_value, p_string(actual_value, expect_value)
|
||||
|
||||
|
||||
def contains(actual_value, expect_value):
|
||||
|
@ -296,3 +294,4 @@ def endswith(actual_value, expect_value):
|
|||
|
||||
if __name__ == '__main__':
|
||||
eq(1, "1")
|
||||
lte(1.23, 400.3)
|
||||
|
|
|
@ -74,7 +74,7 @@ class Validator(Loaders):
|
|||
check_item = validate_variable['check']
|
||||
expect_value = validate_variable['expect']
|
||||
comparator = validate_variable['comparator']
|
||||
if not check_item.startswith("$"):
|
||||
if not str(check_item).startswith("$"):
|
||||
actual_value = check_item
|
||||
else:
|
||||
actual_value = Extractor.extract_value_by_jsonpath(resp_obj=resp, expr=check_item)
|
||||
|
@ -111,7 +111,7 @@ class Validator(Loaders):
|
|||
self.uniform_validate(validate_variables)
|
||||
if not self.validate_variables_list:
|
||||
raise InvalidParameterFormatError(self.validate_variables_list,
|
||||
"uniform_validate 执行失败,无法进行 validate 校验")
|
||||
"uniform_validate 执行失败,无法进行 validate 校验")
|
||||
self.validate(resp)
|
||||
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -36,27 +36,19 @@ class TestProjectApi(unittest.TestCase):
|
|||
|
||||
@list_data(test_case)
|
||||
def test_api(self, item):
|
||||
sheet, iid, condition, st, name, desc, h_crypto, r_crypto, method, expected = self.action.base_info(item)
|
||||
sheet, iid, condition, st, name, desc, method, expected = self.action.base_info(item)
|
||||
if self.action.is_run(condition):
|
||||
self.skipTest("这个测试用例听说泡面比较好吃,所以放弃执行了!!")
|
||||
regex, keys, deps, jp_dict, ex_request_data = self.action.extractor_info(item)
|
||||
setup_script, teardown_script = self.action.script(item)
|
||||
self.action.pause_execution(st)
|
||||
self.action.exc_sql(item)
|
||||
if method.upper() == 'SQL':
|
||||
self.skipTest("这条测试用例被 SQL 吃了,所以放弃执行了!!")
|
||||
item = self.action.execute_dynamic_code(item, setup_script)
|
||||
|
||||
# prepost_script = f"prepost_script_{sheet}_{iid}.py"
|
||||
# item = self.action.load_and_execute_script(Config.SCRIPTS_DIR, prepost_script, "setup", item)
|
||||
|
||||
item = self.action.replace_dependent_parameter(item)
|
||||
url, query_str, request_data, headers, request_data_type = self.action.request_info(item)
|
||||
headers, request_data = self.action.analysis_request(request_data, h_crypto, headers, r_crypto, ex_request_data)
|
||||
kwargs = {request_data_type: request_data, 'headers': headers, "params": query_str}
|
||||
self.action.send_request(host, url, method, teardown_script, **kwargs)
|
||||
self.action.send_request(host, method, ex_request_data)
|
||||
self.action.analysis_response(sheet, iid, name, desc, regex, keys, deps, jp_dict)
|
||||
expected = self.action.replace_dependent_parameter(expected)
|
||||
self.action.execute_validation(excel, sheet, iid, name, desc, expected)
|
||||
|
||||
@classmethod
|
||||
|
|
Loading…
Reference in New Issue