只需 10 分钟,搞懂 pytest-dsl 这款类 RobotFramework 的测试神器

184 阅读3分钟

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 将是你不错的选择!****


需要我协助生成配套的封面图或掘金文章发布文案也可以告诉我。