pytest-dsl 0.5.0__py3-none-any.whl → 0.7.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.
- pytest_dsl/cli.py +28 -33
- pytest_dsl/core/auto_decorator.py +72 -53
- pytest_dsl/core/auto_directory.py +8 -5
- pytest_dsl/core/dsl_executor.py +91 -23
- pytest_dsl/core/http_request.py +272 -221
- pytest_dsl/core/lexer.py +17 -17
- pytest_dsl/core/parser.py +52 -4
- pytest_dsl/core/parsetab.py +81 -70
- pytest_dsl/core/plugin_discovery.py +1 -8
- pytest_dsl/core/utils.py +43 -23
- pytest_dsl/core/variable_utils.py +215 -70
- pytest_dsl/core/yaml_loader.py +96 -19
- pytest_dsl/examples/assert/assertion_example.auto +1 -1
- pytest_dsl/examples/assert/boolean_test.auto +2 -2
- pytest_dsl/examples/assert/expression_test.auto +1 -1
- pytest_dsl/examples/custom/test_advanced_keywords.auto +2 -2
- pytest_dsl/examples/custom/test_custom_keywords.auto +2 -2
- pytest_dsl/examples/custom/test_default_values.auto +2 -2
- pytest_dsl/examples/http/file_reference_test.auto +1 -1
- pytest_dsl/examples/http/http_advanced.auto +1 -1
- pytest_dsl/examples/http/http_example.auto +1 -1
- pytest_dsl/examples/http/http_length_test.auto +1 -1
- pytest_dsl/examples/http/http_retry_assertions.auto +1 -1
- pytest_dsl/examples/http/http_retry_assertions_enhanced.auto +2 -2
- pytest_dsl/examples/http/http_with_yaml.auto +1 -1
- pytest_dsl/examples/quickstart/api_basics.auto +1 -1
- pytest_dsl/examples/quickstart/assertions.auto +1 -1
- pytest_dsl/examples/quickstart/loops.auto +2 -2
- pytest_dsl/keywords/assertion_keywords.py +76 -62
- pytest_dsl/keywords/global_keywords.py +43 -4
- pytest_dsl/keywords/http_keywords.py +58 -56
- pytest_dsl-0.7.0.dist-info/METADATA +1040 -0
- pytest_dsl-0.7.0.dist-info/RECORD +67 -0
- {pytest_dsl-0.5.0.dist-info → pytest_dsl-0.7.0.dist-info}/WHEEL +1 -1
- pytest_dsl/parsetab.py +0 -69
- pytest_dsl-0.5.0.dist-info/METADATA +0 -596
- pytest_dsl-0.5.0.dist-info/RECORD +0 -68
- {pytest_dsl-0.5.0.dist-info → pytest_dsl-0.7.0.dist-info}/entry_points.txt +0 -0
- {pytest_dsl-0.5.0.dist-info → pytest_dsl-0.7.0.dist-info}/licenses/LICENSE +0 -0
- {pytest_dsl-0.5.0.dist-info → pytest_dsl-0.7.0.dist-info}/top_level.txt +0 -0
@@ -9,6 +9,7 @@ import yaml
|
|
9
9
|
import json
|
10
10
|
import os
|
11
11
|
import time
|
12
|
+
import logging
|
12
13
|
from typing import Dict, Any, Union
|
13
14
|
|
14
15
|
from pytest_dsl.core.keyword_manager import keyword_manager
|
@@ -16,6 +17,9 @@ from pytest_dsl.core.http_request import HTTPRequest
|
|
16
17
|
from pytest_dsl.core.yaml_vars import yaml_vars
|
17
18
|
from pytest_dsl.core.context import TestContext
|
18
19
|
|
20
|
+
# 配置日志
|
21
|
+
logger = logging.getLogger(__name__)
|
22
|
+
|
19
23
|
def _process_file_reference(reference: Union[str, Dict[str, Any]], allow_vars: bool = True, test_context: TestContext = None) -> Any:
|
20
24
|
"""处理文件引用,加载外部文件内容
|
21
25
|
|
@@ -223,8 +227,7 @@ def _normalize_retry_config(config, assert_retry_count=None, assert_retry_interv
|
|
223
227
|
{'name': '配置', 'mapping': 'config', 'description': '包含请求、捕获和断言的YAML配置'},
|
224
228
|
{'name': '会话', 'mapping': 'session', 'description': '会话名称,用于在多个请求间保持会话状态'},
|
225
229
|
{'name': '保存响应', 'mapping': 'save_response', 'description': '将完整响应保存到指定变量名中'},
|
226
|
-
{'name': '
|
227
|
-
{'name': '重试间隔', 'mapping': 'retry_interval', 'description': '重试间隔时间(秒)'},
|
230
|
+
{'name': '禁用授权', 'mapping': 'disable_auth', 'description': '禁用客户端配置中的授权机制,默认为false'},
|
228
231
|
{'name': '模板', 'mapping': 'template', 'description': '使用YAML变量文件中定义的请求模板'},
|
229
232
|
{'name': '断言重试次数', 'mapping': 'assert_retry_count', 'description': '断言失败时的重试次数'},
|
230
233
|
{'name': '断言重试间隔', 'mapping': 'assert_retry_interval', 'description': '断言重试间隔时间(秒)'}
|
@@ -240,8 +243,7 @@ def http_request(context, **kwargs):
|
|
240
243
|
config: YAML配置
|
241
244
|
session: 会话名称
|
242
245
|
save_response: 保存响应的变量名
|
243
|
-
|
244
|
-
retry_interval: 重试间隔
|
246
|
+
disable_auth: 禁用客户端配置中的授权机制
|
245
247
|
template: 模板名称
|
246
248
|
assert_retry_count: 断言失败时的重试次数
|
247
249
|
assert_retry_interval: 断言重试间隔时间(秒)
|
@@ -253,8 +255,7 @@ def http_request(context, **kwargs):
|
|
253
255
|
config = kwargs.get('config', '{}')
|
254
256
|
session_name = kwargs.get('session')
|
255
257
|
save_response = kwargs.get('save_response')
|
256
|
-
|
257
|
-
retry_interval = kwargs.get('retry_interval')
|
258
|
+
disable_auth = kwargs.get('disable_auth', False)
|
258
259
|
template_name = kwargs.get('template')
|
259
260
|
assert_retry_count = kwargs.get('assert_retry_count')
|
260
261
|
assert_retry_interval = kwargs.get('assert_retry_interval')
|
@@ -316,7 +317,7 @@ def http_request(context, **kwargs):
|
|
316
317
|
http_req = HTTPRequest(config, client_name, session_name)
|
317
318
|
|
318
319
|
# 执行请求
|
319
|
-
response = http_req.execute()
|
320
|
+
response = http_req.execute(disable_auth=disable_auth)
|
320
321
|
|
321
322
|
# 处理捕获
|
322
323
|
captured_values = http_req.captured_values
|
@@ -338,8 +339,50 @@ def http_request(context, **kwargs):
|
|
338
339
|
# 不需要重试,直接断言
|
339
340
|
http_req.process_asserts()
|
340
341
|
|
341
|
-
#
|
342
|
-
|
342
|
+
# 获取会话状态(如果使用了会话)
|
343
|
+
session_state = None
|
344
|
+
if session_name:
|
345
|
+
try:
|
346
|
+
from pytest_dsl.core.http_client import http_client_manager
|
347
|
+
session_client = http_client_manager.get_session(session_name, client_name)
|
348
|
+
if session_client and session_client._session:
|
349
|
+
session_state = {
|
350
|
+
"cookies": dict(session_client._session.cookies),
|
351
|
+
"headers": dict(session_client._session.headers)
|
352
|
+
}
|
353
|
+
except Exception as e:
|
354
|
+
# 会话状态获取失败不影响主要功能
|
355
|
+
logger.warning(f"获取会话状态失败: {str(e)}")
|
356
|
+
|
357
|
+
# 准备响应数据(如果需要保存响应)
|
358
|
+
response_data = None
|
359
|
+
if save_response:
|
360
|
+
# 确保响应数据是可序列化的
|
361
|
+
try:
|
362
|
+
import json
|
363
|
+
json.dumps(response.__dict__)
|
364
|
+
response_data = response.__dict__
|
365
|
+
except (TypeError, AttributeError):
|
366
|
+
# 如果无法序列化,转换为基本信息
|
367
|
+
response_data = {
|
368
|
+
"status_code": getattr(response, 'status_code', None),
|
369
|
+
"headers": dict(getattr(response, 'headers', {})),
|
370
|
+
"text": getattr(response, 'text', ''),
|
371
|
+
"url": getattr(response, 'url', '')
|
372
|
+
}
|
373
|
+
|
374
|
+
# 统一返回格式 - 支持远程关键字模式
|
375
|
+
return {
|
376
|
+
"result": captured_values, # 主要返回值保持兼容
|
377
|
+
"captures": captured_values, # 明确的捕获变量
|
378
|
+
"session_state": {session_name: session_state} if session_state else {},
|
379
|
+
"response": response_data, # 完整响应(如果需要)
|
380
|
+
"metadata": {
|
381
|
+
"response_time": getattr(response, 'elapsed', None),
|
382
|
+
"status_code": getattr(response, 'status_code', None),
|
383
|
+
"url": getattr(response, 'url', '')
|
384
|
+
}
|
385
|
+
}
|
343
386
|
|
344
387
|
|
345
388
|
def _deep_merge(dict1, dict2):
|
@@ -512,8 +555,11 @@ def _process_assertions_with_unified_retry(http_req, retry_config):
|
|
512
555
|
retry_assertion_indexes = [a['index'] for a in still_retryable_assertions]
|
513
556
|
retry_assertions = [http_req.config.get('asserts', [])[idx] for idx in retry_assertion_indexes]
|
514
557
|
|
515
|
-
#
|
516
|
-
|
558
|
+
# 创建索引映射:新索引 -> 原始索引
|
559
|
+
index_mapping = {new_idx: orig_idx for new_idx, orig_idx in enumerate(retry_assertion_indexes)}
|
560
|
+
|
561
|
+
# 只处理需要重试的断言,传递索引映射
|
562
|
+
results, new_failed_assertions = http_req.process_asserts(specific_asserts=retry_assertions, index_mapping=index_mapping)
|
517
563
|
|
518
564
|
# 如果所有断言都通过了,检查全部断言
|
519
565
|
if not new_failed_assertions:
|
@@ -571,48 +617,4 @@ def _process_assertions_with_unified_retry(http_req, retry_config):
|
|
571
617
|
raise AssertionError(enhanced_error) from final_err
|
572
618
|
|
573
619
|
|
574
|
-
#
|
575
|
-
# 以下函数保留用于向后兼容,但内部逻辑已更改为调用统一重试函数
|
576
|
-
def _process_assertions_with_retry(http_req, retry_count, retry_interval):
|
577
|
-
"""处理断言并支持重试(向后兼容函数)
|
578
|
-
|
579
|
-
Args:
|
580
|
-
http_req: HTTP请求对象
|
581
|
-
retry_count: 重试次数
|
582
|
-
retry_interval: 重试间隔(秒)
|
583
|
-
"""
|
584
|
-
# 创建统一的重试配置
|
585
|
-
retry_config = {
|
586
|
-
'enabled': True,
|
587
|
-
'count': retry_count,
|
588
|
-
'interval': retry_interval,
|
589
|
-
'all': True,
|
590
|
-
'indices': [],
|
591
|
-
'specific': {}
|
592
|
-
}
|
593
|
-
|
594
|
-
# 使用统一的重试处理函数
|
595
|
-
return _process_assertions_with_unified_retry(http_req, retry_config)
|
596
|
-
|
597
|
-
|
598
|
-
def _process_config_based_assertions_with_retry(http_req):
|
599
|
-
"""基于配置处理断言重试(向后兼容函数)
|
600
|
-
|
601
|
-
Args:
|
602
|
-
http_req: HTTP请求对象
|
603
|
-
"""
|
604
|
-
# 从配置中获取重试信息
|
605
|
-
retry_assertions_config = http_req.config.get('retry_assertions', {})
|
606
|
-
|
607
|
-
# 创建统一的重试配置
|
608
|
-
retry_config = {
|
609
|
-
'enabled': True,
|
610
|
-
'count': retry_assertions_config.get('count', 3),
|
611
|
-
'interval': retry_assertions_config.get('interval', 1.0),
|
612
|
-
'all': retry_assertions_config.get('all', False),
|
613
|
-
'indices': retry_assertions_config.get('indices', []),
|
614
|
-
'specific': retry_assertions_config.get('specific', {})
|
615
|
-
}
|
616
|
-
|
617
|
-
# 使用统一的重试处理函数
|
618
|
-
return _process_assertions_with_unified_retry(http_req, retry_config)
|
620
|
+
# 注意:旧的重试函数已被移除,现在使用统一的重试机制
|