pytest-dsl 0.2.0__py3-none-any.whl → 0.3.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 +42 -6
- pytest_dsl/core/dsl_executor.py +133 -2
- pytest_dsl/core/lexer.py +23 -1
- pytest_dsl/core/parser.py +111 -12
- pytest_dsl/core/parsetab.py +82 -61
- pytest_dsl-0.3.0.dist-info/METADATA +448 -0
- {pytest_dsl-0.2.0.dist-info → pytest_dsl-0.3.0.dist-info}/RECORD +11 -11
- {pytest_dsl-0.2.0.dist-info → pytest_dsl-0.3.0.dist-info}/WHEEL +1 -1
- pytest_dsl-0.2.0.dist-info/METADATA +0 -504
- {pytest_dsl-0.2.0.dist-info → pytest_dsl-0.3.0.dist-info}/entry_points.txt +0 -0
- {pytest_dsl-0.2.0.dist-info → pytest_dsl-0.3.0.dist-info}/licenses/LICENSE +0 -0
- {pytest_dsl-0.2.0.dist-info → pytest_dsl-0.3.0.dist-info}/top_level.txt +0 -0
@@ -1,504 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: pytest-dsl
|
3
|
-
Version: 0.2.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)来编写测试用例,使测试更加直观、易读和易维护。它不仅限于API测试,更是一个可以应对各种测试场景的通用自动化框架。
|
34
|
-
|
35
|
-
## 核心优势
|
36
|
-
|
37
|
-
- **关键字驱动架构**:使用高级抽象关键字描述测试步骤,无需编写复杂代码
|
38
|
-
- **易读的DSL语法**:自然语言风格的测试描述,降低学习门槛
|
39
|
-
- **高度可扩展**:轻松创建自定义关键字满足特定领域需求
|
40
|
-
- **统一测试框架**:通过扩展关键字包支持多种测试类型
|
41
|
-
- **完整测试生命周期**:内置teardown、变量管理和断言机制
|
42
|
-
- **非侵入式设计**:以"旁路模式"扩展现有pytest项目,不影响原有测试代码
|
43
|
-
|
44
|
-
## 与pytest的无缝集成
|
45
|
-
|
46
|
-
pytest-dsl采用装饰器模式与pytest框架无缝集成,这意味着:
|
47
|
-
|
48
|
-
1. **保留pytest的全部能力**:所有pytest的插件、钩子、参数化等功能都可以继续使用
|
49
|
-
2. **非侵入式设计**:可以在不修改现有测试代码的情况下,添加DSL测试
|
50
|
-
3. **混合测试模式**:可以在同一个项目中同时使用传统pytest测试和DSL测试
|
51
|
-
|
52
|
-
### 装饰器加载模式
|
53
|
-
|
54
|
-
```python
|
55
|
-
# test_api.py
|
56
|
-
from pytest_dsl.core.auto_decorator import auto_dsl
|
57
|
-
|
58
|
-
@auto_dsl("./api_tests") # 加载指定目录下所有的.auto文件
|
59
|
-
class TestAPI:
|
60
|
-
"""API测试类
|
61
|
-
|
62
|
-
该类将自动加载api_tests目录下的所有.auto文件作为测试方法
|
63
|
-
"""
|
64
|
-
pass
|
65
|
-
```
|
66
|
-
|
67
|
-
这种模式类似于BDD(行为驱动开发)框架,通过装饰器将DSL文件转换为标准的pytest测试方法,使其能被pytest识别和执行。
|
68
|
-
|
69
|
-
## 执行测试
|
70
|
-
|
71
|
-
pytest-dsl提供了两种方式执行测试:
|
72
|
-
|
73
|
-
### 1. 通过pytest命令
|
74
|
-
|
75
|
-
```bash
|
76
|
-
# 运行所有测试
|
77
|
-
pytest
|
78
|
-
|
79
|
-
# 运行特定测试文件
|
80
|
-
pytest test_api.py
|
81
|
-
|
82
|
-
# 使用pytest参数
|
83
|
-
pytest -v --alluredir=./reports
|
84
|
-
```
|
85
|
-
|
86
|
-
### 2. 通过命令行工具
|
87
|
-
|
88
|
-
```bash
|
89
|
-
# 直接执行单个DSL文件
|
90
|
-
pytest-dsl path/to/test_file.auto
|
91
|
-
|
92
|
-
# 执行目录中的所有DSL文件
|
93
|
-
pytest-dsl path/to/test_dir/
|
94
|
-
```
|
95
|
-
|
96
|
-
### 加载YAML变量文件
|
97
|
-
|
98
|
-
```bash
|
99
|
-
# 加载单个变量文件
|
100
|
-
pytest --yaml-vars vars.yaml
|
101
|
-
|
102
|
-
# 加载多个变量文件
|
103
|
-
pytest --yaml-vars common_vars.yaml --yaml-vars env_vars.yaml
|
104
|
-
|
105
|
-
# 加载目录中的所有YAML文件
|
106
|
-
pytest --yaml-vars-dir ./test_vars
|
107
|
-
```
|
108
|
-
|
109
|
-
## 入门示例:API测试
|
110
|
-
|
111
|
-
让我们通过一个实际可运行的API测试例子快速了解pytest-dsl的语法风格:
|
112
|
-
|
113
|
-
```python
|
114
|
-
@name: API测试入门示例
|
115
|
-
@description: 演示基本的API接口测试用法
|
116
|
-
@tags: [API, HTTP, 入门]
|
117
|
-
@author: Felix
|
118
|
-
@date: 2024-01-01
|
119
|
-
|
120
|
-
# 基本GET请求
|
121
|
-
[HTTP请求],客户端:'default',配置:'''
|
122
|
-
method: GET
|
123
|
-
url: https://jsonplaceholder.typicode.com/posts/1
|
124
|
-
asserts:
|
125
|
-
- ["status", "eq", 200]
|
126
|
-
- ["jsonpath", "$.id", "eq", 1]
|
127
|
-
- ["jsonpath", "$.title", "exists"]
|
128
|
-
''',步骤名称:'获取文章详情'
|
129
|
-
|
130
|
-
# 响应数据捕获与使用
|
131
|
-
[HTTP请求],客户端:'default',配置:'''
|
132
|
-
method: GET
|
133
|
-
url: https://jsonplaceholder.typicode.com/posts
|
134
|
-
request:
|
135
|
-
params:
|
136
|
-
userId: 1
|
137
|
-
captures:
|
138
|
-
first_post_id: ["jsonpath", "$[0].id"]
|
139
|
-
post_count: ["jsonpath", "$", "length"]
|
140
|
-
asserts:
|
141
|
-
- ["status", "eq", 200]
|
142
|
-
- ["jsonpath", "$", "type", "array"]
|
143
|
-
''',步骤名称:'获取用户文章列表'
|
144
|
-
|
145
|
-
# 打印捕获的变量
|
146
|
-
[打印],内容:'第一篇文章ID: ${first_post_id}, 文章总数: ${post_count}'
|
147
|
-
|
148
|
-
# POST请求创建资源
|
149
|
-
[HTTP请求],客户端:'default',配置:'''
|
150
|
-
method: POST
|
151
|
-
url: https://jsonplaceholder.typicode.com/posts
|
152
|
-
request:
|
153
|
-
headers:
|
154
|
-
Content-Type: application/json
|
155
|
-
json:
|
156
|
-
title: 测试标题
|
157
|
-
body: 测试内容
|
158
|
-
userId: 1
|
159
|
-
captures:
|
160
|
-
new_post_id: ["jsonpath", "$.id"]
|
161
|
-
asserts:
|
162
|
-
- ["status", "eq", 201]
|
163
|
-
- ["jsonpath", "$.title", "eq", "测试标题"]
|
164
|
-
''',步骤名称:'创建新文章'
|
165
|
-
|
166
|
-
@teardown do
|
167
|
-
[打印],内容:'API测试完成!'
|
168
|
-
end
|
169
|
-
```
|
170
|
-
|
171
|
-
## 入门示例:变量与循环
|
172
|
-
|
173
|
-
loops.auto 文件展示了如何在测试中使用变量和循环结构:
|
174
|
-
|
175
|
-
```python
|
176
|
-
@name: 变量和循环示例
|
177
|
-
@description: 演示变量使用和循环结构
|
178
|
-
@tags: [变量, 循环, 入门]
|
179
|
-
@author: Felix
|
180
|
-
@date: 2024-01-01
|
181
|
-
|
182
|
-
# 基本变量定义和使用
|
183
|
-
name = "pytest-dsl"
|
184
|
-
version = "1.0.0"
|
185
|
-
[打印],内容:'测试框架: ${name}, 版本: ${version}'
|
186
|
-
|
187
|
-
# 循环结构示例
|
188
|
-
[打印],内容:'开始循环测试'
|
189
|
-
count = 3
|
190
|
-
|
191
|
-
for i in range(1, ${count}) do
|
192
|
-
[打印],内容:'循环次数: ${i}'
|
193
|
-
end
|
194
|
-
|
195
|
-
[打印],内容:'循环结束'
|
196
|
-
|
197
|
-
@teardown do
|
198
|
-
[打印],内容:'变量和循环测试完成!'
|
199
|
-
end
|
200
|
-
```
|
201
|
-
|
202
|
-
## 完整项目示例
|
203
|
-
|
204
|
-
下面是一个完整的项目结构,展示了如何组织pytest-dsl测试:
|
205
|
-
|
206
|
-
```
|
207
|
-
测试项目/
|
208
|
-
├── keywords/ # 自定义关键字
|
209
|
-
│ └── api_keywords.py
|
210
|
-
├── tests/
|
211
|
-
│ ├── test_api.py # 使用@auto_dsl装饰器的测试类
|
212
|
-
│ └── api_tests/ # DSL测试文件目录
|
213
|
-
│ ├── login.auto
|
214
|
-
│ ├── user_management.auto
|
215
|
-
│ └── orders.auto
|
216
|
-
├── vars/
|
217
|
-
│ ├── dev.yaml # 开发环境配置
|
218
|
-
│ └── prod.yaml # 生产环境配置
|
219
|
-
└── pytest.ini # pytest配置
|
220
|
-
```
|
221
|
-
|
222
|
-
其中`test_api.py`的内容可能如下:
|
223
|
-
|
224
|
-
```python
|
225
|
-
from pytest_dsl.core.auto_decorator import auto_dsl
|
226
|
-
|
227
|
-
@auto_dsl("./api_tests")
|
228
|
-
class TestAPI:
|
229
|
-
"""API测试类
|
230
|
-
|
231
|
-
自动加载api_tests目录下的所有.auto文件作为测试方法
|
232
|
-
"""
|
233
|
-
pass
|
234
|
-
```
|
235
|
-
|
236
|
-
## 当前内置关键字
|
237
|
-
|
238
|
-
pytest-dsl目前内置了以下几类关键字:
|
239
|
-
|
240
|
-
### 1. HTTP请求关键字
|
241
|
-
|
242
|
-
用于执行API接口测试,支持各种HTTP方法、请求配置、数据捕获和断言。
|
243
|
-
|
244
|
-
```python
|
245
|
-
# 完整的HTTP请求示例
|
246
|
-
[HTTP请求],客户端:'default',配置:'''
|
247
|
-
method: GET
|
248
|
-
url: https://jsonplaceholder.typicode.com/posts
|
249
|
-
request:
|
250
|
-
params:
|
251
|
-
_limit: 5
|
252
|
-
headers:
|
253
|
-
Accept: application/json
|
254
|
-
captures:
|
255
|
-
items: ["jsonpath", "$"]
|
256
|
-
count: ["jsonpath", "$", "length"]
|
257
|
-
asserts:
|
258
|
-
- ["status", "eq", 200]
|
259
|
-
- ["jsonpath", "$", "length", "lte", 5]
|
260
|
-
- ["response_time", "lt", 3000]
|
261
|
-
''',步骤名称:'获取文章列表'
|
262
|
-
```
|
263
|
-
|
264
|
-
### 2. 断言关键字
|
265
|
-
|
266
|
-
用于验证测试结果是否符合预期,支持多种断言类型。
|
267
|
-
|
268
|
-
```python
|
269
|
-
# 基本断言
|
270
|
-
[断言],条件:'1 + 1 == 2',消息:'基本算术断言失败'
|
271
|
-
|
272
|
-
# 数字比较
|
273
|
-
num1 = 10
|
274
|
-
num2 = 5
|
275
|
-
[断言],条件:'${num1} > ${num2}',消息:'数字比较断言失败'
|
276
|
-
|
277
|
-
# JSON数据处理
|
278
|
-
json_data = '{"user": {"name": "张三", "age": 30, "roles": ["admin", "user"]}}'
|
279
|
-
|
280
|
-
# JSON断言示例
|
281
|
-
[JSON断言],JSON数据:${json_data},JSONPath:'$.user.age',预期值:30,操作符:'==',消息:'JSON断言失败:年龄不匹配'
|
282
|
-
|
283
|
-
# 类型断言
|
284
|
-
[类型断言],值:${json_data},类型:'string',消息:'类型断言失败'
|
285
|
-
```
|
286
|
-
|
287
|
-
### 3. 全局关键字
|
288
|
-
|
289
|
-
用于基本操作和流程控制。
|
290
|
-
|
291
|
-
```python
|
292
|
-
# 打印输出
|
293
|
-
[打印],内容:'测试开始执行'
|
294
|
-
|
295
|
-
# 暂停执行
|
296
|
-
[等待],时间:2 # 等待2秒
|
297
|
-
|
298
|
-
# 简单变量赋值和使用
|
299
|
-
result = 53
|
300
|
-
[打印],内容:'结果: ${result}'
|
301
|
-
```
|
302
|
-
|
303
|
-
## HTTP断言重试功能
|
304
|
-
|
305
|
-
对于异步API或需要一定处理时间的请求,pytest-dsl提供了断言重试功能:
|
306
|
-
|
307
|
-
```python
|
308
|
-
# 断言重试示例 - 模拟处理延迟
|
309
|
-
[HTTP请求],客户端:'default',配置:'''
|
310
|
-
method: GET
|
311
|
-
url: https://httpbin.org/delay/2
|
312
|
-
request:
|
313
|
-
params:
|
314
|
-
task_id: ${task_id}
|
315
|
-
_: ${timestamp} # 添加时间戳防止缓存
|
316
|
-
captures:
|
317
|
-
url: ["jsonpath", "$.url"]
|
318
|
-
task_details: ["jsonpath", "$.args"]
|
319
|
-
asserts:
|
320
|
-
- ["status", "eq", 200]
|
321
|
-
- ["jsonpath", "$.args.task_id", "eq", "${task_id}"] # 这个断言一定会通过
|
322
|
-
- ["response_time", "lt", 1000] # 这个断言可能失败,因为延迟是2秒
|
323
|
-
''',断言重试次数: 3,断言重试间隔: 1
|
324
|
-
```
|
325
|
-
|
326
|
-
## 自定义关键字 - 框架的核心力量
|
327
|
-
|
328
|
-
pytest-dsl的真正强大之处在于能够轻松创建自定义关键字,扩展测试能力到任何领域:
|
329
|
-
|
330
|
-
```python
|
331
|
-
# keywords/my_keywords.py
|
332
|
-
from pytest_dsl.core.keyword_manager import keyword_manager
|
333
|
-
|
334
|
-
@keyword_manager.register('调用微服务', [
|
335
|
-
{'name': '服务名', 'mapping': 'service_name', 'description': '微服务名称'},
|
336
|
-
{'name': '方法名', 'mapping': 'method_name', 'description': '要调用的方法'},
|
337
|
-
{'name': '参数', 'mapping': 'params', 'description': '调用参数'}
|
338
|
-
])
|
339
|
-
def call_microservice(**kwargs):
|
340
|
-
"""调用内部微服务接口
|
341
|
-
|
342
|
-
Args:
|
343
|
-
service_name: 微服务名称
|
344
|
-
method_name: 方法名称
|
345
|
-
params: 调用参数
|
346
|
-
context: 测试上下文(自动传入)
|
347
|
-
"""
|
348
|
-
service = kwargs.get('service_name')
|
349
|
-
method = kwargs.get('method_name')
|
350
|
-
params = kwargs.get('params', {})
|
351
|
-
context = kwargs.get('context')
|
352
|
-
|
353
|
-
# 实现微服务调用逻辑
|
354
|
-
result = your_microservice_client.call(service, method, params)
|
355
|
-
return result
|
356
|
-
```
|
357
|
-
|
358
|
-
通过自定义关键字,您可以轻松扩展框架能力,实现:
|
359
|
-
- 数据库测试
|
360
|
-
- UI自动化测试
|
361
|
-
- 文件系统操作
|
362
|
-
- 微服务测试
|
363
|
-
- 等更多领域的测试需求
|
364
|
-
|
365
|
-
## 快速安装
|
366
|
-
|
367
|
-
```bash
|
368
|
-
# 使用 pip 安装
|
369
|
-
pip install pytest-dsl
|
370
|
-
|
371
|
-
# 或使用 uv 安装(推荐)
|
372
|
-
uv pip install pytest-dsl
|
373
|
-
```
|
374
|
-
|
375
|
-
## 框架核心特性
|
376
|
-
|
377
|
-
### DSL语法结构
|
378
|
-
|
379
|
-
```python
|
380
|
-
@name: 测试用例名称
|
381
|
-
@description: 测试用例描述
|
382
|
-
@tags: [标签1, 标签2]
|
383
|
-
@author: 作者名
|
384
|
-
@date: 2024-05-01
|
385
|
-
|
386
|
-
# 变量定义
|
387
|
-
name = "pytest-dsl"
|
388
|
-
version = "1.0.0"
|
389
|
-
[打印],内容:'测试框架: ${name}, 版本: ${version}'
|
390
|
-
|
391
|
-
# 循环结构
|
392
|
-
count = 3
|
393
|
-
for i in range(1, ${count}) do
|
394
|
-
[打印],内容:'循环次数: ${i}'
|
395
|
-
end
|
396
|
-
|
397
|
-
# 关键字调用示例
|
398
|
-
[HTTP请求],客户端:'default',配置:'''
|
399
|
-
method: GET
|
400
|
-
url: https://jsonplaceholder.typicode.com/posts/1
|
401
|
-
asserts:
|
402
|
-
- ["status", "eq", 200]
|
403
|
-
''',步骤名称:'获取数据'
|
404
|
-
|
405
|
-
@teardown do
|
406
|
-
# 清理操作
|
407
|
-
[打印],内容:'测试完成!'
|
408
|
-
end
|
409
|
-
```
|
410
|
-
|
411
|
-
### 数据驱动测试
|
412
|
-
|
413
|
-
使用CSV文件测试多组数据:
|
414
|
-
|
415
|
-
```python
|
416
|
-
@name: 批量测试
|
417
|
-
@data: 'test_data.csv' using csv
|
418
|
-
|
419
|
-
# 使用CSV数据中的"username"和"password"列
|
420
|
-
[HTTP请求],客户端:'default',配置:'''
|
421
|
-
method: POST
|
422
|
-
url: https://example.com/api/login
|
423
|
-
request:
|
424
|
-
json:
|
425
|
-
username: "${username}"
|
426
|
-
password: "${password}"
|
427
|
-
asserts:
|
428
|
-
- ["status", "eq", ${expected_status}]
|
429
|
-
'''
|
430
|
-
```
|
431
|
-
|
432
|
-
### 变量管理
|
433
|
-
|
434
|
-
使用YAML文件管理不同环境的配置:
|
435
|
-
|
436
|
-
```yaml
|
437
|
-
# environments.yaml
|
438
|
-
test:
|
439
|
-
base_url: "https://test-api.example.com"
|
440
|
-
credentials:
|
441
|
-
username: "test_user"
|
442
|
-
password: "test_pass"
|
443
|
-
|
444
|
-
production:
|
445
|
-
base_url: "https://api.example.com"
|
446
|
-
credentials:
|
447
|
-
username: "${PROD_USERNAME}" # 从环境变量获取
|
448
|
-
password: "${PROD_PASSWORD}"
|
449
|
-
```
|
450
|
-
|
451
|
-
## 测试项目结构
|
452
|
-
|
453
|
-
```
|
454
|
-
测试项目/
|
455
|
-
├── keywords/ # 自定义关键字
|
456
|
-
│ └── api/ # API测试关键字
|
457
|
-
├── tests/ # 测试用例
|
458
|
-
│ ├── test_api.py # 使用@auto_dsl装饰器的测试类
|
459
|
-
│ └── api/ # DSL测试文件目录
|
460
|
-
│ ├── login.auto
|
461
|
-
│ └── users.auto
|
462
|
-
├── vars/ # 变量文件
|
463
|
-
│ ├── dev.yaml # 开发环境配置
|
464
|
-
│ └── prod.yaml # 生产环境配置
|
465
|
-
└── pytest.ini # pytest配置
|
466
|
-
```
|
467
|
-
|
468
|
-
## 未来扩展性
|
469
|
-
|
470
|
-
pytest-dsl的架构设计支持通过安装关键字包的方式进行扩展,未来将提供:
|
471
|
-
|
472
|
-
- 数据库测试关键字包
|
473
|
-
- UI自动化测试关键字包
|
474
|
-
- 文件系统操作关键字包
|
475
|
-
- 更多垂直领域的专用关键字包
|
476
|
-
|
477
|
-
## 为什么选择pytest-dsl?
|
478
|
-
|
479
|
-
- **降低自动化门槛**:不需要专业编程技能也能编写自动化测试
|
480
|
-
- **关注测试逻辑**:不必纠结于编程细节,专注业务测试逻辑
|
481
|
-
- **统一测试框架**:通过扩展关键字包覆盖多种测试类型
|
482
|
-
- **无缝集成pytest**:兼容pytest的所有插件和功能
|
483
|
-
- **可定制性强**:通过自定义关键字实现任何特定领域的测试需求
|
484
|
-
- **旁路模式扩展**:不干扰现有测试代码,可平滑演进
|
485
|
-
|
486
|
-
## 进阶文档
|
487
|
-
|
488
|
-
- [完整DSL语法指南](./docs/自动化关键字DSL语法设计.md)
|
489
|
-
- [创建自定义关键字](./pytest_dsl/docs/custom_keywords.md)
|
490
|
-
- [HTTP测试关键字](./docs/api.md)
|
491
|
-
- [断言关键字详解](./docs/assertion_keywords.md)
|
492
|
-
- [HTTP断言重试机制](./docs/http_assertion_retry.md)
|
493
|
-
|
494
|
-
## 贡献与支持
|
495
|
-
|
496
|
-
我们欢迎您的贡献和反馈!如有问题,请提交issue或PR。
|
497
|
-
|
498
|
-
## 许可证
|
499
|
-
|
500
|
-
MIT License
|
501
|
-
|
502
|
-
---
|
503
|
-
|
504
|
-
开始使用pytest-dsl,释放测试自动化的无限可能!
|
File without changes
|
File without changes
|
File without changes
|