首页 > 其他分享 >pytest---fixture知识总结

pytest---fixture知识总结

时间:2023-09-17 16:23:21浏览次数:29  
标签:__ fixture --- test pytest print def

此博客内容全部来源于:https://zhuanlan.zhihu.com/p/443523226

前言

  在做自动化的过程中,编写用例时候需要用到用例的前置和用例的后置,其中pytest中有setup_class和teardown_class可以帮助我们完成这些,但是不够完善而且灵活性不够强。举个简单的例子,一个calss中有3条用例,其中2条需要登录,1条不需要登录,这个时候如果在用setup和teardown来做就有点不方便。这个时候就引入了新的知识点fixture。

fixture简单介绍

  fixture属于pytest中的一个方法。fixture可以用作测试用例的前置和后置操作,其中fixture命令规范没有像setup和teardown固定格式。可以随意命名。控制fixture的前置和后置操作是通过yield关键字进行来区分的,代码在yield前面的属于前置操作,代码在yield后面的属于后置操作。并且fixture也没有强烈的要求必须要前后置同时存在,可以只存在前置也可以只存在后置。fixture如果有后置内容,无论遇到什么问题,都会进行执行后置的代码。

源码:

def fixture(  # noqa: F811
    fixture_function: Optional[_FixtureFunction] = None,
    *,
    scope: "Union[_Scope, Callable[[str, Config], _Scope]]" = "function",
    params: Optional[Iterable[object]] = None,
    autouse: bool = False,
    ids: Optional[
        Union[
            Iterable[Union[None, str, float, int, bool]],
            Callable[[Any], Optional[object]],
        ]
    ] = None,
    name: Optional[str] = None
) -> Union[FixtureFunctionMarker, _FixtureFunction]:
    fixture_marker = FixtureFunctionMarker(
        scope=scope, params=params, autouse=autouse, ids=ids, name=name,
    )
    # Direct decoration.
    if fixture_function:
        return fixture_marker(fixture_function)
    return fixture_marker

通过上述源码可以看到,fixture中一共有5个参数分别是:scope,params,autouse,ids,name。具体每个参数代表什么先不解释,后面会介绍到。

fixture使用方法

  前面已经介绍了fixture是干什么的,但是具体的用法没有说,先介绍下具体用法,这里通过将登录操作写在一个函数中。然后通过装饰器的方法进行使其变成fixture。那条用例需要用到对应的前置和后置操作的时,直接将fixture的名称通过传参的形式放到用例中。

@pytest.fixture()
def login():
    print('登录操作')
    yield
    print('退出登录')

例子:
  一个class中存在3条用例,其中2条需要登录,1条不需要登录。运营fixture进行完成前后置操作。

import pytest
@pytest.fixture()
def login():
    print('登录操作')
    yield
    print('退出登录')
class Test_Login():
    def test_01(self, login):
        print('需要用到登录!')
    def test_02(self):
        print('不需要登录!')
    def test_03(self, login):
        print('这里需要用到登录!')
if __name__ == '__main__':
    pytest.main(['-vs'])

通过查看执行后的结果发现,login的fixture已经在test_01和test_03中进行使用到了。test_02没有用到登录。这里也没有给他传入,对应的结果也是没用登录。

 

从单纯的图片上看可能不是很明显,在命令行参数上加上--setuo-show进行详细打印出fixture在具体那条用例上进行生效。

 

 

用例异常后继续执行后置操作

前面提到过用例出现异常后,fixture继续执行后置操作。这里安静也距离给大家说明。

将上面的代码用例中加入断言内容,保证用例3断言失败,看看是否会执行后置操作(退出登录)。

import pytest
@pytest.fixture()
def login():
    print('登录操作')
    yield
    print('退出登录!')
class Test_Login():
    def test_01(self, login):
        print('需要用到登录!')
        assert 1==1
    def test_02(self):
        print('不需要登录!')
    def test_03(self, login):
        print('这里需要用到登录!')
        assert 1==2
if __name__ == '__main__':
    pytest.main(['-vs']

通过执行发现,我们的test_03断言失败后,继续执行了退出登录操作。也就是后置内容。

 

多个fixture同时使用

  fixture不仅仅能单个使用,还能一起使用。使用的执行顺序取决于你传入的顺序决定,意思就是,先传的先执行。

import pytest
@pytest.fixture()
def login():
    print('登录操作')
    yield
    print('退出登录!')
@pytest.fixture()
def log():
    print('打开日志功能!')
    yield 
    print('关闭日志功能!')
    
class Test_Login():
    def test_01(self, login, log):
        print('需要用到登录!')
    def test_02(self):
        print('不需要登录!')
    def test_03(self, log, login):
        print('这里需要用到登录!')
if __name__ == '__main__':
    pytest.main(['-vs'])

通过下图执行结果可以看出,test_01先执行的前置操作是login的,test_03先执行的前置操作是log的。

 

 

fixture相互调用

  你以为fixture的功能就这么多了?当然不是了,fixture还可以进行其他fixture的调用操作。

  调用方法:直接将被调用fixture的函数名放到调用的fixture当做参数传入。

import pytest
@pytest.fixture()
def login():
    print('\n登录操作')
    yield
    print('\n退出登录!')
    
@pytest.fixture()
def log(login):
    print('\n打开日志功能!')
    yield
    print('\n关闭日志功能!')
class Test_Login():
    def test_01(self, log):
        print('\n需要用到登录!')
    def test_02(self):
        print('\n不需要登录!')
    def test_03(self, log):
        print('\n这里需要用到登录!')
if __name__ == '__main__':
    pytest.main(['-vs'])

这里只需要传入一个参数即刻。通过执行发现,已经成功的调用了2个fixture的内容。

 

 

fixture参数详解

  上面介绍了如何使用fixture,以及fixture的之间的相互调用。前面也留下来一个问题就是关于fixture的5个参数都表示什么意思。5个参数分别是name,scope,params,autouse,ids,。安静一个个给大家解释。

 name

  name参数表示可以对fixture的名称进行重命名。

import pytest
@pytest.fixture(name='anjing')
def login():
    print('\n登录操作')
    yield
    print('\n退出登录!')
class Test_Login():
    def test_01(self, anjing):
        print('---用例01---')
    def test_02(self):
        print('---用例02---')
    def test_03(self, anjing):
        print('---用例03---')
if __name__ == '__main__':
    pytest.main(['-vs'])

执行后发现,通过参数name更改过的名字可以直接进行调用。

  注意:通过name重命名后,继续使用以前的名字调用会报错。

scope

  fixture中的参数scope是用于控制fixture的作用范围。

  源码:

_Scope = Literal["session", "package", "module", "class", "function"]

截图了源码中的主要一部分,这个标识scope中控制的还有其他的几种参数,“session”,“package”,“module”,“class”,“function”。

  其中scope默认参数为function,表示应用于单个测试函数中。

  session:主要应用于会话级别的fixture。

  module:主要应用于模块级别的fixture。

  class:主要应用于class中,表示每个前置和后置都会执行一次。

  package:主要应用于每个包下的fixture。

import pytest
@pytest.fixture(scope='session')
def fix_session():
    print('\n这是属于session')
    yield
    print('\nsession')
@pytest.fixture(scope='class')
def fix_class():
    print('\n这是属于class')
    yield
    print('\nsession')
@pytest.fixture(scope='module')
def fix_module():
    print('\n这是属于module')
    yield
    print('\nmodule')
@pytest.fixture(scope='function')
def fix_function():
    print('\n这是属于function')
    yield
    print('\nfunction')
class Test_01:
    def test_01(self, fix_function, fix_class,fix_module,fix_session):
        print('----用例01---')
if __name__ == '__main__':
    pytest.main(['-vs'])

通过执行会发现他们的执行顺序在不同的fixture作用范围内的执行顺序是不同的。

  执行顺序:session>>module>>class>>function

 

 

autouse

  autouse表示在fixture中用于控制fixture作用范围内的是否全部执行。默认为False,当设置为True的时候表示该fixture在当前作用范围内,全部执行。

import pytest
@pytest.fixture(autouse=True)
def login():
    print('\n登录操作')
    yield
    print('\n退出登录!')
class Test_Login():
    def test_01(self):
        print('---用例01---')
    def test_02(self):
        print('---用例02---')
    def test_03(self):
        print('---用例03---')
if __name__ == '__main__':
    pytest.main(['-vs'])

通过执行结果可以查看到我们当前的用例模块全部都调用了login。

 

 

params

  params表示fixture的参数化功能。参数化这里就不用多说了吧。

  这里会有一个request参数,主要用来接收fixture的返回结果。并通过request.param返回结果内容。

import pytest
data = ['anjing', 'test', 'admin']

@pytest.fixture(params=data, ids=['user=anjing','user=test','user=admin'])
def login(request):
    print('登录功能')
    yield request.param
    print('退出登录')

class Test_01:
    def test_01(self, login):
        print('---用例01---')
        print('登录的用户名:%s' % login)
    def test_02(self):
        print('---用例02---')

if __name__ == '__main__':
    pytest.main(['-vs'])

通过执行结果可以看到,我们的test_01一共执行了3次,每次都是不同的参数,参数也是通过login进行接收的。

 

 

ids

  ids表示在fixture对参数化的内容进行加上标识,比如让别人知道这个传入的参数是什么意思。用于什么样的测试用例。默认是传参数内容:

import pytest
data = ['anjing', 'test', 'admin']

@pytest.fixture(params=data, ids=['user=anjing','user=test','user=admin'])
def login(request):
    print('登录功能')
    yield request.param
    print('退出登录')

class Test_01:
    def test_01(self, login):
        print('---用例01---')
        print('登录的用户名:%s' % login)
    def test_02(self):
        print('---用例02---')

if __name__ == '__main__':
    pytest.main(['-vs'])

执行结果可以看到在每条用例的后面都会有对应的参数详解。

 

  

  

  

  

  

  

  

  

  

 

标签:__,fixture,---,test,pytest,print,def
From: https://www.cnblogs.com/ccnn9/p/17709020.html

相关文章

  • Linux学习之CentOS(三十一)--Linux远程管理之SSH、VNC
    您可以通过点击右下角的按钮来对文章内容作出评价,也可以通过左下方的关注按钮来关注我的博客的最新动态。如果文章内容对您有帮助,不要忘记点击右下角的推荐按钮来支持一下哦如果您对文章内容有任何疑问,可以通过评论或发邮件的方式联系我:[email protected]......
  • PHP入门-搭建运行环境
    在系统装好后,推荐将电脑的命名一个言简意赅的短小名称,这样在Linuxshell或Windows命令行下,看着更舒服,特别是输入的内容较长时,效果会更明显。最近被安排接手PHP项目,由于没接触过,所以做个记录整理,便于以后查看。不管做什么开发,搭建环境是第一步。1. XMAPP 是Apache+MySQL+PHP+PE......
  • Linux学习之CentOS(二十四)--Linux软件管理之YUM软件管理
     您可以通过点击右下角的按钮来对文章内容作出评价,也可以通过左下方的关注按钮来关注我的博客的最新动态。如果文章内容对您有帮助,不要忘记点击右下角的推荐按钮来支持一下哦如果您对文章内容有任何疑问,可以通过评论或发邮件的方式联系我:501395377@qq.......
  • 七天学会C语言-第二天(数据结构)
    1.If语句:If 语句是一种条件语句,用于根据条件的真假执行不同的代码块。它的基本形式如下:if(条件){//条件为真时执行的代码}else{//条件为假时执行的代码}写一个基础的If语句#include<stdio.h>intmain(){intx=10;if(x>5){printf("x......
  • 70-函数也是对象-内存分析
         ......
  • 69-返回值详解
         ......
  • Rockchip RK3399 - USB OTG和extcon驱动
    一、USBOTGUSB是主从模式的总线,主机称为Host,丛机称为Device(设备)。从机与从机之间、主机与主机之间(不包括USB4.0),不能互联。每次通信都是由主机发起,从机不能主动发起通信,只能被动的应答主机的请求。USBOTG(On-The-Go)是一个扩展的USB标准,允许USB设备之间直接进行通信,而无需通......
  • TienChin 渠道管理-配置校验失败信息
    新建ValidationMessages.properties:channel.name.notnull=渠道名称不能为空channel.type.notnull=渠道类型不能为空channel.status.notnull=渠道状态不能为空channel.type.invalid=渠道类型无效channel.status.invalid=渠道状态无效......
  • Docker-compose容器编排
    Docker容器编排的作用是管理和协调多个Docker容器的部署、启动、停止和扩展等操作。它可以确保应用程序在分布式环境中以可靠、高效和可伸缩的方式运行。1)安装步骤参考官网文档,选择对应的系统版本即可,官网提供两种安装方式请根据需要自行选择。https://docs.docker.com/desktop/in......
  • 无涯教程-JavaScript - CSCH函数
    描述CSCH函数返回以弧度指定的Angular的双曲余割值。语法CSCH(number)争论Argument描述Required/OptionalNumberTheangle(inradians)thatyouwanttocalculatethehyperboliccosecantof.RequiredNotes双曲余割值的等式为-$$csch\left(x\right)=\frac......