pytest-api-framework-alpha 0.2.3__tar.gz → 0.2.5__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.
Files changed (31) hide show
  1. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/PKG-INFO +2 -1
  2. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/conftest.py +3 -2
  3. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/http_client.py +28 -15
  4. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/utils/common.py +0 -6
  5. pytest_api_framework_alpha-0.2.5/framework/utils/mock_util.py +159 -0
  6. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/pytest_api_framework_alpha.egg-info/PKG-INFO +2 -1
  7. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/pytest_api_framework_alpha.egg-info/SOURCES.txt +1 -0
  8. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/pytest_api_framework_alpha.egg-info/requires.txt +1 -0
  9. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/setup.py +3 -2
  10. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/__init__.py +0 -0
  11. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/allure_report.py +0 -0
  12. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/base_class.py +0 -0
  13. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/db/__init__.py +0 -0
  14. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/db/mysql_db.py +0 -0
  15. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/db/redis_db.py +0 -0
  16. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/exit_code.py +0 -0
  17. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/extract.py +0 -0
  18. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/global_attribute.py +0 -0
  19. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/render_data.py +0 -0
  20. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/report.py +0 -0
  21. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/settings.py +0 -0
  22. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/startapp.py +0 -0
  23. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/utils/__init__.py +0 -0
  24. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/utils/encrypt.py +0 -0
  25. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/utils/log_util.py +0 -0
  26. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/utils/teams_util.py +0 -0
  27. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/utils/yaml_util.py +0 -0
  28. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/framework/validate.py +0 -0
  29. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/pytest_api_framework_alpha.egg-info/dependency_links.txt +0 -0
  30. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/pytest_api_framework_alpha.egg-info/top_level.txt +0 -0
  31. {pytest_api_framework_alpha-0.2.3 → pytest_api_framework_alpha-0.2.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytest-api-framework-alpha
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Author: alpha
5
5
  Author-email:
6
6
  Requires-Python: >=3.6
@@ -23,6 +23,7 @@ Requires-Dist: requests==2.25.1
23
23
  Requires-Dist: requests-toolbelt==1.0.0
24
24
  Requires-Dist: retry==0.9.2
25
25
  Requires-Dist: dill==0.3.8
26
+ Requires-Dist: simplejson==3.20.1
26
27
  Dynamic: author
27
28
  Dynamic: requires-dist
28
29
  Dynamic: requires-python
@@ -17,6 +17,7 @@ import retry
17
17
  import allure
18
18
  import pytest
19
19
  from box import Box
20
+ import simplejson as json
20
21
 
21
22
  from framework.exit_code import ExitCode
22
23
  from framework.db.mysql_db import MysqlDB
@@ -399,7 +400,7 @@ def pytest_runtest_setup(item):
399
400
  test_object.http = _FRAMEWORK_CONTEXT.get(key="_http")
400
401
  data = item.callspec.params.get("data")
401
402
  test_object.data = Box(data)
402
- test_object.scenario = Box(convert_numbers_to_decimal(data.get("_scenario").get("data")))
403
+ test_object.scenario = Box(json.loads(json.dumps(convert_numbers_to_decimal(data.get("_scenario").get("data")))))
403
404
  test_object.belong_app = data.get("_belong_app")
404
405
  test_before_scenario = getattr(test_object, "test_setup", None)
405
406
  if test_before_scenario:
@@ -456,7 +457,7 @@ def pytest_runtest_call(item):
456
457
  http = item.funcargs.get("http")
457
458
  item.funcargs["data"] = item.instance.data = Box(origin_data)
458
459
  item.funcargs["scenario"] = item.instance.scenario = Box(
459
- convert_numbers_to_decimal(origin_data.get("_scenario").get("data")))
460
+ json.loads(json.dumps(convert_numbers_to_decimal(origin_data.get("_scenario").get("data")))))
460
461
  _belong_app = origin_data.get("_belong_app")
461
462
  item.funcargs["belong_app"] = item.instance.belong_app = _belong_app
462
463
  item.funcargs["config"] = item.instance.config = CONFIG
@@ -4,7 +4,8 @@ from urllib.parse import urljoin
4
4
 
5
5
  import allure
6
6
  import requests
7
- import json as built_json
7
+ import simplejson as built_json
8
+
8
9
  from box import Box, BoxList
9
10
  from jsonpath import jsonpath as jp
10
11
  from requests.models import Response
@@ -22,9 +23,9 @@ class ResponseUtil(object):
22
23
  def __init__(self, response: Response):
23
24
  self.response = response
24
25
  if isinstance(self.response.json(), dict):
25
- self.box = Box(convert_numbers_to_decimal(self.response.json()))
26
+ self.box = Box(built_json.loads(built_json.dumps(convert_numbers_to_decimal(self.response.json()))))
26
27
  elif isinstance(self.response.json(), list):
27
- self.box = BoxList(convert_numbers_to_decimal(self.response.json()))
28
+ self.box = BoxList(built_json.loads(built_json.dumps(convert_numbers_to_decimal(self.response.json()))))
28
29
  else:
29
30
  self.box = self.response.text
30
31
 
@@ -111,31 +112,36 @@ class HttpClient(object):
111
112
 
112
113
  with allure.step(f"请求url: {request_obj.get('url')}"):
113
114
  logger.info(f"请求url: {request_obj.get('url')}")
115
+
114
116
  with allure.step(f"请求method: {request_obj.get('method')}"):
115
117
  logger.info(f"请求method: {request_obj.get('method')}")
116
- with allure.step(f"请求headers: {built_json.dumps(request_obj.get('headers'))}"):
118
+
119
+ with allure.step(f"请求headers: {HttpClient.json(request_obj.get('headers'))}"):
117
120
  if CONSOLE_DETAILED_LOG:
121
+ logger.info(f"请求headers: {HttpClient.json(request_obj.get('headers'))}")
118
122
 
119
- logger.info(f"请求headers: {built_json.dumps(request_obj.get('headers'))}")
120
123
  if request_obj.get('params'):
121
- with allure.step(f"请求参数params: {built_json.dumps(request_obj.get('params'))}"):
122
- logger.info(f"请求参数params: {built_json.dumps(request_obj.get('params'))}")
124
+ with allure.step(f"请求参数params: {HttpClient.json(request_obj.get('params'))}"):
125
+ logger.info(f"请求参数params: {HttpClient.json(request_obj.get('params'))}")
126
+
123
127
  if request_obj.get('data'):
124
- with allure.step(f"请求参数data: {built_json.dumps(request_obj.get('data'))}"):
125
- logger.info(f"请求参数data: {built_json.dumps(request_obj.get('data'))}")
128
+ with allure.step(f"请求参数data: {request_obj.get('data')}"):
129
+ logger.info(f"请求参数data: {request_obj.get('data')}")
130
+
126
131
  if request_obj.get('json'):
127
- with allure.step(f"请求参数json: {built_json.dumps(request_obj.get('json'))}"):
128
- logger.info(f"请求参数json: {built_json.dumps(request_obj.get('json'))}")
132
+ with allure.step(f"请求参数json: {HttpClient.json(request_obj.get('json'))}"):
133
+ logger.info(f"请求参数json: {HttpClient.json(request_obj.get('json'))}")
129
134
 
130
135
  with allure.step("响应结果"):
131
136
  with allure.step(f"响应status code: {self.response.status_code}"):
132
137
  logger.info(f"响应status code: {self.response.status_code}")
133
138
 
134
- with allure.step(f"响应headers: {built_json.dumps(dict(self.response.headers))}"):
139
+ with allure.step(f"响应headers: {HttpClient.json(dict(self.response.headers))}"):
135
140
  if CONSOLE_DETAILED_LOG:
136
- logger.info(f"响应headers: {built_json.dumps(dict(self.response.headers))}")
137
- with allure.step(f"响应body: {built_json.dumps(self.response.json())}"):
138
- logger.info(f"响应body: {built_json.dumps(self.response.json())}")
141
+ logger.info(f"响应headers: {HttpClient.json(dict(self.response.headers))}")
142
+
143
+ with allure.step(f"响应body: {HttpClient.json(self.response.json())}"):
144
+ logger.info(f"响应body: {HttpClient.json(self.response.json())}")
139
145
 
140
146
  # 断言
141
147
  validates = data.get("validate")
@@ -175,3 +181,10 @@ class HttpClient(object):
175
181
 
176
182
  def update_headers(self, headers):
177
183
  self.headers.update(headers)
184
+
185
+ @staticmethod
186
+ def json(dic):
187
+ try:
188
+ return built_json.dumps(dic)
189
+ except:
190
+ return dic
@@ -265,9 +265,3 @@ def convert_numbers_to_decimal(obj: Any) -> Any:
265
265
  def remove_spaces(s: str) -> str:
266
266
  """去掉字符串中的所有空格"""
267
267
  return s.replace(" ", "")
268
-
269
-
270
- if __name__ == '__main__':
271
- a = decimal.Decimal("123")
272
- print(a)
273
- assert a == 123
@@ -0,0 +1,159 @@
1
+ import requests
2
+ from enum import Enum, unique
3
+ from typing import Dict, Optional
4
+
5
+ from config.settings import AVAILABLE_ENVS, ENV_CONFIG
6
+
7
+
8
+ @unique
9
+ class PaymentType(Enum):
10
+ """支付类型枚举"""
11
+ DEPOSIT = 0 # 入金
12
+ WITHDRAWAL = 1 # 出金
13
+ CHECKOUT = 2 # 结账
14
+
15
+
16
+ @unique
17
+ class RiskLevel(Enum):
18
+ """风险等级枚举"""
19
+ DISABLE_MOCK = 0 # 禁用模拟
20
+ LOW = 1 # 低风险
21
+ MEDIUM_LOW = 2 # 中低风险
22
+ MEDIUM_HIGH = 3 # 中高风险
23
+ HIGH = 4 # 高风险
24
+ SEVERE = 5 # 严重风险
25
+
26
+
27
+ @unique
28
+ class IsDelayed(Enum):
29
+ """是否延迟枚举"""
30
+ NO_DELAY = 0 # 不延迟
31
+ DELAY = 1 # 延迟
32
+
33
+
34
+ def get_environment_config(env: str) -> Dict:
35
+ """
36
+ 获取指定环境的完整配置
37
+
38
+ 参数:
39
+ env: 环境名称(如"dev", "test"等)
40
+
41
+ 返回:
42
+ 对应环境的配置字典
43
+
44
+ 异常:
45
+ ValueError: 当环境名称不存在时抛出
46
+ """
47
+ if env not in AVAILABLE_ENVS:
48
+ raise ValueError(f"不支持的环境: {env},可用环境: {AVAILABLE_ENVS}")
49
+ return ENV_CONFIG[env]
50
+
51
+
52
+ def get_full_api_url(env,method):
53
+ """拼接完整的API URL"""
54
+ config = get_environment_config(env)
55
+ return f"{config['base_url']}{config[method]}"
56
+
57
+
58
+ def set_customized_kytmock(env: str,request_id: str, payment_type: PaymentType,risk_level: RiskLevel,is_delayed: IsDelayed = IsDelayed.NO_DELAY):
59
+ """
60
+ 调用指定环境的HTTP接口
61
+
62
+ 参数:
63
+ env: 环境名称(如"dev", "test")
64
+ request_id: 请求ID
65
+ payment_type: 支付类型枚举
66
+ risk_level: 风险等级枚举
67
+ is_delayed: 是否延迟枚举,默认不延迟
68
+ custom_url: 自定义URL(可选,用于临时测试特殊地址)
69
+
70
+ 返回:
71
+ 接口响应的JSON字典,失败则返回None
72
+ """
73
+ # 获取环境配置
74
+ env_config = get_environment_config(env)
75
+ method = "set_mock"
76
+ url = get_full_api_url(env,method)
77
+
78
+ # 参数验证
79
+ if not isinstance(request_id, str) or not request_id:
80
+ raise ValueError("request_id必须是非空字符串")
81
+
82
+ for param, name in [
83
+ (payment_type, "payment_type"),
84
+ (risk_level, "risk_level"),
85
+ (is_delayed, "is_delayed")
86
+ ]:
87
+ if not isinstance(param, (PaymentType, RiskLevel, IsDelayed)):
88
+ raise ValueError(f"{name}必须是对应的枚举类型")
89
+
90
+ # 构建请求参数
91
+ payload = {
92
+ "request_id": request_id,
93
+ "payment_type": payment_type.value,
94
+ "risk_level": risk_level.value,
95
+ "is_delayed": is_delayed.value
96
+ }
97
+
98
+ try:
99
+ # 使用环境配置中的超时时间
100
+ response = requests.post(
101
+ url,
102
+ json=payload,
103
+ timeout=env_config["timeout"]
104
+ )
105
+ response.raise_for_status()
106
+
107
+ return response.json()
108
+ except requests.exceptions.HTTPError as e:
109
+ print(f"HTTP错误 [{env}]: {e}")
110
+ except requests.exceptions.RequestException as e:
111
+ print(f"请求异常 [{env}]: {e}")
112
+ except ValueError:
113
+ print(f"响应解析失败 [{env}]")
114
+
115
+ return None
116
+
117
+
118
+ def get_customized_kytmock(env,request_id):
119
+ # 获取环境配置
120
+ env_config = get_environment_config(env)
121
+
122
+ # 参数验证
123
+ if not isinstance(request_id, str) or not request_id:
124
+ raise ValueError("request_id必须是非空字符串")
125
+ method = f"get_mock"
126
+ url = f"{get_full_api_url(env, method)}{request_id}"
127
+ try:
128
+ response = requests.get(url)
129
+ return response.json()
130
+ except requests.exceptions.HTTPError as e:
131
+ print(f"HTTP错误 [{env}]: {e}")
132
+ except requests.exceptions.RequestException as e:
133
+ print(f"请求异常 [{env}]: {e}")
134
+ except ValueError:
135
+ print(f"响应解析失败 [{env}]")
136
+
137
+ return None
138
+
139
+ if __name__ == "__main__":
140
+ # # 1. 调用测试环境的入金接口
141
+ # test_deposit = set_customized_kytmock(
142
+ # env="dev",
143
+ # request_id="A0101585",
144
+ # payment_type=PaymentType.DEPOSIT,
145
+ # risk_level=RiskLevel.LOW
146
+ # )
147
+ # print(f"测试环境入金响应: {test_deposit}")
148
+ #
149
+ # # 2. 调用测试环境的出金接口
150
+ # dev_withdrawal = set_customized_kytmock(
151
+ # env="dev",
152
+ # request_id="0xf3C3e95597544cD0525393CE49B685994b8e50A7",
153
+ # payment_type=PaymentType.WITHDRAWAL,
154
+ # risk_level=RiskLevel.LOW
155
+ # )
156
+ # print(f"开发环境出金响应: {dev_withdrawal}")
157
+
158
+ get_content = get_customized_kytmock("dev","A0101585")
159
+ print(f"查询结果:{get_content}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytest-api-framework-alpha
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Author: alpha
5
5
  Author-email:
6
6
  Requires-Python: >=3.6
@@ -23,6 +23,7 @@ Requires-Dist: requests==2.25.1
23
23
  Requires-Dist: requests-toolbelt==1.0.0
24
24
  Requires-Dist: retry==0.9.2
25
25
  Requires-Dist: dill==0.3.8
26
+ Requires-Dist: simplejson==3.20.1
26
27
  Dynamic: author
27
28
  Dynamic: requires-dist
28
29
  Dynamic: requires-python
@@ -19,6 +19,7 @@ framework/utils/__init__.py
19
19
  framework/utils/common.py
20
20
  framework/utils/encrypt.py
21
21
  framework/utils/log_util.py
22
+ framework/utils/mock_util.py
22
23
  framework/utils/teams_util.py
23
24
  framework/utils/yaml_util.py
24
25
  pytest_api_framework_alpha.egg-info/PKG-INFO
@@ -17,3 +17,4 @@ requests==2.25.1
17
17
  requests-toolbelt==1.0.0
18
18
  retry==0.9.2
19
19
  dill==0.3.8
20
+ simplejson==3.20.1
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="pytest-api-framework-alpha", # 包名(必须唯一)
5
- version="0.2.3",
5
+ version="0.2.5",
6
6
  packages=find_packages(),
7
7
  author="alpha",
8
8
  author_email="",
@@ -27,6 +27,7 @@ setup(
27
27
  "requests==2.25.1",
28
28
  "requests-toolbelt==1.0.0",
29
29
  "retry==0.9.2",
30
- "dill==0.3.8"
30
+ "dill==0.3.8",
31
+ "simplejson==3.20.1"
31
32
  ]
32
33
  )