pytest-dsl 是一个基于 pytest 的关键字驱动测试框架,使用自定义 DSL(领域特定语言)编写测试用例,让测试更直观、易读、易维护。它不仅适用于 API 测试,还可以扩展到 UI、数据库、性能等各类自动化测试场景。 github地址
🌟 特性亮点
- ✅ 关键字驱动架构:无需编写复杂代码
- ✅ 可读性强:自然语言风格 DSL 语法
- ✅ 自定义关键字支持:高度可扩展
- ✅ 与 pytest、Allure 无缝集成
- ✅ 支持远程关键字调用与分布式测试
🧪 快速开始
安装方式
# 使用 pip 安装
pip install pytest-dsl
# 推荐使用 uv 安装(更快更轻)
uv pip install pytest-dsl
✨ 示例:第一个 DSL 测试
创建 hello.dsl:
message = "Hello, pytest-dsl!"
[打印],内容: ${message}
for i in range(1, 3) do
[打印],内容: "循环次数: ${i}"
end
@teardown do
[打印],内容: "测试完成!"
end
运行测试:
pytest-dsl hello.dsl
# 或运行整个目录
pytest-dsl tests/
🧠 DSL 基础语法
变量、条件与循环
name = "pytest-dsl"
version = "1.0.0"
if version == "1.0.0" do
[打印],内容: "当前是正式版"
else
[打印],内容: "当前是开发版"
end
for i in range(1, 4) do
[打印],内容: "循环次数: ${i}"
end
内置关键字示例
[打印],内容: "测试开始执行"
[断言],条件: "1 + 1 == 2",消息: "算术断言失败"
🔧 自定义关键字(函数)
DSL 文件内可自定义关键字,类似函数:
@keyword 拼接字符串 (前缀, 后缀="默认后缀") do
结果变量 = "${前缀}${后缀}"
return ${结果变量}
end
问候语 = [拼接字符串],前缀: "你好, ",后缀: "世界"
[打印],内容: ${问候语}
可以将关键字定义提取至 .resource 文件并导入:
@import: "resources/common_utils.resource"
结果 = [拼接字符串],前缀: "开始",后缀: "结束"
🌐 API 测试示例
@name: "API测试示例"
[HTTP请求],客户端: "default",配置: '''
method: GET
url: https://jsonplaceholder.typicode.com/posts/1
asserts:
- ["status", "eq", 200]
- ["jsonpath", "$.id", "eq", 1]
''',步骤名称: "获取文章详情"
支持变量捕获与条件断言:
[HTTP请求],客户端: "default",配置: '''
method: GET
url: https://jsonplaceholder.typicode.com/posts
request:
params:
userId: 1
captures:
post_count: ["jsonpath", "$", "length"]
asserts:
- ["status", "eq", 200]
''',步骤名称: "获取用户文章列表"
[打印],内容: "用户文章数量: ${post_count}"
📁 YAML 变量文件
创建 variables.yaml:
api:
base_url: "https://jsonplaceholder.typicode.com"
timeout: 30
使用方式:
pytest-dsl api_test.dsl --yaml-vars variables.yaml
🧬 与 pytest 集成
创建测试类:
from pytest_dsl.core.auto_decorator import auto_dsl
@auto_dsl("./api_tests")
class TestAPI:
pass
运行方式:
pytest
pytest test_api.py
pytest -v --alluredir=./reports
📊 集成 Allure 报告
pytest --alluredir=./allure-results
allure serve ./allure-results
# 或输出为静态HTML
allure generate ./allure-results -o ./allure-report
Allure 支持:
- 断言详情
- 请求/响应日志
- 步骤回溯
- 分类与标签过滤
🔁 高级特性
🔄 断言重试
[HTTP请求],客户端: "default",配置: '''
method: GET
url: https://httpbin.org/delay/2
asserts:
- ["status", "eq", 200]
- ["response_time", "lt", 1000]
''',断言重试次数: 3,断言重试间隔: 1
📂 数据驱动测试(CSV)
@data: "test_data.csv" using csv
[HTTP请求],客户端: "default",配置: '''
method: POST
url: https://example.com/api/login
request:
json:
username: "${username}"
password: "${password}"
asserts:
- ["status", "eq", ${expected_status}]
'''
💡 自定义 Python 关键字
创建 keywords/my_keywords.py:
from pytest_dsl.core.keyword_manager import keyword_manager
@keyword_manager.register('调用微服务', [
{'name': '服务名', 'mapping': 'service_name'},
{'name': '方法名', 'mapping': 'method_name'},
{'name': '参数', 'mapping': 'params'}
])
def call_microservice(**kwargs):
service = kwargs['service_name']
method = kwargs['method_name']
params = kwargs.get('params', {})
return your_microservice_client.call(service, method, params)
📦 项目结构建议
测试项目/
├── keywords/
│ └── api_keywords.py
├── tests/
│ ├── test_api.py
│ └── api_tests/
│ ├── login.dsl
│ └── users.dsl
├── vars/
│ ├── dev.yaml
│ └── prod.yaml
└── pytest.ini
🌍 分布式测试支持
启动远程关键字服务
pytest-dsl-server --host 0.0.0.0 --port 8270
在主机 DSL 文件中添加:
@remote: "http://remote-machine-ip:8270/" as remote1
远程服务可通过 API Key 保护:
pytest-dsl-server --api-key your_secret_key
✅ 总结:为什么选择 pytest-dsl?
| 优势 | 说明 |
|---|---|
| 🚫 降低门槛 | 非开发人员也能编写测试 |
| 🧠 更关注测试逻辑 | 语义清晰,专注业务 |
| 🛠 可扩展性强 | 自定义关键字、插件支持 |
| 🔁 与 pytest 无缝集成 | 支持 pytest 插件生态 |
| 📈 丰富报告和调试能力 | 支持 Allure 和日志分析 |
| 🌐 分布式执行能力 | 支持远程关键字调用 |
✨ 如果你正在寻找一种通用、高可读性、易维护的自动化测试方式,pytest-dsl 将是你不错的选择!****
需要我协助生成配套的封面图或掘金文章发布文案也可以告诉我。