pytest-dsl 0.1.0__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 (74) hide show
  1. pytest_dsl-0.1.0/LICENSE +21 -0
  2. pytest_dsl-0.1.0/MANIFEST.in +15 -0
  3. pytest_dsl-0.1.0/PKG-INFO +537 -0
  4. pytest_dsl-0.1.0/README.md +507 -0
  5. pytest_dsl-0.1.0/pyproject.toml +45 -0
  6. pytest_dsl-0.1.0/pytest_dsl/__init__.py +10 -0
  7. pytest_dsl-0.1.0/pytest_dsl/cli.py +44 -0
  8. pytest_dsl-0.1.0/pytest_dsl/conftest_adapter.py +4 -0
  9. pytest_dsl-0.1.0/pytest_dsl/core/__init__.py +0 -0
  10. pytest_dsl-0.1.0/pytest_dsl/core/auth_provider.py +409 -0
  11. pytest_dsl-0.1.0/pytest_dsl/core/auto_decorator.py +181 -0
  12. pytest_dsl-0.1.0/pytest_dsl/core/auto_directory.py +81 -0
  13. pytest_dsl-0.1.0/pytest_dsl/core/context.py +23 -0
  14. pytest_dsl-0.1.0/pytest_dsl/core/custom_auth_example.py +425 -0
  15. pytest_dsl-0.1.0/pytest_dsl/core/dsl_executor.py +329 -0
  16. pytest_dsl-0.1.0/pytest_dsl/core/dsl_executor_utils.py +84 -0
  17. pytest_dsl-0.1.0/pytest_dsl/core/global_context.py +103 -0
  18. pytest_dsl-0.1.0/pytest_dsl/core/http_client.py +411 -0
  19. pytest_dsl-0.1.0/pytest_dsl/core/http_request.py +810 -0
  20. pytest_dsl-0.1.0/pytest_dsl/core/keyword_manager.py +109 -0
  21. pytest_dsl-0.1.0/pytest_dsl/core/lexer.py +139 -0
  22. pytest_dsl-0.1.0/pytest_dsl/core/parser.py +197 -0
  23. pytest_dsl-0.1.0/pytest_dsl/core/parsetab.py +76 -0
  24. pytest_dsl-0.1.0/pytest_dsl/core/plugin_discovery.py +187 -0
  25. pytest_dsl-0.1.0/pytest_dsl/core/utils.py +146 -0
  26. pytest_dsl-0.1.0/pytest_dsl/core/variable_utils.py +267 -0
  27. pytest_dsl-0.1.0/pytest_dsl/core/yaml_loader.py +62 -0
  28. pytest_dsl-0.1.0/pytest_dsl/core/yaml_vars.py +75 -0
  29. pytest_dsl-0.1.0/pytest_dsl/docs/custom_keywords.md +140 -0
  30. pytest_dsl-0.1.0/pytest_dsl/examples/__init__.py +5 -0
  31. pytest_dsl-0.1.0/pytest_dsl/examples/assert/assertion_example.auto +44 -0
  32. pytest_dsl-0.1.0/pytest_dsl/examples/assert/boolean_test.auto +34 -0
  33. pytest_dsl-0.1.0/pytest_dsl/examples/assert/expression_test.auto +49 -0
  34. pytest_dsl-0.1.0/pytest_dsl/examples/http/__init__.py +3 -0
  35. pytest_dsl-0.1.0/pytest_dsl/examples/http/builtin_auth_test.auto +79 -0
  36. pytest_dsl-0.1.0/pytest_dsl/examples/http/csrf_auth_test.auto +64 -0
  37. pytest_dsl-0.1.0/pytest_dsl/examples/http/custom_auth_test.auto +76 -0
  38. pytest_dsl-0.1.0/pytest_dsl/examples/http/file_reference_test.auto +111 -0
  39. pytest_dsl-0.1.0/pytest_dsl/examples/http/http_advanced.auto +91 -0
  40. pytest_dsl-0.1.0/pytest_dsl/examples/http/http_example.auto +147 -0
  41. pytest_dsl-0.1.0/pytest_dsl/examples/http/http_length_test.auto +55 -0
  42. pytest_dsl-0.1.0/pytest_dsl/examples/http/http_retry_assertions.auto +91 -0
  43. pytest_dsl-0.1.0/pytest_dsl/examples/http/http_retry_assertions_enhanced.auto +94 -0
  44. pytest_dsl-0.1.0/pytest_dsl/examples/http/http_with_yaml.auto +58 -0
  45. pytest_dsl-0.1.0/pytest_dsl/examples/http/new_retry_test.auto +22 -0
  46. pytest_dsl-0.1.0/pytest_dsl/examples/http/retry_assertions_only.auto +52 -0
  47. pytest_dsl-0.1.0/pytest_dsl/examples/http/retry_config_only.auto +49 -0
  48. pytest_dsl-0.1.0/pytest_dsl/examples/http/retry_debug.auto +22 -0
  49. pytest_dsl-0.1.0/pytest_dsl/examples/http/retry_with_fix.auto +21 -0
  50. pytest_dsl-0.1.0/pytest_dsl/examples/http/simple_retry.auto +20 -0
  51. pytest_dsl-0.1.0/pytest_dsl/examples/http/vars.yaml +55 -0
  52. pytest_dsl-0.1.0/pytest_dsl/examples/http_clients.yaml +48 -0
  53. pytest_dsl-0.1.0/pytest_dsl/examples/keyword_example.py +70 -0
  54. pytest_dsl-0.1.0/pytest_dsl/examples/test_assert.py +16 -0
  55. pytest_dsl-0.1.0/pytest_dsl/examples/test_http.py +168 -0
  56. pytest_dsl-0.1.0/pytest_dsl/keywords/__init__.py +10 -0
  57. pytest_dsl-0.1.0/pytest_dsl/keywords/assertion_keywords.py +610 -0
  58. pytest_dsl-0.1.0/pytest_dsl/keywords/global_keywords.py +51 -0
  59. pytest_dsl-0.1.0/pytest_dsl/keywords/http_keywords.py +430 -0
  60. pytest_dsl-0.1.0/pytest_dsl/keywords/system_keywords.py +17 -0
  61. pytest_dsl-0.1.0/pytest_dsl/main_adapter.py +7 -0
  62. pytest_dsl-0.1.0/pytest_dsl/plugin.py +44 -0
  63. pytest_dsl-0.1.0/pytest_dsl.egg-info/PKG-INFO +537 -0
  64. pytest_dsl-0.1.0/pytest_dsl.egg-info/SOURCES.txt +72 -0
  65. pytest_dsl-0.1.0/pytest_dsl.egg-info/dependency_links.txt +1 -0
  66. pytest_dsl-0.1.0/pytest_dsl.egg-info/entry_points.txt +5 -0
  67. pytest_dsl-0.1.0/pytest_dsl.egg-info/requires.txt +9 -0
  68. pytest_dsl-0.1.0/pytest_dsl.egg-info/top_level.txt +1 -0
  69. pytest_dsl-0.1.0/setup.cfg +4 -0
  70. pytest_dsl-0.1.0/setup.py +7 -0
  71. pytest_dsl-0.1.0/tests/conftest.py +23 -0
  72. pytest_dsl-0.1.0/tests/test_advanced_list.auto +24 -0
  73. pytest_dsl-0.1.0/tests/test_core/test_dsl.py +30 -0
  74. pytest_dsl-0.1.0/tests/test_list_support.auto +20 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Chen Shuanglin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,15 @@
1
+ include LICENSE
2
+ include README.md
3
+ include pyproject.toml
4
+ include MANIFEST.in
5
+
6
+ recursive-include pytest_dsl/examples *.auto *.csv *.yaml *.yml
7
+ recursive-include pytest_dsl/docs *.md *.rst *.txt *.png *.jpg
8
+ recursive-include tests *.py *.auto *.csv *.yaml *.yml
9
+
10
+ prune .venv
11
+ prune .pytest_cache
12
+ prune .vscode
13
+ prune allure-results
14
+ prune __pycache__
15
+ prune */*/pycache__
@@ -0,0 +1,537 @@
1
+ Metadata-Version: 2.4
2
+ Name: pytest-dsl
3
+ Version: 0.1.0
4
+ Summary: A DSL testing framework based on pytest
5
+ Author: Chen Shuanglin
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/felix-1991/pytest-dsl
8
+ Project-URL: Bug Tracker, https://github.com/felix-1991/pytest-dsl/issues
9
+ Classifier: Framework :: Pytest
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.8
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: pytest>=7.0.0
21
+ Requires-Dist: allure-pytest>=2.9.0
22
+ Requires-Dist: ply>=3.11
23
+ Requires-Dist: filelock>=3.17.0
24
+ Requires-Dist: PyYAML==6.0.2
25
+ Requires-Dist: jsonpath-ng>=1.5.0
26
+ Requires-Dist: requests>=2.28.0
27
+ Requires-Dist: lxml>=4.9.0
28
+ Requires-Dist: jsonschema>=4.17.0
29
+ Dynamic: license-file
30
+
31
+ # pytest-dsl
32
+
33
+ pytest-dsl是一个基于pytest的测试框架,它使用自定义的领域特定语言(DSL)来编写测试用例,使测试更加直观、易读和易维护。
34
+
35
+ ## 特性
36
+
37
+ - 使用简洁直观的DSL语法编写测试用例
38
+ - 支持中文关键字和参数,提高可读性
39
+ - 自动集成到pytest测试框架
40
+ - 支持测试用例元数据管理(名称、描述、标签等)
41
+ - 支持变量、循环等基本编程结构
42
+ - 支持YAML格式的外部变量文件
43
+ - 支持数据驱动测试(CSV格式)
44
+ - 支持setup和teardown机制
45
+ - 支持并行测试执行(pytest-xdist)
46
+ - 集成Allure报告
47
+ - 支持配置式HTTP断言重试(支持全局和断言级别重试策略)
48
+
49
+ ## 包安装与使用
50
+
51
+ ### 安装
52
+
53
+ pytest-dsl 现在已经采用标准的 Python 包结构,支持使用 pip 或 uv 进行安装:
54
+
55
+ ```bash
56
+ # 使用 uv 安装(推荐)
57
+ uv pip install pytest-dsl
58
+
59
+ # 或使用传统的 pip 安装
60
+ pip install pytest-dsl
61
+ ```
62
+
63
+ 开发模式安装:
64
+
65
+ ```bash
66
+ # 克隆仓库
67
+ git clone https://github.com/yourusername/pytest-dsl.git
68
+ cd pytest-dsl
69
+
70
+ # 使用 uv 安装(推荐)
71
+ uv pip install -e .
72
+
73
+ # 或使用传统的 pip 安装
74
+ pip install -e .
75
+ ```
76
+
77
+ ### 命令行工具
78
+
79
+ 安装后可以直接使用命令行工具执行 DSL 文件:
80
+
81
+ ```bash
82
+ pytest-dsl your_test_file.auto
83
+ ```
84
+
85
+ ### 配置虚拟环境
86
+
87
+ 如果你是项目贡献者,可以使用提供的脚本快速设置开发环境:
88
+
89
+ ```bash
90
+ bash setup_env.sh
91
+ ```
92
+
93
+ ## 项目结构
94
+
95
+ ```
96
+ pytest-dsl/
97
+ ├── pytest_dsl/ # 主包目录
98
+ │ ├── core/ # 核心模块(解析器、执行器等)
99
+ │ ├── keywords/ # 关键字定义模块
100
+ │ ├── examples/ # 示例代码
101
+ │ ├── docs/ # 文档
102
+ │ ├── __init__.py # 包初始化文件
103
+ │ ├── plugin.py # pytest 插件入口
104
+ │ └── cli.py # 命令行工具入口
105
+ ├── tests/ # 测试目录
106
+ │ ├── test_core/ # 核心模块测试
107
+ │ └── test_keywords/ # 关键字模块测试
108
+ ├── pyproject.toml # 项目元数据和构建配置
109
+ ├── setup.py # 兼容旧版安装工具
110
+ ├── MANIFEST.in # 包含非Python文件的配置
111
+ └── README.md # 项目说明文档
112
+ ```
113
+
114
+ ## 自定义关键字
115
+
116
+ 除了使用内置关键字外,pytest-dsl还支持以下方式创建和使用自定义关键字:
117
+
118
+ 1. **项目本地关键字**:在项目根目录下创建`keywords`目录,添加自定义关键字模块
119
+ 2. **插件式关键字**:通过Python的entry_points机制注册的第三方插件
120
+
121
+ ### 项目本地关键字(推荐)
122
+
123
+ 当您将pytest-dsl用于自己的项目时,只需在项目根目录创建一个`keywords`目录,添加您的关键字模块即可:
124
+
125
+ ```
126
+ 您的项目/
127
+ ├── keywords/ # 自定义关键字目录
128
+ │ ├── __init__.py # 可选
129
+ │ ├── web_keywords.py # Web测试关键字
130
+ │ └── db_keywords.py # 数据库测试关键字
131
+ ├── tests/ # 测试目录
132
+ │ └── test_cases.auto # DSL测试用例
133
+ └── pytest.ini # pytest配置
134
+ ```
135
+
136
+ pytest-dsl会自动发现并加载您项目中的关键字,无需额外配置。
137
+
138
+ ### 关键字编写示例
139
+
140
+ 关键字模块中使用`keyword_manager.register`装饰器来注册自定义关键字:
141
+
142
+ ```python
143
+ # keywords/db_keywords.py
144
+ from pytest_dsl.core.keyword_manager import keyword_manager
145
+
146
+ @keyword_manager.register('数据库查询', [
147
+ {'name': 'SQL', 'mapping': 'sql', 'description': 'SQL查询语句'},
148
+ {'name': '数据库', 'mapping': 'db', 'description': '数据库连接名称'}
149
+ ])
150
+ def query_database(**kwargs):
151
+ """执行数据库查询
152
+
153
+ Args:
154
+ sql: SQL查询语句
155
+ db: 数据库连接名称
156
+ context: 测试上下文(自动传入)
157
+ """
158
+ sql = kwargs.get('sql')
159
+ db = kwargs.get('db', 'default')
160
+ context = kwargs.get('context')
161
+
162
+ # 实现数据库查询逻辑
163
+ # ...
164
+
165
+ return result
166
+ ```
167
+
168
+ 详细文档请参阅 [自定义关键字指南](./pytest_dsl/docs/custom_keywords.md)。
169
+
170
+ ## DSL语法
171
+
172
+ ### 基本结构
173
+
174
+ 测试用例使用`.auto`文件编写,基本结构如下:
175
+
176
+ ```
177
+ @name: 测试用例名称
178
+ @description: 测试用例描述
179
+ @tags: [标签1, 标签2]
180
+ @author: 作者
181
+ @date: 创建日期
182
+
183
+ # 测试步骤
184
+ [关键字],参数1:值1,参数2:值2
185
+
186
+ @teardown do
187
+ # 清理操作
188
+ end
189
+ ```
190
+
191
+ ### 元信息
192
+
193
+ 元信息部分用于描述测试用例的基本信息:
194
+
195
+ ```
196
+ @name: 登录功能测试
197
+ @description: 验证用户登录功能
198
+ @tags: [BVT, 自动化]
199
+ @author: Felix
200
+ @date: 2023-01-01
201
+ ```
202
+
203
+ ### 变量管理
204
+
205
+ #### DSL内变量声明与使用
206
+
207
+ ```
208
+ # 变量赋值
209
+ number = 5
210
+
211
+ # 变量引用
212
+ [打印],内容:${number}
213
+ ```
214
+
215
+ #### YAML变量文件
216
+
217
+ 您可以使用YAML文件来管理测试变量,支持多文件和目录方式加载。YAML变量优先级高于DSL中定义的变量。
218
+
219
+ ##### YAML文件格式
220
+
221
+ ```yaml
222
+ # vars.yaml
223
+ test_data:
224
+ username: "testuser"
225
+ password: "password123"
226
+
227
+ api_config:
228
+ base_url: "https://api.example.com"
229
+ timeout: 30
230
+
231
+ environment: "staging"
232
+ ```
233
+
234
+ ##### 使用YAML变量
235
+
236
+ 在DSL文件中可以直接引用YAML文件中定义的变量:
237
+
238
+ ```
239
+ # test.auto
240
+ [API接口调用],
241
+ URL:'${api_config.base_url}/login',
242
+ 请求参数:'{"username":"${test_data.username}","password":"${test_data.password}"}'
243
+ ```
244
+
245
+ ##### 加载YAML变量文件
246
+
247
+ 可以通过命令行参数指定YAML变量文件:
248
+
249
+ ```bash
250
+ # 加载单个变量文件
251
+ pytest --yaml-vars vars.yaml
252
+
253
+ # 加载多个变量文件(后加载的文件会覆盖先加载文件中的同名变量)
254
+ pytest --yaml-vars common_vars.yaml --yaml-vars env_vars.yaml
255
+
256
+ # 加载目录中的所有YAML文件
257
+ pytest --yaml-vars-dir ./test_vars
258
+
259
+ # 同时使用文件和目录
260
+ pytest --yaml-vars-dir ./common_vars --yaml-vars specific_vars.yaml
261
+ ```
262
+
263
+ ### 循环结构
264
+
265
+ ```
266
+ for i in range(1, 5) do
267
+ [打印],内容:'第${i}次循环'
268
+ end
269
+ ```
270
+
271
+ ### 关键字调用
272
+
273
+ ```
274
+ # 基本格式:[关键字],参数名1:值1,参数名2:值2
275
+ [打印],输出:'Hello World'
276
+ [API接口调用],方法:GET,URL:'https://api.example.com',请求头:'{"Content-Type":"application/json"}'
277
+
278
+ # 使用自定义步骤名称
279
+ [HTTP请求],客户端:'default',配置:'...',步骤名称:'获取用户信息'
280
+ [HTTP请求],客户端:'default',配置:'...',步骤名称:'创建新文章'
281
+ ```
282
+
283
+ ### 自定义步骤名称
284
+
285
+ 在 DSL 中,每个关键字调用都可以通过 `步骤名称` 参数来自定义在测试报告中显示的步骤名称。这对于提高测试报告的可读性和维护性非常有帮助。
286
+
287
+ #### 使用场景
288
+
289
+ 1. 为 HTTP 请求添加有意义的步骤名称:
290
+ ```
291
+ [HTTP请求],客户端:'default',配置:'''
292
+ method: GET
293
+ url: https://api.example.com/users/1
294
+ ''',步骤名称:'获取用户详细信息'
295
+ ```
296
+
297
+ 2. 为断言添加描述性名称:
298
+ ```
299
+ [HTTP请求],客户端:'default',配置:'''
300
+ method: GET
301
+ url: https://api.example.com/posts
302
+ asserts:
303
+ - ["status", "eq", 200]
304
+ - ["jsonpath", "$.length()", "gt", 0]
305
+ ''',步骤名称:'验证文章列表API'
306
+ ```
307
+
308
+ 3. 为复杂操作添加清晰的步骤说明:
309
+ ```
310
+ [HTTP请求],客户端:'default',配置:'''
311
+ method: POST
312
+ url: https://api.example.com/tasks
313
+ request:
314
+ json:
315
+ type: "data_analysis"
316
+ dataset: "sample123"
317
+ ''',步骤名称:'创建数据分析任务'
318
+ ```
319
+
320
+ 自定义步骤名称会显示在 Allure 测试报告中,使测试步骤更加清晰易懂。如果不指定步骤名称,将使用默认的关键字名称作为步骤名称。
321
+
322
+ ### 清理操作
323
+
324
+ ```
325
+ @teardown do
326
+ [打印],内容:'测试结束,开始清理'
327
+ [删除文件],路径:'/tmp/test.txt'
328
+ end
329
+ ```
330
+
331
+ ### 数据驱动测试
332
+
333
+ DSL支持使用CSV文件进行数据驱动测试。在测试用例中使用`@data`标记指定数据源:
334
+
335
+ ```
336
+ @name: 用户注册测试
337
+ @description: 验证不同用户数据的注册功能
338
+ @tags: [数据驱动, 自动化]
339
+ @author: Felix
340
+ @date: 2024-03-05
341
+ @data: 'test_data/register_users.csv' using csv
342
+
343
+ # 使用CSV中的数据进行注册
344
+ [API接口调用],
345
+ 方法:POST,
346
+ URL:'https://example.com/register',
347
+ 请求头:'{"Content-Type":"application/json"}',
348
+ 请求参数:'{"username":"${username}","email":"${email}","password":"${password}"}'
349
+
350
+ # 验证注册结果
351
+ result = [获取响应状态码]
352
+ [断言],条件:'${result} == 200',消息:'注册失败'
353
+
354
+ @teardown do
355
+ [打印],内容:'清理用户数据'
356
+ end
357
+ ```
358
+
359
+ #### CSV文件格式
360
+
361
+ 数据文件 `test_data/register_users.csv` 的内容示例:
362
+
363
+ ```csv
364
+ username,email,password
365
+ user1,user1@example.com,pass123
366
+ user2,user2@example.com,pass456
367
+ user3,user3@example.com,pass789
368
+ ```
369
+
370
+ 测试框架会自动读取CSV文件,并为每组数据执行一次测试用例。CSV文件的列名会自动映射为测试用例中可用的变量。
371
+
372
+ ## 目录结构
373
+
374
+ 测试目录可以包含以下特殊文件:
375
+
376
+ - `setup.auto`: 目录级别的setup,在该目录下所有测试执行前运行一次
377
+ - `teardown.auto`: 目录级别的teardown,在该目录下所有测试执行后运行一次
378
+ - `*.auto`: 普通测试文件,每个文件会被转换为一个测试用例
379
+
380
+ ## 使用方法
381
+
382
+ ### 运行测试
383
+
384
+ ```bash
385
+ # 运行所有测试
386
+ pytest
387
+
388
+ # 运行特定目录下的测试
389
+ pytest tests/login/
390
+
391
+ ```
392
+
393
+ ### 示例
394
+
395
+ 以下是一个完整的测试用例示例:
396
+
397
+ ```
398
+ @name: 断言关键字示例
399
+ @description: 演示不同断言关键字的使用方法
400
+ @tags: [断言, JSON, 示例]
401
+ @author: Felix
402
+ @date: 2024-01-01
403
+
404
+ # 基本断言示例
405
+ [断言],条件:'1 + 1 == 2',消息:'基本算术断言失败'
406
+
407
+ # 字符串断言
408
+ str_value = "Hello, World!"
409
+ [断言],条件:'${str_value} contains "Hello"',消息:'字符串包含断言失败'
410
+
411
+ # 数字比较
412
+ num1 = 10
413
+ num2 = 5
414
+ [数据比较],实际值:${num1},预期值:${num2},操作符:'>',消息:'数字比较断言失败'
415
+
416
+ # 类型断言
417
+ [类型断言],值:${str_value},类型:'string',消息:'类型断言失败'
418
+ [类型断言],值:${num1},类型:'number',消息:'类型断言失败'
419
+
420
+ # JSON数据处理
421
+ json_data = '{"user": {"name": "张三", "age": 30, "roles": ["admin", "user"], "address": {"city": "北京", "country": "中国"}}}'
422
+
423
+ # JSON提取示例
424
+ username = [JSON提取],JSON数据:${json_data},JSONPath:'$.user.name',变量名:'username'
425
+ [断言],条件:'${username} == "张三"',消息:'JSON提取断言失败'
426
+
427
+ # JSON断言示例
428
+ [JSON断言],JSON数据:${json_data},JSONPath:'$.user.age',预期值:30,操作符:'==',消息:'JSON断言失败:年龄不匹配'
429
+
430
+ [JSON断言],JSON数据:${json_data},JSONPath:'$.user.roles[0]',预期值:'admin',消息:'JSON断言失败:角色不匹配'
431
+
432
+ # 复杂JSON断言
433
+ [JSON断言],JSON数据:${json_data},JSONPath:'$.user.address.city',预期值:'北京',消息:'JSON断言失败:城市不匹配'
434
+
435
+ # 布尔值断言
436
+ bool_value = True
437
+ [断言],条件:'${bool_value} == True',消息:'布尔值断言失败'
438
+
439
+ @teardown do
440
+ [打印],内容:'所有断言测试通过!'
441
+ end
442
+ ```
443
+
444
+ ## 扩展关键字
445
+
446
+ 您可以通过在`keywords`目录下添加新的Python模块来扩展关键字库。每个关键字需要使用`@keyword`装饰器注册。
447
+
448
+
449
+ ## 测试上下文(Context)
450
+
451
+ 测试上下文是一个在测试用例生命周期内共享的对象,用于在关键字之间传递和共享数据。每个测试用例都有自己独立的上下文,并在测试结束时自动清理。
452
+
453
+ ### 上下文的生命周期
454
+
455
+ - 创建:每个测试用例开始执行时创建新的上下文
456
+ - 共享:测试用例中的所有关键字都可以访问同一个上下文
457
+ - 清理:测试用例结束时(包括teardown之后)自动清理
458
+
459
+ ### 在关键字中使用上下文
460
+
461
+ 每个关键字都会自动接收到 `context` 参数,可以通过以下方法操作上下文:
462
+
463
+ ```python
464
+ def my_keyword(context, **kwargs):
465
+ # 存储数据到上下文
466
+ context.set('key', value)
467
+
468
+ # 从上下文获取数据
469
+ value = context.get('key')
470
+
471
+ # 检查键是否存在
472
+ if context.has('key'):
473
+ # 处理逻辑
474
+ pass
475
+ ```
476
+
477
+ ### 注意事项
478
+
479
+ 1. 上下文对象在测试用例之间是相互隔离的
480
+ 2. teardown 执行后上下文会被自动清理
481
+ 3. 建议在 teardown 中主动清理重要资源
482
+ 4. 上下文中的数据仅在当前测试用例中有效
483
+
484
+
485
+
486
+ ## 贡献
487
+
488
+ 欢迎提交问题和功能请求!
489
+
490
+ ### 开发流程
491
+
492
+ 1. Fork 存储库
493
+ 2. 创建功能分支 (`git checkout -b feature/amazing-feature`)
494
+ 3. 提交更改 (`git commit -m 'Add some amazing feature'`)
495
+ 4. 推送到分支 (`git push origin feature/amazing-feature`)
496
+ 5. 打开 Pull Request
497
+
498
+ ### 编码规范
499
+
500
+ - 使用 [black](https://github.com/psf/black) 进行代码格式化
501
+ - 使用 [isort](https://github.com/PyCQA/isort) 对导入语句排序
502
+ - 编写适当的测试用例
503
+
504
+ ### 断言重试功能
505
+
506
+ pytest-dsl支持强大的HTTP断言重试功能,特别适用于测试异步API或状态变化的场景。现在提供了更清晰的配置方式:
507
+
508
+ 1. 使用独立的`retry_assertions`配置块(推荐)
509
+ 2. 为特定断言设置独立的重试策略
510
+ 3. 混合使用全局和断言级别的重试配置
511
+
512
+ #### 示例:独立的断言重试配置
513
+
514
+ ```yaml
515
+ # HTTP请求配置
516
+ method: GET
517
+ url: https://api.example.com/tasks/123
518
+
519
+ # 断言定义
520
+ asserts:
521
+ - ["status", "eq", 200] # 索引0
522
+ - ["jsonpath", "$.status", "eq", "completed"] # 索引1
523
+ - ["jsonpath", "$.result", "exists"] # 索引2
524
+
525
+ # 独立的断言重试配置(推荐)
526
+ retry_assertions:
527
+ count: 3 # 全局重试次数
528
+ interval: 1 # 全局重试间隔(秒)
529
+ all: true # 是否重试所有断言
530
+ indices: [1, 2] # 指定要重试的断言索引
531
+ specific: # 针对特定断言的重试配置
532
+ "1": { # 索引1的断言特定配置
533
+ count: 5, # 特定重试次数
534
+ interval: 2 # 特定重试间隔
535
+ }
536
+ ```
537
+ 详细文档请参阅 [HTTP断言重试指南](./docs/http_assertion_retry.md)。