Pytest-Bdd-Playwright 系列教程(12):步骤参数 parsers参数解析

Pytest-Bdd-Playwright 系列教程(12):步骤参数 & parsers参数解析

  • 前言
  • 一、什么是步骤参数?
  • 二、pytest-bdd 的步骤参数用法
    • 2.1 简单字符串解析
    • 2.2 自定义正则表达式解析
    • 2.3 参数类型转换
  • 三、案例:基于 pytest-bdd 实现计算器功能测试
    • 3.1. 编写 Feature 文件
    • 3.2 实现步骤定义
    • 3.3 执行测试
  • 四、最佳实践
  • 总结

前言

  • 在 pytest-bdd 中,步骤参数是构建动态、灵活测试用例的核心功能之一,它允许通过占位符的形式将具体值插入步骤中,从而避免重复编写相似的场景;
  • 我们可以通过给步骤添加参数来重用步骤,实现单一实现和多重使用,从而使代码更简洁;
  • 本文将探讨如何通过简单字符串解析、自定义正则表达式解析以及参数类型转换等方法来灵活处理不同的参数需求,并通过一个基于计算器功能的完整案例进行说明。

一、什么是步骤参数?

在 Gherkin 描述中,步骤参数(Step Parameters)是动态定义测试数据的关键方式。它允许通过占位符的形式将具体值插入步骤中,从而避免重复编写相似的场景。例如:

Given 第一个数字是 5
And 第二个数字是 3
When 我按下 加号
Then 结果应该是 8

上述例子中的 538 是参数,通过步骤实现函数将它们传递到测试逻辑中进行处理。

二、pytest-bdd 的步骤参数用法

在 pytest-bdd 中,步骤参数通过字符串匹配实现,配合 pytest-bdd.parsers 模块,可以实现灵活的参数解析。以下是几种常见的参数解析方式:

2.1 简单字符串解析

简单字符串解析是 pytest-bdd 的默认行为,可以直接使用占位符解析参数。例如:

Given 第一个数字是 <first_number>

对应的 Python 实现:

from pytest_bdd import given, parsers

@given(parsers.parse("第一个数字是 {first_number:d}"))
def first_number(first_number):
    return first_number

解析规则通过 {} 语法实现,其中 :d 表示参数是整数类型。

2.2 自定义正则表达式解析

如果需要更复杂的匹配逻辑,可以使用自定义正则表达式。例如:

Then 计算器的宽度应该是 12.5

实现代码:

@then(parsers.re(r"计算器的宽度应该是 (?P<expected_width>\d+\.\d+)"))
def check_width(expected_width):
    assert float(expected_width) == 12.5

通过 parsers.re() 定义正则表达式,可以精确控制参数提取规则。

2.3 参数类型转换

pytest-bdd 支持内置的数据类型转换,例如:

  • {name:s}:字符串
  • {value:d}:整数
  • {value:f}:浮点数

在示例中,我们可以指定参数类型:

Given 第一个数字是 5

对应 Python 代码:

@given(parsers.parse("第一个数字是 {first_number:d}"))
def first_number(first_number):
    return first_number

测试框架会自动将参数 first_number 转换为整数。


三、案例:基于 pytest-bdd 实现计算器功能测试

接下来,我们通过一个具体的案例,展示如何在 pytest-bdd 中使用步骤参数。

3.1. 编写 Feature 文件

首先,新增 featuress/calculator_example.feature文件,定义计算器的几个功能测试场景:

Feature: 计算器
  一个简单的计算器,用于执行基本的算术操作。

  Background:
    Given 我已经准备好计算器

  Scenario: 检查计算器的尺寸
    Then 计算器的宽度应该是 12.5
    And 计算器的高度应该是 20.0
    And 计算器的厚度应该是 0.5

  Scenario: 打开计算器
    Given 我按下电源按钮
    Then 屏幕应该亮起

  Scenario Outline: 两个数之间的计算
    Given 我检查按钮是否正常
    And 第一个数字是 <first_number>
    And 第二个数字是 <second_number>
    When 我按下 <operation>
    Then 结果应该是 <expected_result>

    Examples:
      | first_number | second_number | operation | expected_result |
      | 5            | 3            | 加号       | 8               |
      | 10           | 4            | 减号       | 6               |
      | 2            | 6            | 乘号       | 12              |
      | 8            | 2            | 除号       | 4               |

3.2 实现步骤定义

tests/test_calculator_example.py 文件中为上述场景定义步骤参数:

import pytest
from pytest_bdd import given, when, then, parsers, scenarios


scenarios("calculator_example.feature")

@given("我已经准备好计算器")
def _():
    print("计算器已准备好!")

@given("我检查按钮是否正常")
def _():
    print("按钮已检查。")

@given("我按下电源按钮")
def _():
    pass

@then("屏幕应该亮起")
def _():
    pass

@then(parsers.parse("计算器的宽度应该是 {expected_width:f}"))
def _(expected_width: float):
    print(f"宽度: {expected_width}")

@then(parsers.parse("计算器的高度应该是 {expected_height:f}"))
def _(expected_height: float):
    print(f"高度: {expected_height}")

@then(parsers.parse("计算器的厚度应该是 {expected_thickness:f}"))
def _(expected_thickness: float):
    print(f"厚度: {expected_thickness}")

@given(parsers.parse("第一个数字是 {first_number:d}"), target_fixture="first_number")
def _(first_number):
    return first_number

@given(parsers.parse("第二个数字是 {second_number:d}"), target_fixture="second_number")
def _(second_number):
    return second_number

@when(parsers.parse("我按下 {operation}"), target_fixture="result")
def _(operation, first_number, second_number):
    if operation == "加号":
        return first_number + second_number
    elif operation == "减号":
        return first_number - second_number
    elif operation == "乘号":
        return first_number * second_number
    elif operation == "除号":
        return first_number / second_number
    else:
        raise ValueError(f"不支持的操作: {operation}")

@then(parsers.parse("结果应该是 {expected_result:d}"))
def _(result, expected_result):
    assert result == expected_result

3.3 执行测试

运行测试命令:

pytest .\tests\test_calculator_example.py

输出结果如下:

在这里插入图片描述

四、最佳实践

  1. 合理使用参数类型
    根据步骤的需求选择合适的数据类型解析器,确保输入值正确解析。

  2. 避免重复代码
    如果多个步骤有相似逻辑,可以使用 Python 的函数装饰器和参数化技术优化代码。

  3. 使用目标 Fixture
    利用 target_fixture 提取步骤中的数据,简化上下文传递。

  4. 测试数据分离
    将测试数据与逻辑分离(如使用 Examples 表),提高测试用例的可读性和可维护性。

总结

pytest-bdd 的步骤参数功能通过灵活的解析机制,为测试用例的动态数据支持提供了强大的工具。在本文中,我们通过对步骤参数的详尽讲解和计算器案例的实操演示,展示了如何高效使用这一功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/919049.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

EHOME视频平台EasyCVR多品牌摄像机视频平台监控视频编码H.265与Smart 265的区别?

在视频监控领域&#xff0c;技术的不断进步推动着行业向更高效、更智能的方向发展。特别是在编码技术方面&#xff0c;Smart 265作为一种新型的视频编码技术&#xff0c;相较于传统的H.265&#xff0c;有明显优势。这种技术的优势在EasyCVR视频监控汇聚管理平台中得到了充分的体…

利用redis的key失效监听器KeyExpirationEventMessageListener作任务定时提醒功能

某需求&#xff1a; 要求在任务截止日期的前3天时&#xff0c;系统自动给用户发一条消息提醒。 用定时任务的话感觉很不舒服。间隔时间不好弄。不能精准卡到那个点。 由于系统简单&#xff0c;没有使用消息列队&#xff0c;也不能使用延时队列来做。 用Timer的话开销还挺大的&a…

数造科技亮相第26届高交会并接受媒体采访,以数据智能赋能未来

11 月 14 日至 16 日&#xff0c;第二十六届中国国际高新技术成果交易会&#xff08;简称“高交会”&#xff09;在深圳成功举办。本届大会以“科技引领发展&#xff0c;产业融合聚变”为主题&#xff0c;汇聚了全球最新的科技成果&#xff0c;打造了一场科技界的盛大聚会。 在…

Facebook广告投放如何提高过审率?

在Facebook进行广告投放活动时&#xff0c;如何让广告过审应该是让很多人头疼的事情&#xff0c;前期花时间准备文案素材等&#xff0c;结果广告不过审&#xff0c;等于一切的前期准备都打水漂了&#xff0c;特别是黑五类的一些产品。许多独立站会架设斗篷&#xff0c;根据市场…

springBoot插件打包部署

打包插件spring-boot-maven-plugin 不使用插件&#xff0c;运行时&#xff0c;异常信息为“没有主清单属性” 本地部署 杀进程

VSCode+ESP-IDF开发ESP32-S3-DevKitC-1(2)第一个工程 LED心跳灯

VSCodeESP-IDF开发ESP32-S3-DevKitC-1&#xff08;2&#xff09;第一个工程 LED心跳灯 前言1.新建工程2.编写控制LED代码3.LED控制独立成.c和.h文件 前言 实际开发中很多时候我们需要有一个类似心跳灯或运行指示灯的灯以不同的状态闪烁以表示程序的运行状态&#xff0c;所以第…

【金融风控项目-06】:风控建模流程

文章目录 2 风控建模流程2.1 ABC评分卡简介2.2 机器学习模型工作的完整流程2.3 项目准备期2.3.1 明确需求 2.4 模型设计2.4.1 业务抽象成分类/回归问题2.4.2 模型算法2.4.3 模型输入2.4.4 Y标签定义2.4.5 样本选取2.4.6 样本采样2.4.7 观察期和表现期2.4.8 Y标签阈值确定2.4.9 …

Gartner发布中国PAM特权访问管理创新洞察:PAM的8个主要目标和国内9个主要提供商

特权账户是攻击者的主要目标&#xff0c;对每个组织来说都是重大的安全风险。安全和风险管理领导者可以利用这项研究来了解技术前景并降低特权访问风险。 主要发现 合规在推动中国采用特权访问管理 (PAM) 工具方面发挥着重要作用。然而&#xff0c;这些工具的实施经常遭到IT管理…

mayo介绍和QTqmake编译基于Opencascade开发的mayo工程-小白配置

目录: 一、mayo介绍:zap: 最新功能&#xff08;截止7.8.2&#xff09;在这里插入图片描述 二、编译准备三、编译过程3.1QT Creator打开源码的pro工程3.2修改几处pro配置3.3复制所需的动态链接库3.4编译完成 一、mayo介绍 1️⃣mayo是一个基于opencascade开源库开发的一个开源CA…

ISUP协议视频平台EasyCVR私有化部署视频平台如何实现RTMP推流将大疆无人机的视频画面回传?

在现代视频监控和流媒体技术领域&#xff0c;EasyCVR视频融合云平台以其卓越的性能和灵活性&#xff0c;成为了跨区域、网络化视频监控综合管理的理想选择。作为TSINGSEE青犀视频“云边端”架构体系中的核心组件&#xff0c;私有化部署视频平台EasyCVR不仅能够实现视频数据的集…

如何高效实现汤臣倍健营销云数据集成到SQLServer

新版订单同步-&#xff08;Life-Space&#xff09;江油泰熙&#xff1a;汤臣倍健营销云数据集成到SQL Server 在企业信息化建设中&#xff0c;数据的高效集成和管理是提升业务运营效率的关键。本文将分享一个实际案例——如何通过新版订单同步方案&#xff0c;将汤臣倍健营销云…

OpenHarmony-2.DeviceInfo适配

DeviceInfo适配说明 1.启动子系统设备信息说明 2.OHOS 2.1.OHOS 固定值参数适配 OHOS 固定值参数: const.ohos.version.security_patch const.ohos.releasetype const.ohos.apiversion const.ohos.fullname适配说明&#xff1a; OHOS 固定值参数由OHOS系统填充&#xff0…

Java实现两数交换

文章目录 实现两数交换方法一、&#xff08;数组的方式进行交换&#xff09;方法二、&#xff08;对象的方式进行交换&#xff09;总结 实现两数交换 实现两数交换&#xff0c;没有办法通过直接传递数字达到交换的结果&#xff0c;定义的int型变量是被存储在栈空间上的&#xf…

uniapp 购物弹窗组件 (微信小程序)

效果图&#xff0c;暂时只适应单规格&#xff0c;居中弹出和下方弹出&#xff0c;如需求不满足&#xff0c;请自行修改代码 &#xff08;更新于24/11/15) 居中显示效果 下方弹出效果 html <template><view class"" v-if"show":class"mod…

革新车间照明,分布式IO模块引领智能制造新纪元

在智能制造的浪潮中&#xff0c;每一个细节的优化都是推动生产效率与能耗管理迈向新高度的关键。车间照明系统&#xff0c;作为生产环境中不可或缺的一环&#xff0c;其智能化升级正成为众多企业转型升级的重要着力点。 一、从传统到智能&#xff1a;照明系统的变革之旅 传统…

Java基于微信小程序+SSM的校园失物招领小程序

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

微软Office 2021 24年11月授权版

概述 Microsoft Office LTSC 2021 专业增强版是微软公司推出的一款专为企业客户设计的办公软件套件。该版本于2024年11月进行了批量许可版更新推送&#xff0c;旨在为企业用户提供更加稳定、高效的办公体验。 主要特点 LOGO设计趋势强化&#xff1a;新版Office将棱角改为圆角…

uniapp实现中英文切换

home.js const data {ZH: {content1: "苹果",},EN: {content1: “Apple”,} } export default dataindex.js import home from "./home.js" export default {home }en.js import part1 from ./data/part1/index.js const en {language: {name: "…

go-zero(七) RPC服务和ETCD

go-zero 实现 RPC 服务 在实际的开发中&#xff0c;我们是通过RPC来传递数据的&#xff0c;下面我将通过一个简单的示例&#xff0c;说明如何使用go-zero框架和 Protocol Buffers 定义 RPC 服务。 一、生成 RPC项目 在这个教程中&#xff0c;我们根据user.api文件&#xff0…

C#.Net筑基-字符串超全总结

字符串是日常编码中最常用的引用类型了&#xff0c;可能没有之一&#xff0c;加上字符串的不可变性、驻留性&#xff0c;很容易产生性能问题&#xff0c;因此必须全面了解一下。 01、字符与字符编码 1.1、字符Char 字符 char 表示为 Unicode字符&#xff0c;在C#中用 UTF-16 …