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 + 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/


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

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

相关文章

【Git】第四篇:基本操作(理解工作区、暂存区、版本库)

Git 工作区、暂存区和版本库 工作区:就是我们创建的本地仓库所在的目录暂存区: stage或index,一般放在.git(可隐藏文件)目录下的index文件(.git/index)中,所以我们把暂存区有时候也叫做索引(in…

飞书开发学习笔记(五)-Python快速开发网页应用

飞书开发学习笔记(五)-Python快速开发网页应用 一.下载示例代码 首先进入飞书开放平台: https://open.feishu.cn/app 凭证与基础信息 页面,在 应用凭证 中获取 App ID 和 App Secret 值。 教程和示例代码位置:https://open.feishu.cn/document/home/integrating-…

C语言 每日一题 牛客网 11.13 Day17

找零 Z国的货币系统包含面值1元、4元、16元、64元共计4种硬币&#xff0c;以及面值1024元的纸币。 现在小Y使用1024元的纸币购买了一件价值为N(0 < N≤1024)的商品&#xff0c;请问最少他会收到多少硬币&#xff1f; 思路 运用if语句进行判断分类 代码实现 int main() {…

基于php+thinkphp的网上书店购物商城系统

运行环境 开发语言&#xff1a;PHP 数据库:MYSQL数据库 应用服务:apache服务器 使用框架:ThinkPHPvue 开发工具:VScode/Dreamweaver/PhpStorm等均可 项目简介 系统主要分为管理员和用户二部分&#xff0c;管理员主要功能包括&#xff1a;首页、个人中心、用户管理、图书分类…

jupyter lab常用插件集合

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

毕业设计项目:基于java+springboot的共享单车信息网站

运行环境 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Ma…

【Java 进阶篇】JQuery DOM操作:通用属性操作的绝妙魔法

在前端的舞台上&#xff0c;JQuery犹如一位魔法师&#xff0c;为我们展现了操纵HTML元素的奇妙技巧。而在这个技巧的精妙组成中&#xff0c;通用属性操作是一门绝妙的魔法。在本篇博客中&#xff0c;我们将深入研究JQuery DOM操作中的通用属性操作&#xff0c;揭示这段魔法的神…

Linux进程间通信之命名管道及SystemV共享内存

命名管道及SystemV共享内存 命名管道1. 什么是命名管道2. 用命名管道实现server&client通信Log.hppcomm.hppserver.cppclient.cppclient.cppMakefile编译 system V共享内存1. 共享内存示意图2. 共享内存数据结构3. 共享内存函数3.1 shmget函数3.2 shmat函数3.3 shmdt函数3.…

一招验收测试自动化天下知

今天下午给同事就自动化验收测试做了一个简单的介绍&#xff0c;引起了大家的阵阵讨论。同时还有其他Team的人来分享各自的经验&#xff0c;他们也都做得相当不错。 测试包括很多种&#xff0c;单元测试、集成测试、功能测试、验收测试、数据库测试等等。撇开大家都熟悉的单元测…

基于JavaWeb+SSM+基于微信小程序的“生鲜食品”团购平台生鲜商城系统的设计和实现

基于JavaWebSSM基于微信小程序的“生鲜食品”团购平台生鲜商城系统的设计和实现 源码获取入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 生鲜食品是我们生活中的必需品&#xff0c;为了确保食品的新鲜…

leetCode 25.K 个一组翻转链表

给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。k 是一个正整数&#xff0c;它的值小于 或 等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保持原有顺序。你不能只是单纯的改变节点内部的值&a…

设计模式—结构型模式之代理模式

设计模式—结构型模式之代理模式 代理模式(Proxy Pattern) ,给某一个对象提供一个代理&#xff0c;并由代理对象控制对原对象的引用,对象结构型模式。 静态代理 比如我们有一个直播平台&#xff0c;提供了直播功能&#xff0c;但是如果不进行美颜&#xff0c;可能就比较冷清…

基于springboot+vue的学生毕业离校信息网站

项目介绍 该学生毕业离校系统包括管理员、学生和教师。其主要功能包括管理员&#xff1a;首页、个人中心、学生管理、教师管理、离校信息管理、费用结算管理、论文审核管理、管理员管理、留言板管理、系统管理等&#xff0c;前台首页&#xff1b;首页、离校信息、网站公告、留…

博弈论入门

目录 什么是博弈&#xff1f; 博弈论的发展历史&#xff1f; 博弈的要素有哪些&#xff1f; 博弈的分类&#xff1f; 博弈论的应用 收益矩阵 纳什均衡的定义 博弈论的例子 1、田忌赛马 2、穷途困境 2.1优化反应函数法 2.2Nashpy库 2.3顶点枚举算法 3、Nash游戏 …

WebUI 自动化测试框架搭建详解

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

Nginx-基础-基础配置(Server,Location语法,匹配优先级,rewrite)

请求定位(Server模块) nginx有两层指令来匹配请求 URL &#xff1a; 第一个层次是 server 指令&#xff0c;它通过域名、ip和端口来做第一层级匹配&#xff0c;当找到匹配的 server 后就进入此 server 的 location 匹配。第二个层次是location指令&#xff0c;它通过请求uri来…

“谐波”分析治理,电能质量在线监测

安科瑞 崔丽洁 摘要&#xff1a;在国家鼓励半导体材料国产化的政策导向下&#xff0c;本土半导体材料厂商不断提升半导体产品技术水平和研发能力&#xff0c;逐渐打破了国外半导体厂商的垄断格局&#xff0c;推进中国半导体材料国产化进程&#xff0c;促进中国半导体行业的发展…

ssm826基于ssm的电影评论系统+vue

ssm826基于ssm的电影评论系统vue 交流学习 ​​​​​​​ 演示 项目功能演示&#xff1a; ————————————————

C语言-for循环入门代码

#include <stdio.h>int main() {int count;for (count 0; count < 10; count){printf("1\n");}system("pause");return 0; }1 1 1 1 1 1 1 1 1 1 请按任意键继续. . .灵活的for循环 死循环 while(1) {... }#include <stdio.h> int main(…

【ArcGIS Pro微课1000例】0030:ArcGIS Pro中自带晕渲地貌工具的妙用

在ArcGIS中,制作地貌晕渲效果通常的做法是先制作山体阴影效果,然后叠加在DEM的下面,再改变DEM的透明度来实现。而在ArcGIS Pro中自带了效果显著的晕渲地貌工具。 文章目录 一、晕渲地貌工具1. 符号系统2. 栅格函数二、山体阴影效果1. 工具箱2. 栅格函数打开ArcGIS Pro3.0,加…