基于pytest-bdd的项目目录结构和命名规范

阿里云国际,腾讯云国际,AWS 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov8

pytest-bdd 的文件的命名规范

pytest-bdd 是基于pytest 之上所以需要遵循pytest 的命名规则才能进行测试具体有

  1. 测试文件名必须以*test.py或者test*.py命名
  2. 测试函数必须以 test_开头

在pytest-bdd中存在两类文件

  1. 以 .feature 结尾的用户场景文件
  2. 以 .py 结尾的测试代码。这里又细分为两类
  • @given@when@then 注解的步骤函数这些函数名没有强制限制 也可以借鉴beheave的写法以 step_开头。
  • @scenario 注解的测试场景函数这个函数名需要以 test_ 开头 因为这样才会被pytest 识别。

举例来看 @given@when@then 的步骤函数的示例

@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)

@scenario 注解的测试场景函数的示例

@scenario('../features/calculator.feature','Add two numbers')
def test_add():
    pass
  • @scenario 本身没有实际的内容只是一个占位符关联场景和步骤但是又不可少

关于 @scenario

@scenario是 pytest-bdd 框架中的一个装饰器用于标记一个 BDD 场景并将其与编写的测试函数关联起来。
@scenario装饰器可以用来定义一个场景并确定它所属的 feature 和 scenario。其语法如下

@scenario('<feature_file_path>', '<scenario_name>')
def test_my_scenario():
    pass

其中<feature_file_path>是 feature 文件的路径<scenario_name>是场景的名称。在测试方法中不需要任何具体的测试步骤。相反pytest-bdd 将自动加载与场景匹配的步骤并在执行测试时逐步执行它们。这意味着测试方法本身只是一个占位符其定义的唯一目的是将场景与步骤关联起来。

使用@scenario装饰器需要遵循一定的规则如下

  1. 一个@scenario装饰器用于定义一个场景。

  2. 必须指定该场景所属的 feature 文件的路径和场景名称。

  3. 测试函数的名称必须与场景名称匹配。

  4. 测试函数的参数必须与场景步骤的参数名称相匹配。

  5. 测试函数必须使用 BDD 关键字来编写场景步骤。

  6. pytest-bdd 将自动加载与场景匹配的步骤并在执行测试时逐步执行它们。

  7. 可以将多个场景分组在同一个 feature 文件中并在同一个测试类中执行它们。

使用pytest-bdd的项目的目录结构

基于以上目录的设计如下
1…feature 场景文件放置在项目根目录的 features目录中。[非强制]
2. 步骤函数和场景函数可以放在一个.py文件中 也可以放在两个 .py文件中。
3. 包含场景函数的.py 需要以test_ 开头 [强制]
4. 测试步骤的文件放置在项目根目录的steps 或step_defs 目录中[非强制]
5. 场景函数如果分拆出来放置在根目录的 test_cases目录中[非强制]
6. 在基于面向对象的设计中可以一个类一个场景文件 也可以一个功能一个场景文件。[非强制]

基于以上原则提供的几个目录结构示例如下

目录结构1

步骤函数和场景函数放在一起一个功能一个场景文件

├────features/   # 用户场景
│    ├────user/
│    │    ├────create_user.feature
│    ├────login.feature
├────step_defs/  # 步骤函数和测试场景
│    ├────user/
│    │    ├────test_create_user.py
│    └────test_login.py

目录结构2

步骤函数和场景函数放在一起一个类一个场景文件

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

│    ├────login.feature
├────step_defs/  # 步骤函数和测试场景
│    ├────user.feature

│    └────test_login.py

目录结构3

├────features/   # 用户场景
│    ├────user/
│    │    ├────create_user.feature
│    ├────login.feature
├────step_defs/  # 步骤函数
│    ├────user/
│    │    ├────create_user_steps.py
│    └────login_steps.py
├────test_case/  # 测试场景
│    ├────test_user/
│    │    ├────test_create_user.py
│    └────test_login.py

其他还可以用 cases和 test_cases 来命名类似如下

├────cases/  # 用户场景
│    ├────projects/
│    │    ├────create_project.features
│    ├────login.features
├────test_cases/  # 步骤函数和测试场景
│    ├────projects/
│    │    ├────test_create_project.py
│    └────test_login.py
├────test_cases/  # 测试用例
│    ├────features/  # 用户场景
│    │    ├────login.features
│    ├────step_defs/  # 步骤函数和测试场景
│    │    ├────test_login.py

以测试角度出发的目录

上面的目录规范是将BDD的规范文件和测试作为独立的部分 也有的项目从测试角度出发将BDD的文件作为测试的一部分 统一放入项目的tests 目录中

|-- tests
|   |-- features
|   |   |-- step_definitions
|   |   |   |-- __init__.py
|   |   |   |-- test_steps.py
|   |   |-- support
|   |   |   |-- conftest.py
|   |   |   |-- env.py
|   |   |   |-- hooks.py
|   |   |-- feature1.feature
|   |   |-- feature2.feature
|   |-- unit
|   |   |-- __init__.py
|   |   |-- test_module1.py
|   |   |-- test_module2.py
|   |-- __init__.py
|   |-- conftest.py
|-- setup.py
|-- requirements.txt
|-- README.md

  • tests目录包含所有测试相关文件其中features目录用于存放 BDD 测试用例和相关文件unit目录用于存放其他类型的测试用例。
  • step_definitions目录用于存放实现 BDD 测试用例步骤的 Python 脚本。每个 BDD 测试用例的步骤都应该在这里实现
  • support目录用于存放 BDD 测试用例所需的支持文件比如环境设置、钩子函数等。
  • conftest.py文件放在tests目录下用于实现项目级别的配置和夹具设置。
  • setup.py文件是一个 Python 包的安装脚本。
  • requirements.txt文件用于存储项目依赖库的清单。
  • README.md文件是项目的说明文档。

如果从BDD的定义和作用来看的话这种目录结构就有点混淆了 BDD和测试的概念因为BDD是有终端用户参与进来的部分 目录层级较深不利于使用个人是比较不建议这种方式。



阿里云国际,腾讯云国际,AWS 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov8

“基于pytest-bdd的项目目录结构和命名规范” 的相关文章

如何用thinkphp m方法实现多表查询 - 编程语言

本篇内容主要讲解“如何用thinkphp m方法实现多表查询”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何用thinkphp m方法实现多表查询”吧! 一、什么是多表查询在数据库中,有时我们...

java.security.InvalidKeyException: IOException : algid parse error, not a sequence

问题读取私钥时报错 KeyFactory keyFactory = KeyFactory.getInstance("RSA");PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decodeB...

重 构

终于把重构读完了,说实话,觉得它"闻名不如见面",好多东西和设计模式重复了.好吧,也多年以后我会觉得我错了,而且大错特错,我应该好好再读次.2012.06.03(BTY目前半年重构经验) 以下出自重构的要点列表,精华居然在书的最后... 1.如果你发现自己需...

一文搞懂 XSS攻击、SQL注入、CSRF攻击、DDOS攻击、DNS劫持

XSS 攻击全称跨站脚本攻击 Cross Site Scripting为了与重叠样式表 CSS 进行区分,所以换了另一个缩写名称 XSSXSS攻击者通过篡改网页,注入恶意的 HTML 脚本,一般是 javascript,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式XSS 攻击经常使用在...

每个程序员都应该知道的8大算法

在编程开发中算法是用于解决特定问题或完成特定任务的一组指令或过程。算法可以用任何编程语言表示可以像一系列基本操作一样简单也可以像涉及不同数据结构和逻辑的多步骤过程一样复杂。 算法的主要目标是接收输入、处理它并提供预期的输出。算法可以根据时间和空间复杂性、用于解决问题的技术以及解决问题的类型进行分类...

vue中父组件和子组件怎么通讯 - web开发

这篇文章主要介绍“vue中父组件和子组件怎么通讯”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vue中父组件和子组件怎么通讯”文章能帮助大家解决问题。 一、单向数据流在 Vue.js 中,父组件向子...