pytest session scoped fixtures--pytest 会话作用域的fixtures(测试夹具)

2024-06-02 01:58

本文主要是介绍pytest session scoped fixtures--pytest 会话作用域的fixtures(测试夹具),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文博客链接
在《pytest fixtures nuts and bolts》这边博客中,我提到你可以通过限定会话作用域,来使fixture在整个测试会话期间运行一次,并且可以在多个测试函数、类、模块中访问。
在接下来的博客中,我将使用一个简单的例子来演示如何再说实际中使用:

下边的表格是前一篇博客中用到的:

functionRun once per test
classRun once per class of tests
moduleRun once per module
sessionRun once per session

conftest.py–一个用于fixtures的独立文件

在函数、类、以及module的作用域下,将fixture的代码和测试放在同一个文件是说的通的。
但是在会话作用域下,这样是不合理的。
我们可以将fixture的代码放到conftest.py文件。这是一个pytest指定寻找的特殊名字的文件。
pytest的官方文档之处这是为本地插件使用的,我们也可以将其用于本地fixtures。可以通过pytest.org网站来了解conftest.py的相关规定。


会话作用域fixtures的简单例子

我认为直接看实际的代码是最清晰的。
我准备了4个文件:

  • conftest.py
    • 2 fixtures
    • my_own_session_run_at_beginning, 一个会话作用域自动使用的fixture
    • some_resource, 一个会话作用域的非自动使用的fixture
  • test_alpha.py
    • 2个简单的测试函数
    • test_alpha_1, 没有命名的fixture
    • test_alpha_2, 有一个命名的fixture-some_resource
  • test_beta.py
    • 和test_alpha.py类似,只是使用了基于unittest的测试
  • test_gamma.py
    • 和test_aplha.py类似,使用了基于类的测试。
import pytest@pytest.fixture(scope="session", autouse=True)
def my_own_session_run_at_beginning(request):print('\nIn my_own_session_run_at_beginning()')def my_own_session_run_at_end():print('In my_own_session_run_at_end()')request.addfinalizer(my_own_session_run_at_end)@pytest.fixture(scope="session")
def some_resource(request):print('\nIn some_resource()')def some_resource_fin():print('\nIn some_resource_fin()')request.addfinalizer(some_resource_fin)

test_alpha.py:

def test_alpha_1():print('\nIn test_alpha_1()')def test_alpha_2(some_resource):print('\nIn test_alpha_2()') 

test_beta.py:

import unittest
import pytestclass BetaTest(unittest.TestCase):def test_unit_beta_1(self):print('\nIn test_unit_beta_1()')@pytest.mark.usefixtures('some_resource')    def test_unit_beta_2(self):print('\nIn test_unit_beta_2()')

test_gamma.py:

class TestGamma:def test_gamma_1(self):print('\nIn test_gamma_1()')def test_gamma_2(self, some_resource):print('\nIn test_gamma_2()')

Output

**Run with pytest -s -v

============================= test session starts ==============================
platform darwin -- Python 2.7.5 -- py-1.4.20 -- pytest-2.5.2 -- /usr/bin/python
collecting ... collected 6 itemstest_alpha.py:1: test_alpha_1 
In my_own_session_run_at_beginning()In test_alpha_1()
PASSED
test_alpha.py:4: test_alpha_2 
In some_resource()In test_alpha_2()
PASSED
test_beta.py:5: BetaTest.test_unit_beta_1 
In test_unit_beta_1()
PASSED
test_beta.py:8: BetaTest.test_unit_beta_2 
In test_unit_beta_2()
PASSED
test_gamma.py:2: TestGamma.test_gamma_1 
In test_gamma_1()
PASSED
test_gamma.py:5: TestGamma.test_gamma_2 
In test_gamma_2()
PASSED
In some_resource_fin()
In my_own_session_run_at_end()
=========================== 6 passed in 0.04 seconds ===========================

混合使用function,module和session作用域

首先看看我准备了什么:

  • 一个函数作用域的fixture-‘resource_c’
  • 一个模块作用域的fixture-‘resource_b’
  • 一个会话作用域的fixture-‘resource_a’

所有的这些都能完美工作
在这类例子中,我加入了一些autouse.

conftest.py:

import pytest@pytest.fixture(scope="session")
def resource_a(request):print('In resource_a()')def resource_a_fin():print('\nIn resource_a_fin()')request.addfinalizer(resource_a_fin)@pytest.fixture(scope="module")
def resource_b(request, resource_a):print('In resource_b()')def resource_b_fin():print('\nIn resource_b_fin()')request.addfinalizer(resource_b_fin)@pytest.fixture(scope="function")
def resource_c(request, resource_b):print('In resource_c()')def resource_c_fin():print('\nIn resource_c_fin()')request.addfinalizer(resource_c_fin)# these are just some fun dividiers to make the output pretty
# completely unnecessary, I was just playing with autouse fixtures
@pytest.fixture(scope="function", autouse=True)
def divider_function(request):print('\n        --- function %s() start ---' % request.function.__name__)def fin():print('        --- function %s() done ---' % request.function.__name__)request.addfinalizer(fin)@pytest.fixture(scope="module", autouse=True)
def divider_module(request):print('\n    ------- module %s start ---------' % request.module.__name__)def fin():print('    ------- module %s done ---------' % request.module.__name__)request.addfinalizer(fin)@pytest.fixture(scope="session", autouse=True)
def divider_session(request):print('\n----------- session start ---------------')def fin():print('----------- session done ---------------')request.addfinalizer(fin)

test_one_two.py:

def test_one(resource_c):print('In test_one()')def test_two(resource_c):print('\nIn test_two()')

test_three_four.py:

def test_three(resource_c):print('\nIn test_three()')def test_four(resource_c):print('\nIn test_four()')

**This seems reasonable to me.
What do you think will happen?**

output:

$ py.test -s -v
==================================== test session starts ====================================
platform darwin -- Python 2.7.5 -- py-1.4.20 -- pytest-2.5.2 -- /usr/bin/python
collected 4 items test_one_two.py:1: test_one 
----------- session start ---------------
------- module test_one_two start ---------
--- function test_one() start ---
In resource_a()
In resource_b()
In resource_c()
In test_one()
PASSED
In resource_c_fin()--- function test_one() done ---

test_one_two.py:4: test_two --- function test_two() start ---
In resource_c()In test_two()
PASSED
In resource_c_fin()--- function test_two() done ---

In resource_b_fin()------- module test_one_two done ---------

test_three_four.py:1: test_three ------- module test_three_four start ---------
--- function test_three() start ---
In resource_b()
In resource_c()In test_three()
PASSED
In resource_c_fin()--- function test_three() done ---

test_three_four.py:4: test_four --- function test_four() start ---
In resource_c()In test_four()
PASSED
In resource_c_fin()--- function test_four() done ---

In resource_b_fin()------- module test_three_four done ---------

In resource_a_fin()
----------- session done ---------------
================================= 4 passed in 0.02 seconds ==================================

警告:应该按照越来越大的作用域使用

如果使用的顺序反了,情况会脱离控制。
我们尝试在几个测试上调整一下顺序

conftest.py:

...
@pytest.fixture(scope="module")   # session -> module
def resource_a(request):print('In resource_a()')def resource_a_fin():print('\nIn resource_a_fin()')request.addfinalizer(resource_a_fin)@pytest.fixture(scope="session")   # module -> session
def resource_b(request, resource_a):
...

我们会在标准输出里面看到下述的错误和警告:

E           ScopeMismatchError: You tried to access the 'module' scoped fixture 'resource_a' 
... with a 'session' scoped request object, involved factories
E           conftest.py:18:  def resource_c(request, resource_b)
E           conftest.py:10:  def resource_b(request, resource_a)
E           conftest.py:2:  def resource_a(request)

所以,我们不能这么做。

警告同样适用于内嵌的fixtures。

pytest包括一些内嵌的fixtures。我相信他们都是function作用域。
这就意味着你只能将他们用在function作用域的fixtures。

我们深入一步讨论

我演示的代码只在fixture开始和结尾运行。
然而,你可以在session fixture的帮助下做更多,在pytest.org有一个很不错的例子A session-fixture which can look at all collected tests

这篇关于pytest session scoped fixtures--pytest 会话作用域的fixtures(测试夹具)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1022724

相关文章

将一维机械振动信号构造为训练集和测试集(Python)

从如下链接中下载轴承数据集。 https://www.sciencedirect.com/science/article/pii/S2352340918314124 import numpy as npimport scipy.io as sioimport matplotlib.pyplot as pltimport statistics as statsimport pandas

编译测试后出现“发现不明确的匹配”错误

原文链接:http://blog.163.com/zhaoyanping_1125/blog/static/201329153201204218533/ 错误提示: 【“/”应用程序中的服务器错误。  分析器错误 说明: 在分析向此请求提供服务所需资源时出错。请检查下列特定分析错误详细信息并适当地修改源文件。  分析器错误信息: 发现不明确的匹配。】   这个问题发生原因一般情况是

laravel 多个项目共享SESSION

只讨论一个域下的项目。 eg: a.xxx.com 和 b.xxx.com 来共享session 如果多个laravel项目共享SESSION要满足以下条件: SESSION可以存放在一个地方,eg:共用一个reids用户表为连接同一个数据库的用户表需要在同一域下 操作步骤:以将session 存放到redis中为例: 1. 安装redis库composer require predis/

RODNet安装测试

项⽬地址: GitHub - yizhou-wang/RODNet: RODNet: Radar object detection network 搭建环境并配置RODNet 1. 参考README.md搭建并配置环境 准备数据集 1. 本实验使⽤ ROD2021 dataset. 百度⽹盘链接:百度网盘 请输入提取码 密码:slxy 2. 使⽤这个script来重新组织文件。 具体形

Pytest和Unitest框架对比

在学到自动化的时候,很多同学都遇到了Pytest和Unitest框架,有的人是两个都学,但是学的不精只是知道分别怎么用.不了解两个区别是什么.有的是犹豫到底要学习那个框架.其实要做好自动化测试,是有必要了解不同框架之间的差异化的. Pytest 特点: Pytest采用了更简洁、更灵活的语法风格,使用“assert”语句来进行断言,Pytest可以自动发现并执行以“test_”开头的函数

Mockito测试

Mockito 一 mockito基本概念 Mock测试是单元测试的重要方法之一,而Mockito作为一个流行的Mock框架,简单易学,且有非常简洁的API,测试代码的可读性很高。 Mock测试就是在测试过程中,对于一些不容易构造(如HttpServletRequest必须在Servlet容器中才能构造出来)或者说获取比较复杂的对象(如JDBC中的ResultSet对象)

jmeter测试https请求

公司最近在搞全站HTTPS改造,进一步提高网站的安全性,防止运营商劫持。那么,改造完成后,所有前后端的URL将全部为https。 So ,研究下怎么用Jmeter访问https请求呢。 其实很简单, 第一步在jmeter中创建HTTP请求,如下图进行配置,https端口为443; 第二步,在本机浏览器,如Chrome中导入该域名证书,在更多工具-设置-管理证书的地方,找到该证书,导出到本地。然后在

pytest测试框架flaky插件重试失败用例

Pytest提供了丰富的插件来扩展其功能,本章介绍下插件flaky ,用于在测试用例失败时自动重新运行这些测试用例。与前面文章介绍的插件pytest-rerunfailures功能有些类似,但是功能上不如pytest-rerunfailures插件丰富。 flaky官方并没有明确python和pytest版本限制。 flaky安装 使用pip命令安装: pip install flaky

Maven的依赖传递、依赖管理、依赖作用域

在Maven项目中通常会引入大量依赖,但依赖管理不当,会造成版本混乱冲突或者目标包臃肿。因此,我们以SpringBoot为例,从三方面探索依赖的使用规则。 1、 依赖传递 依赖是会传递的,依赖的依赖也会连带引入。例如在项目中引入了spring-boot-starter-web依赖: <dependency><groupId>org.springframework.boot</groupId>

Selenium进行Web自动化测试

Selenium进行Web自动化测试 Selenium+Python实现Web自动化测试一、环境配置 Selenium+Python实现Web自动化测试 一、环境配置 环境基于win10(X64) 安装Python;安装PyCham安装chomedriver chomedriver下载地址 可以查看本地chrome软件版本下载对应的chomedriver,如果没有则下载最新