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

相关文章

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

Verybot之OpenCV应用一:安装与图像采集测试

在Verybot上安装OpenCV是很简单的,只需要执行:         sudo apt-get update         sudo apt-get install libopencv-dev         sudo apt-get install python-opencv         下面就对安装好的OpenCV进行一下测试,编写一个通过USB摄像头采

【C++】作用域指针、智能指针、共享指针、弱指针

十、智能指针、共享指针 从上篇文章 【C++】如何用C++创建对象,理解作用域、堆栈、内存分配-CSDN博客 中我们知道,你的对象是创建在栈上还是在堆上,最大的区别就是对象的作用域不一样。所以在C++中,一旦程序进入另外一个作用域,那其他作用域的对象就自动销毁了。这种机制有好有坏。我们可以利用这个机制,比如可以自动化我们的代码,像智能指针、作用域锁(scoped_lock)等都是利用了这种机制。

BIRT 报表的自动化测试

来源:http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-birttest/如何为 BIRT 报表编写自动化测试用例 BIRT 是一项很受欢迎的报表制作工具,但目前对其的测试还是以人工测试为主。本文介绍了如何对 BIRT 报表进行自动化测试,以及在实际项目中的一些测试实践,从而提高了测试的效率和准确性 -------

js私有作用域(function(){})(); 模仿块级作用域

摘自:http://outofmemory.cn/wr/?u=http%3A%2F%2Fwww.phpvar.com%2Farchives%2F3033.html js没有块级作用域,简单的例子: for(var i=0;i<10;i++){alert(i);}alert(i); for循环后的i,在其它语言像c、java中,会在for结束后被销毁,但js在后续的操作中仍然能访

可测试,可维护,可移植:上位机软件分层设计的重要性

互联网中,软件工程师岗位会分前端工程师,后端工程师。这是由于互联网软件规模庞大,从业人员众多。前后端分别根据各自需求发展不一样的技术栈。那么上位机软件呢?它规模小,通常一个人就能开发一个项目。它还有必要分前后端吗? 有必要。本文从三个方面论述。分别是可测试,可维护,可移植。 可测试 软件黑盒测试更普遍,但很难覆盖所有应用场景。于是有了接口测试、模块化测试以及单元测试。都是通过降低测试对象

day45-测试平台搭建之前端vue学习-基础4

目录 一、生命周期         1.1.概念         1.2.常用的生命周期钩子         1.3.关于销毁Vue实例         1.4.原理​编辑         1.5.代码 二、非单文件组件         2.1.组件         2.2.使用组件的三大步骤         2.3.注意点         2.4.关于VueComponen