pytest-api-framework-alpha 0.3.14__tar.gz → 0.3.16__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 (32) hide show
  1. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/PKG-INFO +1 -1
  2. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/base_class.py +5 -5
  3. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/conftest.py +39 -18
  4. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/utils/lark_util.py +13 -1
  5. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/pytest_api_framework_alpha.egg-info/PKG-INFO +1 -1
  6. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/setup.py +1 -1
  7. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/__init__.py +0 -0
  8. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/db/__init__.py +0 -0
  9. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/db/mysql_db.py +0 -0
  10. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/db/redis_db.py +0 -0
  11. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/exceptions.py +0 -0
  12. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/exit_code.py +0 -0
  13. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/extract.py +0 -0
  14. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/global_attribute.py +0 -0
  15. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/http_client.py +0 -0
  16. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/render_data.py +0 -0
  17. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/report.py +0 -0
  18. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/script.py +0 -0
  19. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/startapp.py +0 -0
  20. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/utils/__init__.py +0 -0
  21. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/utils/common.py +0 -0
  22. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/utils/date_util.py +0 -0
  23. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/utils/encrypt.py +0 -0
  24. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/utils/log_util.py +0 -0
  25. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/utils/mock_util.py +0 -0
  26. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/utils/yaml_util.py +0 -0
  27. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/framework/validate.py +0 -0
  28. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/pytest_api_framework_alpha.egg-info/SOURCES.txt +0 -0
  29. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/pytest_api_framework_alpha.egg-info/dependency_links.txt +0 -0
  30. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/pytest_api_framework_alpha.egg-info/requires.txt +0 -0
  31. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/pytest_api_framework_alpha.egg-info/top_level.txt +0 -0
  32. {pytest_api_framework_alpha-0.3.14 → pytest_api_framework_alpha-0.3.16}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytest-api-framework-alpha
3
- Version: 0.3.14
3
+ Version: 0.3.16
4
4
  Author: alpha
5
5
  Author-email:
6
6
  Requires-Python: >=3.6
@@ -43,7 +43,7 @@ class BaseTestCase(ExtendBaseTestCase):
43
43
  response: ResponseUtil = None
44
44
  context: Union[GlobalAttribute, Box] = None
45
45
  config: Union[GlobalAttribute, Box] = None
46
- # faker方法文档 https://blog.csdn.net/m0_60052979/article/details/126368024
46
+ # faker方法文档 https://hellopython.readthedocs.io/zh-cn/latest/faker_generate_fake_data.html
47
47
  faker: Faker = SingletonFaker(locale=FAKER_LANGUAGE).faker
48
48
  env = CONTEXT.get("env")
49
49
  logger: logger = logger
@@ -221,8 +221,8 @@ class BaseTestCase(ExtendBaseTestCase):
221
221
  # 删除crm中钱包
222
222
  crm = self.mysql_conn(db=self.db.DB_CAMP_CRM)
223
223
  crm.execute(
224
- f"delete from tbl_crypto_wallet where id in (select wallet_id from tbl_participant_crypto_wallet where participant_code='{participant_code}');")
225
- crm.execute(f"delete from tbl_participant_crypto_wallet where participant_code='{participant_code}';")
224
+ f"delete from tbl_crypto_wallet where id in (select wallet_id from tbl_participant_crypto_wallet where wallet_tag ='MY HOT WALLET' and participant_code='{participant_code}');")
225
+ crm.execute(f"delete from tbl_participant_crypto_wallet where wallet_tag ='MY HOT WALLET' and participant_code='{participant_code}';")
226
226
 
227
227
  # 重新生成新钱包
228
228
  self.post(
@@ -253,8 +253,8 @@ class BaseTestCase(ExtendBaseTestCase):
253
253
  # 删除crm中钱包
254
254
  crm = self.mysql_conn(db=self.db.DB_CAMP_CRM)
255
255
  crm.execute(
256
- f"delete from tbl_crypto_wallet where id in (select crypto_wallet_id from tbl_buyer_crypto_wallet where participant_code='{buyer_participant_code}');")
257
- crm.execute(f"delete from tbl_buyer_crypto_wallet where participant_code='{buyer_participant_code}';")
256
+ f"delete from tbl_crypto_wallet where id in (select crypto_wallet_id from tbl_buyer_crypto_wallet where wallet_tag ='MY HOT WALLET' and participant_code='{buyer_participant_code}');")
257
+ crm.execute(f"delete from tbl_buyer_crypto_wallet where wallet_tag ='MY HOT WALLET' and participant_code='{buyer_participant_code}';")
258
258
 
259
259
  # 重新生成新钱包
260
260
  self.post(
@@ -122,12 +122,15 @@ def pytest_generate_tests(metafunc):
122
122
  # 获取当前用例对应的测试数据路径
123
123
  data_path = find_data_path_by_case(belong_app, module_name)
124
124
  if not data_path:
125
- logger.error(f"测试数据文件: {func_file_path} 不存在")
126
- traceback.print_exc()
127
- pytest.exit(ExitCode.CASE_YAML_NOT_EXIST)
125
+ logger.warning(f"测试数据文件: {func_file_path} 不存在")
126
+ return
127
+ # traceback.print_exc()
128
+ # pytest.exit(ExitCode.CASE_YAML_NOT_EXIST)
128
129
  # yml转json
129
130
  test_data = CachedYamlLoader(data_path).load_yml()
130
-
131
+ if not test_data:
132
+ logger.warning(f"测试数据文件: {func_file_path} 内容为空")
133
+ return
131
134
  # 测试用例公共数据
132
135
  case_common = test_data.get("case_common")
133
136
  # 忽略的用例直接跳过
@@ -167,6 +170,8 @@ def pytest_generate_tests(metafunc):
167
170
  case_data["_belong_app"] = belong_app
168
171
  # 根据belong_app获取域名
169
172
  domain = CONTEXT.get(key="domain", app=belong_app)
173
+ if not domain:
174
+ return
170
175
  domain = domain if domain.startswith("http") else f"https://{domain}"
171
176
  # 获取request中的url
172
177
  url = case_data.get("request").get("url")
@@ -289,19 +294,18 @@ def pytest_collection_modifyitems(items):
289
294
  data = item.callspec.params["data"]
290
295
  if isinstance(data, dict):
291
296
  marks = data.get("_marks")
292
- for mark in marks:
293
- item.add_marker(mark)
294
-
295
-
297
+ if marks:
298
+ for mark in marks:
299
+ item.add_marker(mark)
296
300
 
297
301
 
298
302
  def pytest_collection_finish(session):
299
303
  """获取最终排序后的 items 列表"""
300
- logger.info(f"共收集到 {len(session.items)} 个测试用例")
301
304
  if not session.items:
302
305
  pytest.exit("未收集到用例")
303
306
  # 过滤掉item名称是test_setup或test_teardown的
304
307
  session.items = [item for item in session.items if item.name not in ["test_setup", "test_teardown"]]
308
+ logger.info(f"共收集到 {len(session.items)} 个测试用例")
305
309
 
306
310
  # 1. 筛选出带井号 名称带'#' 的item,并记录原始索引
307
311
  hash_items_with_index = [(index, item) for index, item in enumerate(session.items) if "#" in item.name]
@@ -322,8 +326,10 @@ def pytest_collection_finish(session):
322
326
  grouped_data = OrderedDict()
323
327
  # 按照#号后面的数字进行排序并分组
324
328
  for item in group_values:
325
- index = re.search(pattern, item.name).group(1)
326
- grouped_data.setdefault(index, []).append(item)
329
+ match_result = re.search(pattern, item.name)
330
+ if match_result:
331
+ index = match_result.group(1)
332
+ grouped_data.setdefault(index, []).append(item)
327
333
  # 标记每个分组的第一个和最后一个
328
334
  for group2 in grouped_data.values():
329
335
  group2[0].funcargs["first"] = True
@@ -356,9 +362,9 @@ def pytest_runtestloop(session):
356
362
  cls = getattr(importlib.import_module(module_path), class_name)
357
363
  cls().run()
358
364
  except Exception as e:
359
- logger.error(str(e))
360
- traceback.print_exc()
361
- pytest.exit(ExitCode.GLOBAL_SCRIPT_ERROR)
365
+ logger.warning(str(e))
366
+ # traceback.print_exc()
367
+ # pytest.exit(ExitCode.GLOBAL_SCRIPT_ERROR)
362
368
 
363
369
 
364
370
  def pytest_sessionfinish(session, exitstatus):
@@ -529,6 +535,7 @@ def pytest_terminal_summary(terminalreporter, exitstatus, config):
529
535
  if settings.ONLY_LINUX_NOTIFICATION:
530
536
  if "linux" not in platform.platform().lower():
531
537
  return
538
+ # 发送测试结果群消息
532
539
  for webhook in settings.LARK_WEBHOOKS.get(CONTEXT.get("env")):
533
540
  LarkUtil(webhook).send_test_report(
534
541
  total=total,
@@ -539,6 +546,16 @@ def pytest_terminal_summary(terminalreporter, exitstatus, config):
539
546
  job_name=os.environ.get("JOB_NAME"),
540
547
  env=CONTEXT.get("env")
541
548
  )
549
+ # 发送测试结果统计
550
+ LarkUtil(settings.LARK_CHART_WEBHOOKS.get(CONTEXT.get("env"))).send_test_chart(
551
+ total=total,
552
+ passed=passed,
553
+ failed=failed,
554
+ skipped=skipped,
555
+ job_name=os.environ.get("JOB_NAME"),
556
+ env=CONTEXT.get("env")
557
+ )
558
+
542
559
 
543
560
  def pytest_exception_interact(node, call, report):
544
561
  """
@@ -583,10 +600,14 @@ def inner_login(app):
583
600
  login_cls = getattr(module, f"{snake_to_pascal(app)}Login")
584
601
  setattr(Http, app, login_cls(app))
585
602
  # Token 过期时间写入上下文
586
- token_expiry = CONTEXT.get(app).get("token_expiry")
587
- if token_expiry:
588
- expire_time = datetime.now() + timedelta(seconds=token_expiry)
589
- _FRAMEWORK_CONTEXT.set(app=app, key="expire_time", value=expire_time)
603
+ application = CONTEXT.get(app)
604
+ if application:
605
+ token_expiry = application.get("token_expiry")
606
+ if token_expiry:
607
+ expire_time = datetime.now() + timedelta(seconds=token_expiry)
608
+ _FRAMEWORK_CONTEXT.set(app=app, key="expire_time", value=expire_time)
609
+ else:
610
+ logger.warning(f'{app} not found')
590
611
 
591
612
 
592
613
  def login():
@@ -84,4 +84,16 @@ class LarkUtil:
84
84
  if report_url:
85
85
  markdown += f"\n**测试报告:** [点击查看测试报告]({report_url})"
86
86
  title = f"【自动化测试结果】-{job_name} " if job_name else "【自动化测试结果】"
87
- return self.send_markdown(title, markdown)
87
+ return self.send_markdown(title, markdown)
88
+
89
+ def send_test_chart(self, total: int, passed: int, failed: int, skipped: int, job_name: str = None, env=None):
90
+
91
+ return requests.post(self.url, headers=self.headers,
92
+ json={
93
+ "job": job_name,
94
+ "total": total,
95
+ "passed": passed,
96
+ "failed": failed,
97
+ "skiped": skipped,
98
+ "env": env
99
+ })
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytest-api-framework-alpha
3
- Version: 0.3.14
3
+ Version: 0.3.16
4
4
  Author: alpha
5
5
  Author-email:
6
6
  Requires-Python: >=3.6
@@ -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.3.14",
5
+ version="0.3.16",
6
6
  packages=find_packages(),
7
7
  author="alpha",
8
8
  author_email="",