pytest-bdd快速示例和问题解决

news2024/12/24 9:05:16

BDD 与 pytest-bdd

BDD 即 Behavior-driven development,行为驱动开发。BDD行为驱动是一种敏捷开发模式, 重点在于消除开发/测试对需求了解的歧义及用户场景的验证。
pytest-bdd 是一个BDD测试框架,类似于behave, cucumber。它可以统一单元测试和功能测试。

环境准备

首先需要确定是否安装了pytest-bdd框架,通过 pip show pytest-bdd 命令可以查看是否安装了pytest-bdd框架:

在这里插入图片描述

出现如上页面说明没有安装,安装pytest-bdd框架:使用pip安装pytest-bdd模块。

pip install pytest-bdd

备注: 也可以使用 pip list 命令查看所有已经安装的模块。

##示例场景与步骤

这里测试一个加法运算器, 在实际场景中验证加法使用Unit 测试即可,BDD 一般用作功能测试,这里为了演示方便使用该场景作为示例。

具体步骤如下:

  1. 创建用户场景文件(.feature后缀的文件)
  2. 编写步骤函数和测试场景。(这两者可以分开为不同文件,也可以合并在一起写)
  3. 开始测试

项目目录

pytest-bdd 对于目录的要求非常灵活,可以根据自己的项目结构进行配置。通常情况下,pytest-bdd 会将 feature 文件和 step 实现文件分别放置在不同的目录中,这两个目录可以分别为features/step_defs/,也可以根据自己的需要进行修改。同时,pytest-bdd 还可以支持多个 feature 目录和 step 实现目录,只需要在配置文件中进行相应的配置即可。

除了 feature 文件和 step 实现文件的目录外,pytest-bdd 还可以支持其他的目录,例如 fixture 目录、data 目录等。这些目录同样可以根据自己的需要进行配置。总之,pytest-bdd 的目录要求非常灵活,可以根据自己的项目进行配置。

简单起见, 这里演示的目录结构如下所示:

├────features/   # 用户场景
│    ├────calculator.feature

├────step_defs/  # 步骤函数和测试场景
│    ├────test_calculator.py
├────util/
│    └────calculator.py # 需要测试的计算器类

文件内容

  1. 用于测试的计算器类文件calculator.py的内容如下:
# calculator.py
class Calculator:
    def add(self, a, b):
        return a + b

    def subtract(self, a, b):
        return a - b

    def multiply(self, a, b):
        return a * b

    def divide(self, a, b):
        if b == 0:
            raise ValueError("Cannot divide by zero")
        return a / b
  1. 用户场景文件calculator.feature 内容如下:
Feature: Addition
  Scenario: Add two numbers
    Given I have a calculator
    When I enter "1" and "2"
    Then the result should be "3"
  1. 步骤函数和测试场景文件test_calculator.py 内容如下:
import sys
import os
import pytest
#sys.path.append('D:/devworkspace/python-ency/chp3/tests/bdd/util')
sys.path.append(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util'))
from calculator import Calculator
from pytest_bdd import scenario, given, when, then, parsers



@scenario('../features/calculator.feature','Add two numbers')
def test_add():
    print(sys.path.append(os.path.dirname(os.path.dirname(__file__))+'util'))
    pass

@pytest.fixture
@given("I have a calculator")
def calculator():
    return Calculator()

@when(parsers.parse('I enter "{a}" and "{b}"'))
def enter_numbers(calculator, a, b):
    calculator.a = int(a)
    calculator.b = int(b)

@then(parsers.parse('the result should be "{result}"'))
def verify_result(calculator, result):
    assert calculator.add(calculator.a, calculator.b) == int(result)

测试

命令行切换到对应的目录,执行 pytest即可。执行的效果如下图:
在这里插入图片描述

问题

自定义类的导入方式

from calculator import Calculator
E   ModuleNotFoundError: No module named 'calculator'
  1. 添加绝对路径导入
import sys
sys.path.append("E:/mybdd/util")
  1. 添加上层目录
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(__file__)))

修改sys.path之后的导入行为会对你的整个 Python 环境产生影响,使用时需要谨慎。

  1. 相对导入
    .来表示当前目录,两个(或更多的)点..来表示上一层(或更多层)目录
    相对导入只有在作为模块的一部分时才能工作,也就是说,你不能直接运行一个使用了相对导入的 Python 文件,你需要通过主模块或者 -m 标志运行。
    Python 的相对导入基于当前的模块名称。所以,你不能在一个脚本直接运行时使用相对导入,因为脚本的__name__属性为__main__,Python 就不知道如何找到父模块或者兄弟模块。
    将你的脚本作为模块执行
    你可以使用-m选项来告诉 Python 运行包含相对导入的脚本作为一个模块。首先,确保你在当前执行目录的上级目录中,然后使用类似以下的命令:

python -m mypackage.mysubpackage.mymodule

对于相对导入,你必须以包的方式运行你的项目(也就是说目录下需要有__init__.py文件,让Python把这个目录看作包),例如你可能需要在项目的顶层目录下运行python -m main,而非python main.py

  1. 使用环境变量 PYTHONPATH

也可以通过在环境变量PYTHONPATH中添加你的模块所在的目录,Python 在运行时会添加这些目录到sys.path中,这样就可以搜索到你的模块了。
export PYTHONPATH=“${PYTHONPATH}:/my/new/path”

fixture ‘calculator’ not found

@pytest.mark.usefixtures(*func_args)
          def scenario_wrapper(request: FixtureRequest, _pytest_bdd_example: dict[str, str]) -> Any:
E       fixture 'calculator' not found

注意下面代码

@pytest.fixture
@given("I have a calculator")
def calculator():
    return Calculator()

@pytest.fixture 这一句必须加上, 很多在线的例子中都没有

ERROR test_calculator.py - TypeError: ‘NoneType’ object is not callable

@scenario('../features/calculator.feature','Add two numbers')
#@scenarios('../features/calculator.feature')
def test_add():
    pass

注意:使用scenarios会出现错误

本篇完整示例

  • https://download.csdn.net/download/oscar999/88532317

参考

  • https://github.com/pytest-dev/pytest-bdd
  • https://pytest-bdd.readthedocs.io/en/stable/


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】——单链表(增删查改)

目录 前言: 一:单链表的特点 ​编辑 二:单链表实现 单链表定义 2.1申请节点(初始化) 2.2单链表尾插 ​编辑 2.3单链表打印 2.4单链表头插 2.5单链表尾删 2.6单链表头删 2.7单链表查找 2.8在目标位置后面插入…

三国杀中的概率学问题4——曹冲

前言 这篇文章是围绕曹冲的称象技能展开的一些数学上的讨论,将涉及到积分、概率论等知识,并会做很多拓展。 值得说明的是,本文受到了这篇文章的一些启发。 连续情形1 先来看一个连续情形的问题。 问题一:假设每张牌的点数是0~1…

JVM:卡表元素如何维护?(写屏障)

写屏障 上面使用记忆集解决了缩减GC Roots扫描范围的问题,现在又抛出来一个新的问题,卡表元素如何维护的呢?,例如它们何时变脏、谁来把它们变脏等。 何时变脏这个问题应该很明确的,原则上应该发生在引用类型字段赋值…

编译原理-语法分析-自上而下分析

文章目录 语法分析器的功能自上而下分析面临的问题LL(1)分析法左递归的消除直接左递归非直接左递归 消除左递归的算法消除回溯、提左因子FIRST提左因子FOLLOW集 LL(1)的分析条件LL(1)文法构造FIRST和FOLLOW集合构造每个文法符号的FIRST集合构造FOLLOW集合…

java网络编程之UDP协议

文章目录 UDP简介一发一收客户端:服务端: 多发多收实现多开客户端:服务端 UDP简介 UDP(User Datagram Protocol) DatagramSocket 用于创建客户端、服务端DatagramSocket() :创建客户端的Socket对象,系统随…

C++ 11 新特性

目录 1. 支持特性的编译器版本2. 模板表达式中空格3. 空指针4. auto5. 统一初始化6. explict7. 范围for8. default,delete9. 化名模板(alias template)10. using11. noexcept12. override13. final14. decltype15. lambda16. Variadic Templa…

4.2每日一题(求多元函数在某一点的微分)

1、分别求x和y的偏导,再相加即可 2、因为多元函数的表达式不方便求偏导,所以可以使用先代后求法: (1)对x偏导:把y0代入,很容易求出对x偏导的结果 (2)对y偏导&#xff1a…

Django——路由层

一. 路由匹配 1. 路由匹配注意事项 urlpatterns [url(r^admin/, admin.site.urls),# 首页url(r^$,views.home),# 路由匹配url(r^test/$,views.test),url(r^testadd/$,views.testadd),# 尾页(了解): 后期使用异常捕获处理, 这样的尾页让django的第二次在路径中斜杠APPEND_SL…

Redis解决缓存问题

目录 一、引言二、缓存三、Redis缓存四、缓存一致性1.缓存更新策略2.主动更新 五、缓存穿透六、缓存雪崩七、缓存击穿1.基于互斥锁解决具体业务2.基于逻辑过期解决具体业务 一、引言 在一些大型的网站中会有十分庞大的用户访问流量,而过多的用户访问对我们的MySQL数…

Linux SSH免密登录

目录 简介 创建Linux用户和用户组 配置LINUX静态IP 编辑IP映射 SSH免密登录配置 登录测试 简介 SSH(Secure shell)是可以在应用程序中提供安全通信的一个协议,通过SSH可以安全地进行网络数据传输,它的主要原理是利用非对称加密…

Libhybris之线程局部存储TLS实例(五)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

二十三、W5100S/W5500+RP2040树莓派Pico<Web I/O 通过网页控制板载LED灯>

文章目录 1 前言2 简介2 .1 什么是Web?2.2 Web的优点2.3 Web数据交互原理2.4 Web应用场景 3 WIZnet以太网芯片4 HTTP网络设置示例概述以及使用4.1 流程图4.2 准备工作核心4.3 连接方式4.4 主要代码概述4.5 结果演示 5 注意事项6 相关链接 1 前言 Web只是一个静态的文…

电源基础元件

文章目录 电源基础元件理想电压源理想电流源受控电源 电源基础元件 理想电压源 定义 其两端电压总能保持定值或一定的时间函数,其值与流过它的电流i无关的元件叫理想电压源 理想电压源的电压、电流关系 1.电源两端电压由电源本身决定,与外电路无关&…

桶装水订水送水app有哪些功能?

桶装水订水送水app是一款专为送水工量身打造的提供送水服务的软件,在这里,送水人员将更好的在线发布一些送水信息,在线接单等功能,极大的提高了工作效率,方便了日常生活。 系统的商户端,专为送水工日常送水…

【计算机网络】VRRP协议理论和配置

目录 1、VRRP虚拟路由器冗余协议 1.1、协议作用 1.2、名词解释 1.3、简介 1.4、工作原理 1.5、应用实例 2、 VRRP配置 2.1、配置命令 2.2、拓扑与配置: 1、VRRP虚拟路由器冗余协议 1.1、协议作用 虚拟路由冗余协议(Virtual Router Redundancy Protocol&am…

2023nacos源码解读第2集——nacos-server的启动

nacos 是一个典型的server-client中间件,server这里安装最新的nacos-server 2.3.0-BETA版本 1.docker启动nacos-server 镜像详情参考nacos-docker项目的readme ,很方便,但是官方提供的nacos-server镜像往往可能滞后,且不便于后续…

【Java 进阶篇】JQuery DOM操作:舞动网页的属性魔法

在前端的舞台上,属性操作是我们与HTML元素进行互动的关键步骤之一。而JQuery,这位前端开发的巫师,通过简洁而强大的语法,为我们提供了便捷的属性操作工具。在这篇博客中,我们将深入研究JQuery DOM操作中的属性操作&…

C语言--1,5,10人民币若干,现在需要18元,一共有多少种?

今天小编给大家分享一下穷举法的一道典型例题 一.题目描述 1,5,10人民币若干,现在需要18元,一共有多少种? 二.思路分析 总共有18块钱,设1元有x张,5元有y张,10元有z张,则有表达式:x5y10z18,穷举法最重要的…