pytest-dsl 0.12.0__py3-none-any.whl → 0.13.0__py3-none-any.whl

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.
@@ -130,7 +130,8 @@ def _load_file_content(file_path: str, is_template: bool = False,
130
130
 
131
131
 
132
132
  def _process_request_config(config: Dict[str, Any],
133
- test_context: TestContext = None) -> Dict[str, Any]:
133
+ test_context: TestContext = None) -> \
134
+ Dict[str, Any]:
134
135
  """处理请求配置,检查并处理文件引用
135
136
 
136
137
  Args:
@@ -219,7 +220,15 @@ def _normalize_retry_config(config, assert_retry_count=None,
219
220
  if 'indices' in retry_assertions:
220
221
  standard_retry_config['indices'] = retry_assertions['indices']
221
222
  if 'specific' in retry_assertions:
222
- standard_retry_config['specific'] = retry_assertions['specific']
223
+ # 确保specific配置中的整数键被转换为字符串键,保持兼容性
224
+ specific_config = {}
225
+ for key, value in retry_assertions['specific'].items():
226
+ # 同时支持整数键和字符串键
227
+ specific_config[str(key)] = value
228
+ # 保留原始键类型以便查找
229
+ if isinstance(key, int):
230
+ specific_config[key] = value
231
+ standard_retry_config['specific'] = specific_config
223
232
 
224
233
  # 处理传统retry配置(如果专用配置不存在)
225
234
  elif 'retry' in config and config['retry']:
@@ -360,7 +369,17 @@ def http_request(context, **kwargs):
360
369
  # 执行请求
361
370
  response = http_req.execute(disable_auth=disable_auth)
362
371
 
363
- # 处理捕获
372
+ # 统一处理断言逻辑
373
+ with allure.step("执行断言验证"):
374
+ if retry_config['enabled']:
375
+ # 使用统一的重试处理函数
376
+ _process_assertions_with_unified_retry(http_req, retry_config,
377
+ disable_auth)
378
+ else:
379
+ # 不需要重试,直接断言
380
+ http_req.process_asserts()
381
+
382
+ # 在断言完成后获取最终的捕获值(可能在重试期间被更新)
364
383
  captured_values = http_req.captured_values
365
384
 
366
385
  # 将捕获的变量注册到上下文
@@ -371,15 +390,6 @@ def http_request(context, **kwargs):
371
390
  if save_response:
372
391
  context.set(save_response, response)
373
392
 
374
- # 统一处理断言逻辑
375
- with allure.step("执行断言验证"):
376
- if retry_config['enabled']:
377
- # 使用统一的重试处理函数
378
- _process_assertions_with_unified_retry(http_req, retry_config)
379
- else:
380
- # 不需要重试,直接断言
381
- http_req.process_asserts()
382
-
383
393
  # 获取会话状态(如果使用了会话)
384
394
  session_state = None
385
395
  if session_name:
@@ -447,7 +457,8 @@ def _deep_merge(dict1, dict2):
447
457
  return dict1
448
458
 
449
459
 
450
- def _process_assertions_with_unified_retry(http_req, retry_config):
460
+ def _process_assertions_with_unified_retry(http_req, retry_config,
461
+ disable_auth=False):
451
462
  """使用统一的重试配置处理断言
452
463
 
453
464
  Args:
@@ -482,6 +493,11 @@ def _process_assertions_with_unified_retry(http_req, retry_config):
482
493
  # 临时替换配置
483
494
  http_req.config = temp_config
484
495
 
496
+ # 确保在收集失败断言之前,response和captures是可用的
497
+ if not http_req.response:
498
+ # 如果response为空,重新执行一次请求
499
+ http_req.execute(disable_auth=disable_auth)
500
+
485
501
  # 重新运行断言,这次只收集失败的断言而不抛出异常
486
502
  _, failed_retryable_assertions = http_req.process_asserts()
487
503
  except Exception as collect_err:
@@ -582,7 +598,17 @@ def _process_assertions_with_unified_retry(http_req, retry_config):
582
598
  time.sleep(retry_interval)
583
599
 
584
600
  # 重新发送请求
585
- http_req.execute()
601
+ try:
602
+ http_req.execute(disable_auth=disable_auth)
603
+ except Exception as exec_error:
604
+ # 如果重新执行请求失败,记录错误并继续重试
605
+ allure.attach(
606
+ f"重试执行请求失败: {type(exec_error).__name__}: "
607
+ f"{str(exec_error)}",
608
+ name=f"重试请求执行失败 #{attempt}",
609
+ attachment_type=allure.attachment_type.TEXT
610
+ )
611
+ continue
586
612
 
587
613
  # 过滤出仍在重试范围内的断言
588
614
  still_retryable_assertions = []
@@ -657,6 +683,8 @@ def _process_assertions_with_unified_retry(http_req, retry_config):
657
683
  )
658
684
 
659
685
  try:
686
+ # 确保在最终断言之前重新执行一次请求
687
+ http_req.execute(disable_auth=disable_auth)
660
688
  results, _ = http_req.process_asserts()
661
689
  return results
662
690
  except AssertionError as final_err:
pytest_dsl/plugin.py CHANGED
@@ -5,11 +5,12 @@
5
5
  """
6
6
  import pytest
7
7
  import os
8
- from pathlib import Path
9
8
 
10
9
  # 导入模块化组件
11
10
  from pytest_dsl.core.yaml_loader import add_yaml_options, load_yaml_variables
12
- from pytest_dsl.core.plugin_discovery import load_all_plugins, scan_local_keywords
11
+ from pytest_dsl.core.plugin_discovery import (
12
+ load_all_plugins, scan_local_keywords
13
+ )
13
14
  from pytest_dsl.core.global_context import global_context
14
15
 
15
16
 
@@ -39,6 +40,23 @@ def pytest_configure(config):
39
40
 
40
41
  # 加载所有已安装的关键字插件
41
42
  load_all_plugins()
42
-
43
+
43
44
  # 加载本地关键字(向后兼容)
44
- scan_local_keywords()
45
+ scan_local_keywords()
46
+
47
+ # 自动导入项目中的resources目录
48
+ try:
49
+ from pytest_dsl.core.custom_keyword_manager import custom_keyword_manager
50
+
51
+ # 获取pytest的根目录
52
+ project_root = str(config.rootdir) if config.rootdir else os.getcwd()
53
+
54
+ # 检查是否存在resources目录
55
+ resources_dir = os.path.join(project_root, "resources")
56
+ if os.path.exists(resources_dir) and os.path.isdir(resources_dir):
57
+ custom_keyword_manager.auto_import_resources_directory(
58
+ project_root)
59
+ print(f"pytest环境:已自动导入resources目录 {resources_dir}")
60
+
61
+ except Exception as e:
62
+ print(f"pytest环境:自动导入resources目录时出现警告: {str(e)}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytest-dsl
3
- Version: 0.12.0
3
+ Version: 0.13.0
4
4
  Summary: A DSL testing framework based on pytest
5
5
  Author: Chen Shuanglin
6
6
  License: MIT
@@ -1,23 +1,23 @@
1
1
  pytest_dsl/__init__.py,sha256=FzwXGvmuvMhRBKxvCdh1h-yJ2wUOnDxcTbU4Nt5fHn8,301
2
- pytest_dsl/cli.py,sha256=clpvDtQ18tJHl0DUKhoAfCNROE3TB_t59z0fOn5VL9M,33404
2
+ pytest_dsl/cli.py,sha256=kFGOoGQ3dzi5C895QPawnAkif6UmQ4f9zFZmmag0Zgo,34336
3
3
  pytest_dsl/conftest_adapter.py,sha256=cevEb0oEZKTZfUrGe1-CmkFByxKhUtjuurBJP7kpLc0,149
4
4
  pytest_dsl/main_adapter.py,sha256=pUIPN_EzY3JCDlYK7yF_OeLDVqni8vtG15G7gVzPJXg,181
5
- pytest_dsl/plugin.py,sha256=MEQcdK0xdxwxCxPEDLNHX_kGF9Jc7bNxlNi4mx588DU,1190
5
+ pytest_dsl/plugin.py,sha256=Ymepaknms6N5mMoFgtiVi4YYiycE8a_6BPCBONmN-W8,1901
6
6
  pytest_dsl/core/__init__.py,sha256=ersUoxIWSrisxs9GX_STlH4XAbjNxAWUQB0NboaC5zI,322
7
7
  pytest_dsl/core/auth_provider.py,sha256=IZfXXrr4Uuc8QHwRPvhHSzNa2fwrqhjYts1xh78D39Q,14861
8
8
  pytest_dsl/core/auto_decorator.py,sha256=9Mga-GB4AzV5nkB6zpfaq8IuHa0KOH8LlFvnWyH_tnU,6623
9
9
  pytest_dsl/core/auto_directory.py,sha256=egyTnVxtGs4P75EIivRauLRPJfN9aZpoGVvp_Ma72AM,2714
10
10
  pytest_dsl/core/context.py,sha256=fXpVQon666Lz_PCexjkWMBBr-Xcd1SkDMp2vHar6eIs,664
11
- pytest_dsl/core/custom_keyword_manager.py,sha256=UdlGUc_mT8hIwmU7LVf4wJLG-geChwYgvcFM-KtPvJA,7512
12
- pytest_dsl/core/dsl_executor.py,sha256=aEEfocFCFxNDN1puBFhQzL5fzw9eZx8BAyYJI5XSt4Y,30472
11
+ pytest_dsl/core/custom_keyword_manager.py,sha256=vFXRfKXOu7CxoLsLCd6B2TI_JgOrfnE8JN9iShdv_hw,12308
12
+ pytest_dsl/core/dsl_executor.py,sha256=T-8_U3s3KD3HIZ0fWcydftOh9qAwWZDbSNxiT2SBDeA,32039
13
13
  pytest_dsl/core/dsl_executor_utils.py,sha256=cFoR2p3qQ2pb-UhkoefleK-zbuFqf0aBLh2Rlp8Ebs4,2180
14
14
  pytest_dsl/core/global_context.py,sha256=NcEcS2V61MT70tgAsGsFWQq0P3mKjtHQr1rgT3yTcyY,3535
15
15
  pytest_dsl/core/http_client.py,sha256=hdx8gI4JCmq1-96pbiKeyKzSQUzPAi08cRNmljiPQmY,15536
16
- pytest_dsl/core/http_request.py,sha256=nGMlx0mFc7rDLIdp9GJ3e09OQH3ryUA56yJdRZ99dOQ,57445
16
+ pytest_dsl/core/http_request.py,sha256=6e-gTztH3wu2eSW27Nc0uPmyWjB6oBwndx8Vqnu5uyg,60030
17
17
  pytest_dsl/core/keyword_manager.py,sha256=hoNXHQcumnufPRUobnY0mnku4CHxSg2amwPFby4gQEs,7643
18
18
  pytest_dsl/core/lexer.py,sha256=WaLzt9IhtHiA90Fg2WGgfVztveCUhtgxzANBaEiy-F8,4347
19
- pytest_dsl/core/parser.py,sha256=xxy6yC6NdwHxln200aIuaWWN3w44uI8kkNlw8PTVpYI,11855
20
- pytest_dsl/core/parsetab.py,sha256=aN-2RRTr3MSbMyfe-9zOj_t96Xu84avE29GWqH6nqmg,31472
19
+ pytest_dsl/core/parser.py,sha256=pZjbfvab-VLjGJ28AV-69Nrdom_F1L0hwO76TyTyC2s,11947
20
+ pytest_dsl/core/parsetab.py,sha256=o4XbFKwpsi3fYmfI_F6u5NSM61Qp6gTx-Sfh1jDINxI,31767
21
21
  pytest_dsl/core/plugin_discovery.py,sha256=3pt3EXJ7EPF0rkUlyDZMVHkIiTy2vicdIIQJkrHXZjY,8305
22
22
  pytest_dsl/core/utils.py,sha256=q0AMdw5HO33JvlA3UJeQ7IXh1Z_8K1QlwiM1_yiITrU,5350
23
23
  pytest_dsl/core/variable_utils.py,sha256=sx5DFZAO_syi0E_0ACisiZUQL9yxGeOfNmMtV6w9V3E,13947
@@ -39,16 +39,16 @@ pytest_dsl/examples/http/__init__.py,sha256=TCV9NzLmBbPDwNpLQs4_s_LlX9T47ApQ5UAr
39
39
  pytest_dsl/examples/http/builtin_auth_test.auto,sha256=qZYpmxTBW018E5YQ4c8bbnoByEA3Y7BzpPfLJtDwMKQ,2374
40
40
  pytest_dsl/examples/http/file_reference_test.auto,sha256=lHDxuR9NWp-DdASRUt5xNlcOn7FtmLu6oAGDvSsMpeo,3870
41
41
  pytest_dsl/examples/http/http_advanced.auto,sha256=rVEtEY93rYcSrQJ7ntwW-GbHm8wltDobgd-KydIdVLU,2595
42
- pytest_dsl/examples/http/http_example.auto,sha256=y_5g6p3ydUoksovJd-21uAfKzcvvIA7iFJhyxx64rLc,4988
42
+ pytest_dsl/examples/http/http_example.auto,sha256=g66-jQODonQeoVSRdggUIho6FGm5ON6Vqa0nuLDKG1o,4982
43
43
  pytest_dsl/examples/http/http_length_test.auto,sha256=GYlFtSj0Nfk_9aqQrCXvRlwvTJHOk9CIf8X1CV_VKJg,1972
44
- pytest_dsl/examples/http/http_retry_assertions.auto,sha256=zn3a54Mk4tpwi9l7qy3D4UWeci5kZJmQjXOoKuSQIwo,3332
45
- pytest_dsl/examples/http/http_retry_assertions_enhanced.auto,sha256=xIPGujQ1Oll1fi8LW1ZGuyAryu2RjK50_utA8cfKs88,3182
44
+ pytest_dsl/examples/http/http_retry_assertions.auto,sha256=Dke5gkEZ9PTnKAhH86Umoo5DSh8P3RGjZN-gQSmrcBU,3385
45
+ pytest_dsl/examples/http/http_retry_assertions_enhanced.auto,sha256=Y9Lt6KO9z799na-jtZGv6nrskOlM3CXVGPVo82SEmHM,3195
46
46
  pytest_dsl/examples/http/http_with_yaml.auto,sha256=u6Bw4EqQuQAMV-g2xS_iPmZwL4WRTpTqsJhL3xMRyfo,1942
47
- pytest_dsl/examples/http/new_retry_test.auto,sha256=XBTD3NnyVnKr23FVy6xa_5RJq76k8pUR3rFwZe30RRI,664
48
- pytest_dsl/examples/http/retry_assertions_only.auto,sha256=l2MNtJVhJ4vt3jsue1QsoyEAZrNcwyeINmHDfSEOgyk,1867
49
- pytest_dsl/examples/http/retry_config_only.auto,sha256=6zof7HvFdBG6SEZ_ZnHygsuu9hpRpFEj-z1uPwaCSSc,1479
50
- pytest_dsl/examples/http/retry_debug.auto,sha256=wHIGtkCG8p7x4KP1A1nuz6usroU1Pwfep5wkIffgEQo,854
51
- pytest_dsl/examples/http/retry_with_fix.auto,sha256=BU8HeFtY8xor9o9XV_h-yx45_ZP0iAS-Ec12FE_7fNA,649
47
+ pytest_dsl/examples/http/new_retry_test.auto,sha256=8ALnUYsZDI9TryQ2zDUg1JJYy7KGWKNQaECqure_0ck,669
48
+ pytest_dsl/examples/http/retry_assertions_only.auto,sha256=KhLnpGYIGz49VQZuXqcbKucEV4uW0mUWiQKg_MM80Vw,1887
49
+ pytest_dsl/examples/http/retry_config_only.auto,sha256=jGlpOcJS9IkN9OSe3Hs4uIq5EwxCzIg_72q5HFJK8NI,1482
50
+ pytest_dsl/examples/http/retry_debug.auto,sha256=5f32aYYpnNg98sl8-2arooHA4LI4870rkEGu8Z4UlE8,1136
51
+ pytest_dsl/examples/http/retry_with_fix.auto,sha256=GUn4T9oPsOQTsxScBRJD-M_sQkS3k2HDFYShtJNH-9s,693
52
52
  pytest_dsl/examples/http/simple_retry.auto,sha256=Y7S8sR8VRjdk-iVJxcOD0Fb2tt_RO00BmA9eat3L0ks,569
53
53
  pytest_dsl/examples/http/vars.yaml,sha256=GO0x6kpaUYk90TSOxtXh_3RYcacw8-ogBv5nG72Lr9Y,1186
54
54
  pytest_dsl/examples/quickstart/api_basics.auto,sha256=SrDRBASqy5ZMXnmfczuKNCXoTijF54DChpeTrfsDtGQ,1544
@@ -57,7 +57,7 @@ pytest_dsl/examples/quickstart/loops.auto,sha256=ZNZ6qP636v8QMY8QRyTUBB43gWCsqHb
57
57
  pytest_dsl/keywords/__init__.py,sha256=5aiyPU_t1UiB2MEZ6M9ffOKnV1mFT_2YHxnZvyWaBNI,372
58
58
  pytest_dsl/keywords/assertion_keywords.py,sha256=obW06H_3AizsvEM_9VE2JVuwvgrNVqP1kUTDd3U1SMk,23240
59
59
  pytest_dsl/keywords/global_keywords.py,sha256=4yw5yeXoGf_4W26F39EA2Pp-mH9GiKGy2jKgFO9a_wM,2509
60
- pytest_dsl/keywords/http_keywords.py,sha256=z2Brqj1Mkufa_PlZZNwfKuYqkgJhnjsZw-7YNnbt2N4,27302
60
+ pytest_dsl/keywords/http_keywords.py,sha256=baT_p04lOqZpfmOvBdPdzW2_KTikMEJmKPvpEx5sddU,28839
61
61
  pytest_dsl/keywords/system_keywords.py,sha256=hjsACYER87rseSj4thBFnjDqe6At5hBT4Gjifj4ulDE,24470
62
62
  pytest_dsl/remote/__init__.py,sha256=syRSxTlTUfdAPleJnVS4MykRyEN8_SKiqlsn6SlIK8k,120
63
63
  pytest_dsl/remote/hook_manager.py,sha256=0hwRKP8yhcnfAnrrnZGVT-S0TBgo6c0A4qO5XRpvV1U,4899
@@ -65,9 +65,9 @@ pytest_dsl/remote/keyword_client.py,sha256=BL80MOaLroUi0v-9sLtkJ55g1R0Iw9SE1k11I
65
65
  pytest_dsl/remote/keyword_server.py,sha256=vGIE3Bhh461xX_u1U-Cf5nrWL2GQFYdtQdcMWfFIYgE,22320
66
66
  pytest_dsl/remote/variable_bridge.py,sha256=dv-d3Gq9ttvvrXM1fdlLtoSOPB6vRp0_GBOwX4wvcy8,7121
67
67
  pytest_dsl/templates/keywords_report.html,sha256=7x84iq6hi08nf1iQ95jZ3izcAUPx6JFm0_8xS85CYws,31241
68
- pytest_dsl-0.12.0.dist-info/licenses/LICENSE,sha256=Rguy8cb9sYhK6cmrBdXvwh94rKVDh2tVZEWptsHIsVM,1071
69
- pytest_dsl-0.12.0.dist-info/METADATA,sha256=M9J5LQQtA4aCQ3KqCRxjgiDcnZnMc_f_0Yctx91ZpvI,29655
70
- pytest_dsl-0.12.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
71
- pytest_dsl-0.12.0.dist-info/entry_points.txt,sha256=PLOBbH02OGY1XR1JDKIZB1Em87loUvbgMRWaag-5FhY,204
72
- pytest_dsl-0.12.0.dist-info/top_level.txt,sha256=4CrSx4uNqxj7NvK6k1y2JZrSrJSzi-UvPZdqpUhumWM,11
73
- pytest_dsl-0.12.0.dist-info/RECORD,,
68
+ pytest_dsl-0.13.0.dist-info/licenses/LICENSE,sha256=Rguy8cb9sYhK6cmrBdXvwh94rKVDh2tVZEWptsHIsVM,1071
69
+ pytest_dsl-0.13.0.dist-info/METADATA,sha256=Z3ywUBY2yKn3V6BouBNFEcZ1l1D6I-_S2-NLCGBcGeE,29655
70
+ pytest_dsl-0.13.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
71
+ pytest_dsl-0.13.0.dist-info/entry_points.txt,sha256=PLOBbH02OGY1XR1JDKIZB1Em87loUvbgMRWaag-5FhY,204
72
+ pytest_dsl-0.13.0.dist-info/top_level.txt,sha256=4CrSx4uNqxj7NvK6k1y2JZrSrJSzi-UvPZdqpUhumWM,11
73
+ pytest_dsl-0.13.0.dist-info/RECORD,,