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

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 + bdef subtract(self, a, b):return a - bdef multiply(self, a, b):return a * bdef divide(self, a, b):if b == 0:raise ValueError("Cannot divide by zero")return a / b
  1. 用户场景文件calculator.feature 内容如下:
Feature: AdditionScenario: Add two numbersGiven I have a calculatorWhen 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.hqwc.cn/news/174639.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络编程学习笔记

参考: 套接字通信部分 《TCP/IP 网络编程》以及《TCP/IP网络编程》学习笔记 socket 编程 1. 字节序 字节序,顾名思义字节的顺序,就是大于一个字节类型的数据在内存中的存放顺序,也就是说对于单字符来说是没有字节序问题的&…

鸿蒙HarmonyOS从零实现类微信app效果第一篇,基础界面搭建

最近鸿蒙HarmonyOS开发相关的消息非常的火,传言华为系手机后续将不再支持原生Android应用,所以对于原Android应用开发对应的Harmony版本也被一系列大厂提上了日程。作为一个名义上的移动端开发工程师((⊙o⊙)…,最近写python多过A…

分类网络搭建示例

搭建CNN网络 本章我们来学习一下如何搭建网络,初始化方法,模型的保存,预训练模型的加载方法。本专栏需要搭建的是对分类性能的测试,所以这里我们只以VGG为例。 请注意,这里定义的只是一个简陋的版本,后续一…

STM32基础--NVIC中断控制器

一、NVIC是什么? NVIC是一种中断控制器。当一个中断正在处理时,另一个更高优先级的中断可以打断当前中断的执行,并立即得到处理。这种机制使得处理器在高速运行的同时,能够及时响应不同优先级的中断请求。 二、有哪些优先级&…

EasyA正在帮助Sui为新一代Web3 App培养构建者

最近,我们采访了Phil和Dom Kwok,他们是兄弟也是Web3教育移动应用EasyA的共同创始人。这个教育app通过学习模块和编码挑战的形式,向开发人员教授有关不同区块链及其独特特性的知识。他们在十月初推出了他们的第一个Sui模块,并在随后…

使用matlab制作声音采样率转换、播放以及显示的界面

利用matlab做一个声音采样率转换、播放以及显示的界面 大抵流程: 图形界面创建:使用figure函数创建名为“声音采样率转换”的图形界面,并设置了其位置和大小。 按钮和文本框:使用uicontrol函数创建了选择音频文件的按钮、显示当前…

CCF ChinaSoft 2023 论坛巡礼 | CCF-华为胡杨林基金-形式化方法专项(海报)论坛

2023年CCF中国软件大会(CCF ChinaSoft 2023)由CCF主办,CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办,将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

使用后端代码生成器,提高开发效率

如果你是一名后端开发者,那么大多数的工作一定是重复编写各种 CRUD(增删改查)代码。时间长了你会发现,这些工作不仅无趣,还会浪费你的很多时间,没有机会去做更有创造力和挑战的工作。 作为一名程序员&…

Gempy 实现地理位置3D模型的展示以及导出

1. 首先安装python gempy 包 pip install gempy python 版本 3.10 这个很重要,版本不同可能会报错 2. gdal 可能会报错, 一下地址根据python版本下载,然后移入到python解释器环境中, Script文件中,然后cmd ,pip install 文件名安装即可 Releases cgohlke/geospatial-wheels …

MySQL数据库的表操作

1.创建表 1.1一般格式 create table table_name( Field1 datatype, Field2 datatype, Field3 datatype ) charset 字符集名 collate 校验规则 engine 存储引擎; 解释: Field : 表示列名datatype: 表示列的类型 charset 字符集:…

④【数据查询】MySQL查询语句,拿来即用。

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ MySQL查询操作 ④【数据查询】MySQL查询语句&a…

pytorch需要用到的模型和数据

关于常用的模型和数据: pytorch网站上有很多已经封装好的训练好的模型和数据,我们只需要进行网站下载即可地址如下:pytorch模型数据地址 进入后,往下滑,点击Datasets,挑选自己需要用的数据