pytest-api-framework-alpha 0.1.2__tar.gz → 0.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/PKG-INFO +1 -1
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/render_data.py +9 -56
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/startapp.py +14 -3
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/pytest_api_framework_alpha.egg-info/PKG-INFO +1 -1
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/setup.py +1 -1
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/__init__.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/allure_report.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/base_class.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/conftest.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/db/__init__.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/db/mysql_db.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/db/redis_db.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/exit_code.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/extract.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/global_attribute.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/http_client.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/report.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/utils/__init__.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/utils/common.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/utils/encrypt.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/utils/log_util.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/utils/teams_util.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/utils/yaml_util.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/validate.py +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/pytest_api_framework_alpha.egg-info/SOURCES.txt +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/pytest_api_framework_alpha.egg-info/dependency_links.txt +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/pytest_api_framework_alpha.egg-info/requires.txt +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/pytest_api_framework_alpha.egg-info/top_level.txt +0 -0
- {pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/setup.cfg +0 -0
{pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/render_data.py
RENAMED
|
@@ -5,6 +5,7 @@ import traceback
|
|
|
5
5
|
|
|
6
6
|
import allure
|
|
7
7
|
import pytest
|
|
8
|
+
from box import Box
|
|
8
9
|
from faker import Faker
|
|
9
10
|
from framework.exit_code import ExitCode
|
|
10
11
|
from framework.utils.log_util import logger
|
|
@@ -31,7 +32,7 @@ class RenderData(object):
|
|
|
31
32
|
def __init__(self, data):
|
|
32
33
|
self.data = data
|
|
33
34
|
self.request = data.get("request")
|
|
34
|
-
self.scenario = data.get("_scenario").get("data")
|
|
35
|
+
self.scenario = Box(data.get("_scenario").get("data"))
|
|
35
36
|
self.context = CONTEXT
|
|
36
37
|
self.faker = SingletonFaker(locale=FAKER_LANGUAGE).faker
|
|
37
38
|
self._is_multipart = False
|
|
@@ -42,39 +43,11 @@ class RenderData(object):
|
|
|
42
43
|
:return:
|
|
43
44
|
"""
|
|
44
45
|
with allure.step("渲染数据"):
|
|
45
|
-
if self.scenario:
|
|
46
|
-
self.request = self.replace_variables_recursive(self.request, self.scenario)
|
|
47
46
|
self.replace_attribute(self.request)
|
|
48
47
|
self.data["request"] = self.request
|
|
49
48
|
self.data["_is_multipart"] = self._is_multipart
|
|
50
49
|
return self.data
|
|
51
50
|
|
|
52
|
-
def replace_variables_recursive(self, data, params):
|
|
53
|
-
"""
|
|
54
|
-
递归遍历 data 并用 params[key] 替换 ${key} 变量,保持数据类型
|
|
55
|
-
"""
|
|
56
|
-
|
|
57
|
-
if isinstance(data, dict): # 处理字典
|
|
58
|
-
new_dict = {}
|
|
59
|
-
for key, value in data.items():
|
|
60
|
-
new_dict[key] = self.replace_variables_recursive(value, params) # 递归处理
|
|
61
|
-
return new_dict
|
|
62
|
-
|
|
63
|
-
elif isinstance(data, list): # 处理列表
|
|
64
|
-
return [self.replace_variables_recursive(item, params) for item in data]
|
|
65
|
-
|
|
66
|
-
elif isinstance(data, str) and data.startswith("${") and data.endswith("}"):
|
|
67
|
-
# 仅当字符串是完整的 "${key}" 格式时才替换
|
|
68
|
-
key = data[2:-1] # 提取 key 名称
|
|
69
|
-
if key in params.keys():
|
|
70
|
-
value = params[key]
|
|
71
|
-
logger.info(f"前置读取变量: {key}: {value}")
|
|
72
|
-
return value # 直接赋值(不存在则返回原值)
|
|
73
|
-
return data
|
|
74
|
-
|
|
75
|
-
else: # 其他类型(int, float, bool, None)直接返回
|
|
76
|
-
return data
|
|
77
|
-
|
|
78
51
|
def replace_attribute(self, data):
|
|
79
52
|
pattern = re.compile(r"\$\{([\w.\[\]0-9]+(?:\(\w*(?:,\w*)*\))?)}")
|
|
80
53
|
file_path_pattern = re.compile(
|
|
@@ -137,13 +110,15 @@ class RenderData(object):
|
|
|
137
110
|
new_expression = f"{belong_app}.{expression}"
|
|
138
111
|
else:
|
|
139
112
|
new_expression = expression
|
|
140
|
-
value = self.get_nested_value(self.context, expression) or self.get_nested_value(self.context, new_expression)
|
|
141
113
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
114
|
+
value = (
|
|
115
|
+
self.get_nested_value(self.scenario, expression)
|
|
116
|
+
if self.get_nested_value(self.scenario, expression) is not None else
|
|
117
|
+
self.get_nested_value(self.context, new_expression)
|
|
118
|
+
if self.get_nested_value(self.context, new_expression) is not None else
|
|
119
|
+
self.get_nested_value(self.context, expression)
|
|
120
|
+
)
|
|
145
121
|
|
|
146
|
-
return None
|
|
147
122
|
with allure.step(f"{expression}: {value}"):
|
|
148
123
|
logger.info(f"前置读取变量: {expression}: {value}")
|
|
149
124
|
return value
|
|
@@ -171,28 +146,6 @@ class RenderData(object):
|
|
|
171
146
|
logger.info(f"前置读取函数: {keyword}: {value}")
|
|
172
147
|
return value
|
|
173
148
|
|
|
174
|
-
def get_file_obj(self, data, pattern):
|
|
175
|
-
# 如果 data 是字典,则遍历每一个键值对
|
|
176
|
-
if isinstance(data, dict):
|
|
177
|
-
for key, value in data.items():
|
|
178
|
-
# 递归调用处理值
|
|
179
|
-
data[key] = self.get_file_obj(value, pattern)
|
|
180
|
-
|
|
181
|
-
# 如果 data 是列表,则遍历每一个元素
|
|
182
|
-
elif isinstance(data, list):
|
|
183
|
-
for index in range(len(data)):
|
|
184
|
-
# 递归调用处理列表中的每一个元素
|
|
185
|
-
data[index] = self.get_file_obj(data[index], pattern)
|
|
186
|
-
|
|
187
|
-
# 如果 data 是字符串,则检查是否匹配正则表达式
|
|
188
|
-
elif isinstance(data, str):
|
|
189
|
-
if re.fullmatch(pattern, data):
|
|
190
|
-
# 如果匹配,则替换为文件流
|
|
191
|
-
self._is_multipart = True
|
|
192
|
-
return self.open_file_for_multipart(data)
|
|
193
|
-
# 返回处理后的数据
|
|
194
|
-
return data
|
|
195
|
-
|
|
196
149
|
@staticmethod
|
|
197
150
|
def get_nested_value(obj, attr_path):
|
|
198
151
|
"""通过字符串路径(如 'a.b[0].c')获取嵌套属性值"""
|
|
@@ -52,7 +52,7 @@ class TestUntitled(BaseTestCase):
|
|
|
52
52
|
|
|
53
53
|
def test_untitled(self):
|
|
54
54
|
# 发送请求
|
|
55
|
-
self.request(app="{app}", account="
|
|
55
|
+
self.request(app="{app}", account="admin", data=self.data)
|
|
56
56
|
# 断言
|
|
57
57
|
assert self.response.status_code == 200
|
|
58
58
|
assert len(self.response.jsonpath("$.data.balances")) > 0"""
|
|
@@ -67,7 +67,17 @@ def create_test_data(app):
|
|
|
67
67
|
yaml.dump({
|
|
68
68
|
"case_common": {
|
|
69
69
|
"module": "功能模块名称",
|
|
70
|
-
"describe": "测试场景描述"
|
|
70
|
+
"describe": "测试场景描述",
|
|
71
|
+
"scenarios": [
|
|
72
|
+
{
|
|
73
|
+
"scenario": {
|
|
74
|
+
"data": {
|
|
75
|
+
"tag_id": 4,
|
|
76
|
+
"user_id": 1
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
]
|
|
71
81
|
},
|
|
72
82
|
"test_untitled": {
|
|
73
83
|
"title": "登录成功",
|
|
@@ -76,7 +86,8 @@ def create_test_data(app):
|
|
|
76
86
|
"url": "/login",
|
|
77
87
|
"method": "post",
|
|
78
88
|
"json": {
|
|
79
|
-
"name": "Jerry"
|
|
89
|
+
"name": "Jerry",
|
|
90
|
+
"user_id": "${user_id}"
|
|
80
91
|
}
|
|
81
92
|
},
|
|
82
93
|
"extract": [
|
|
File without changes
|
{pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/allure_report.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/base_class.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/db/__init__.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/db/mysql_db.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/db/redis_db.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/exit_code.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/global_attribute.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/http_client.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/utils/__init__.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/utils/common.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/utils/encrypt.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/utils/log_util.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/utils/teams_util.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.1.2 → pytest_api_framework_alpha-0.1.3}/framework/utils/yaml_util.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|