pytest之fixture

fixture在pytest中是用来实现setup和teardown的方法,是在测试用例执行前后执行的函数,当有需要在测试用例执行前或执行后执行某些动作的场景时使用fixture来处理

一、fixture的调用方式:

fixture有三种调用方式

1、函数或类直接将fixture的函数名作为参数传入,调用多个用逗号隔开

import pytest

@pytest.fixture()
def login():
    print '登录'

@pytest.fixture()
def start():
    print '开始'
class TestIndex():
    def test_myself(self,login,start):
        print '示例'

运行结果:

2、使用装饰器@pytest.mark.usefixture()修饰

调用多个时,可以只修饰一次,用逗号分割fixture函数名

import pytest

@pytest.fixture()
def login():
    print '登录'

@pytest.fixture()
def start():
    print '开始'
class TestIndex():
    @pytest.mark.usefixtures('login','start')
    def test_myself(self):
        print '示例'

运行结果:

 

也可以修饰多个,需要注意的是执行顺序是从下往上,有执行顺序要求时想先执行的要往下写

import pytest

@pytest.fixture()
def login():
    print '登录'

@pytest.fixture()
def start():
    print '开始'
class TestIndex():
    @pytest.mark.usefixtures('login')
    @pytest.mark.usefixtures('start')
    def test_myself(self):
        print '示例'

运行结果:

3、@pytest.fixture(autouse=True)自动调用,范围跟着scope走

import pytest

@pytest.fixture(autouse=True,scope='function')
def start():
    print '开始'
class TestIndex():
    def test_myself(self):
        print '示例'

    def test_class(self):
        print '示例1'

运行结果:

 可以看到函数、类都没有实际调用fixture,是自动调用的,作用范围是fixture设置的scope范围

4、使用装饰器@pytest.mark.parametrize(argnames=fixture函数名,indirect=True)

import pytest

@pytest.fixture()
def login():
    print '登录'

@pytest.fixture()
def start():
    print '开始'
class TestIndex():
    @pytest.mark.parametrize('login,start',[('a','b')],indirect=True)
    def test_myself(self,login,start):
        print '示例'

运行结果:

这种调用方式是当你需要用fixture处理一些数据并返回一个返回值时使用,如果只是单纯的调用不推荐用这种方式

二、fixture参数介绍:

1、scope

fixture的作用域,fixture有四个作用域分别为session(会话级)、module(模块级)、class(类级)、function(函数级),作用域都是从开始引用fixture的位置开始

接下来从低到高依次说明:

代码先放在这里:
 

import pytest

@pytest.fixture(autouse=True,scope='function')
def login():
    print '登录'
class TestIndex():
    def test_myself(self):
        print '示例'

    def test_class(self):
        print '示例1'

class TestIn():
    def test_myself(self):
        print '示例2'

1-1、function:

引用了fixture的函数都会执行一次fixture

范围是function,看到每个函数都执行了一次fixture

1-2、class

引用了fixture的类,在整个类只执行一次

@pytest.fixture(autouse=True,scope='class')   #scope范围为class

 每个class执行了一次

1-3、module

引用了fixture的模块,在整个模块只执行一次

@pytest.fixture(autouse=True,scope='module')     #scope范围为module

 一个文件只执行了一次

1-4、session

引用了fixture的会话,是指当前运行的整个项目,只执行一次

2、ids

用例标识ID,与params配合使用,一一对应

3、params

此参数是fixture的可选形参,支持传入列表,默认为None

每个params值fixture都会调用一次,类似for循环,与@pytest.mark.parametrize()的argvalues用法一致

可与ids一起使用,类似@pytest.mark.parametrize()的argvalues和argnames的关系

params在fixture中的使用要用pytest自带的request来调用:request.param

import pytest

@pytest.fixture(params=['张三'])
def login(request):
    user = request.param           #  使用pytest自带的request.param来调用fixture的params
    print user
class TestIndex():
    def test_myself(self,login):
        print '示例'

运行结果:

4、name

fixture的重命名,若使用name重命名后,则调用fixture必须使用新的命名,否则报错

import pytest

@pytest.fixture(name='start')
def login():
    print '登录'
class TestIndex():
    def test_myself(self,start):    # 这里调用必须使用新命名
        print '示例'

运行结果:

import pytest

@pytest.fixture(name='start')
def login():
    print '登录'
class TestIndex():
    def test_myself(self,login):          # 如果不使用新命名,就会报错
        print '示例'

运行结果:

5、autouse

默认为False,若设置为True,则以scope的作用域为执行单位,自动调用fixture

具体前面有说明,这里不再复述

三、在fixture中前置后置方法用yield关键字区分

1、写在yield前面的程序为前置方法,前置会在执行测试用例之前执行,只实现前置时可省略yield

import pytest

@pytest.fixture()
def setup():
    print '前置执行'    #  此处只前置,省略yield

class TestIndex():
    def test_myself(self,setup):
        print '用例'

运行结果:
  

2、写在yield后面的程序为后置方法,后置会在测试用例执行结束后执行

import pytest

@pytest.fixture()
def setup():
    yield
    print '后置执行'

class TestIndex():
    def test_myself(self,setup):
        print '用例'

运行结果:

3、若有返回值,若需实现后置则必需有yield关键字,否则yield或return都可以

yield返回:

import pytest

@pytest.fixture()
def setup():
    msg = '用例'
    yield msg
    print '后置执行'
class TestIndex():
    def test_myself(self,setup):
        print setup

运行结果:

 return返回:

import pytest

@pytest.fixture()
def setup():
    print '前置执行'
    msg = '用例'
    return msg

class TestIndex():
    def test_myself(self,setup):
        print setup

运行结果:

四、conftest.py

这个文件是pytest的配置文件,不需要import导入,pytest会自动识别,可以创建在根目录,也可以创建在用例目录下,建在哪个目录下它的作用范围就是哪个目录,需要注意conftest.py一定要与需要调用它的用例文件在同级或上级目录下,否则在下级或与用例所在目录同级的其他目录下是不生效的

该文件主要存放fixture,统一管理前置后置条件

目录层级:

package
    testcase
        test_index.py
    conftest.py

conftest.py

import pytest

@pytest.fixture()
def setup():
    print '前置执行'
    msg = '用例'
    return msg

test_index.py

class TestIndex():
    def test_myself(self,setup):
        print setup

运行结果:

fixture函数命名建议不要test_开头,与测试用例区分开

五、pytest搜索fixture的顺序

1、优先搜索测试函数所在模块

2、然后搜索模块所在目录下的conftest.py

3、找不到在继续逐层向上层搜索conftest.py

这里顺便提一下笔者在刚接触pytest的fixture时曾遇到一个坑,那个时候是从unittest换到pytest,当时因为知道pytest与unittest可以兼容,所以就没有去掉unittest的代码,而是在其基础上使用pytest,后来在用到fixture的时候就发现fixture不能正确使用,只有写在同一个文件下才可以调用fixture,而且怎么都拿不到fixture的返回值,fixture的大部分实现都做不到,后来查阅资料发现是因为当中混杂了unittest导致的,后来把unittest全部去掉就可以正常使用fixture了

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值