学习pytest的第三天-----fixture的使用方式+参数介绍

引入

我们之前学过pytest中的“setup”和“teardown”,可以实现测试用例的前后执行操作。其实pytest中还有另外一种方式——fixture。与setup和teardown相比,fixture使用起来更加灵活,更加炫酷。话不多说,进入正文。

@pytest.fixtrue()的使用方式

方式一:测试用例传入前置函数名

pytest.fixtrue标签是pytest的内置标签,被该标签标记的函数可以作为其他测试用例的前置函数,类似于“setup”。

如何使用该标签呢,我们先来看一下小栗子:在下面的代码中,我们显示导入了pytest包,然后定义了myfixture函数,注意我们在函数上面用了@pytest.fixture()标签。在下面的测试类中的三个测试方法,我们在第二个测试方法中传入了fixtrue标签标记的函数名。这样,在运行第二个测试方法之前便会运行该前置函数,另外两个函数我们未传入函数名便不会执行。

#文件名是test_firstFile.py
#coding=utf-8
import pytest

@pytest.fixture()
def myfixture():
    print("执行myfixture")

class Test_firstFile():

    def test_one(self):
        print("执行test_one")
        assert 1+1==3

    def test_two(self,myfixture):
        print("执行test_two")
        assert 1==1

    def test_three(self):
        print("执行test_three")
        assert 1+1==2

if __name__=="__main__":
    pytest.main(["-s","test_firstFile.py"])

运行结果如图:
运行结果图1

方式二:通过conftest.py文件

如果我们有很多个前置函数,写在各个py文件中是不很乱?再或者说,我们很多个py文件想要使用同一个前置函数该怎么办?这也就是conftest.py的作用。
使用conftest.py的规则:

  1. conftest.py这个文件名是固定的,不可以更改
  2. conftest.py与运行用例在同一个包下,并且该包中有__init__.py文件
  3. 使用的时候不需要导入conftest.py,会自动寻找

来看个小荔枝:我们新建了一个conftest.py文件,将前置函数的声明写在里面;在同一包下又新建了一个测试模块,在测试方法中传入了conftest.py中声明的前置函数名。

#文件名是conftest.py
#conding=utf-8

import pytest

@pytest.fixture()
def myfixture():
    print("执行myfixture")
#文件名是test_firstFile.py
#coding=utf-8
import pytest

class Test_firstFile():

    def test_one(self,myfixture):
        print("执行test_one")
        assert 1+2==3

    def test_two(self,myfixture):
        print("执行test_two")
        assert 1==1

    def test_three(self,myfixture):
        print("执行test_three")
        assert 1+1==2

if __name__=="__main__":
    pytest.main(["-s","test_firstFile.py"])

运行结果如下图:
执行结果图2

我们在conftest.py中声明完前置函数后,在测试模块中除了使用传入函数名的方式,还可以使用@pytest.mark.userfixtures()装饰器

举个小荔枝:声明前置函数的过程和上面一样;我们在每个测试方法上都加了@pytest.mark.userfixtures()装饰器,传入了前置函数名作为参数;运行结果和上图一样便不再展示。

#文件名是test_firstFile.py
#coding=utf-8
import pytest

class Test_firstFile():

    @pytest.mark.usefixtures("myfixture")
    def test_one(self):
        print("执行test_one")
        assert 1+2==3

    @pytest.mark.usefixtures("myfixture")
    def test_two(self):
        print("执行test_two")
        assert 1==1

    @pytest.mark.usefixtures("myfixture")
    def test_three(self):
        print("执行test_three")
        assert 1+1==2

if __name__=="__main__":
    pytest.main(["-s","test_firstFile.py"])

如果你想要模块中的每个测试用例都调用该固件,你也可以使用pytestmark标记:如下代码(注意pytestmark变量名不可更改)

#文件名是test_firstFile.py
#coding=utf-8
import pytest

pytestmark=pytest.mark.usefixtures("myfixture")

class Test_firstFile():

    def test_one(self):
        print("执行test_one")
        assert 1+2==3

    def test_two(self):
        print("执行test_two")
        assert 1==1

    def test_three(self):
        print("执行test_three")
        assert 1+1==2

if __name__=="__main__":
    pytest.main(["-s","test_firstFile.py"])

补充说明一下conftest.py文件的作用域是当前包内(包括子包);如果函数调用固件优先从当前测试类中寻找,然后是模块(.py文件)中,接着是当前包中寻找(conftest.py中),如果没有再找父包直至根目录;如果我们要声明全局的conftest.py文件,我们可以将其放在根目录下

方式三:通过autouse参数

如果我们想要模块中每个测试函数都是用声明好的前置函数,每个测试函数都传入参数或添加装饰器,是不是很不方便?这时我们可以使用@pytest.fixture()中的参数autouse(自动使用),将其设为true(默认为false),这样每个测试函数都会自动调用该前置函数了。

再来吃了小荔枝:

#文件名是test_firstFile.py
#coding=utf-8
import pytest

@pytest.fixture(autouse="true")
def myfixture():
    print("执行myfixture")

class Test_firstFile():

    def test_one(self):
        print("执行test_one")
        assert 1+2==3

    def test_two(self):
        print("执行test_two")
        assert 1==1

    def test_three(self):
        print("执行test_three")
        assert 1+1==2

if __name__=="__main__":
    pytest.main(["-s","test_firstFile.py"])

运行结果如下图:
执行结果图3

@pytest.fixtrue()的参数

scope

scope参数有四种选择:function(测试函数级别),class(测试类级别),module(测试模块“.py”级别),session(多个文件级别)。默认是function级别

function级别也就是默认级别,在测试用例之前执行一次。我们的第一个小例子就是这种级别,便不再举例子。

class级别:我们在使用标签的时候将scope设置为class,之后再每个测试方法中都将前置函数名传入。

#文件名是test_firstFile.py
#coding=utf-8
import pytest

@pytest.fixture(scope="class")
def myfixture():
    print("执行myfixture")

class Test_firstFile():

    def test_one(self,myfixture):
        print("执行test_one")
        assert 1+2==3

    def test_two(self,myfixture):
        print("执行test_two")
        assert 1==1

    def test_three(self,myfixture):
        print("执行test_three")
        assert 1+1==2

if __name__=="__main__":
    pytest.main(["-s","test_firstFile.py"])

运行结果如图:可以观察到myfixture只在第一个测试方法前执行了一次。
执行结果4
如果我们不在第一测试方法中传入函数名,而在第二个和第三个方法中传入,那么执行结果是会在第二个方法之前执行myfixture前置函数,第三个函数便不会执行。也就是说,在一个测试类中该前置函数只会执行一次,并且是在传入函数名的测试方法中的第一个执行的测试方法之前执行

module级别:我们在使用标签的时候将scope设置为module,之后再每个测试函数和测试方法中都将前置函数名传入。

#文件名是test_firstFile.py
#coding=utf-8
import pytest

@pytest.fixture(scope="module")
def myfixture():
    print("执行myfixture")

def test_zero(myfixture):
    print("执行test_zero")
    assert 2-1==1

class Test_firstFile():

    def test_one(self,myfixture):
        print("执行test_one")
        assert 1+2==3

    def test_two(self,myfixture):
        print("执行test_two")
        assert 1==1

    def test_three(self,myfixture):
        print("执行test_three")
        assert 1+1==2

if __name__=="__main__":
    pytest.main(["-s","test_firstFile.py"])

执行结果如图:在测试模块(.py文件)中只执行一次,并且是在传入函数名的测试用例中的第一个执行的测试用例之前执行
执行结果图5
session级别:设置方式和module级别的设置方式一样,需要注意的是session级别一般都是多个.py文件共用,所以要前置函数的声明一般在conftest.py中。其作用在多个测试模块(.py文件)中只执行一次,并且是在传入函数名的测试用例中的第一个执行的测试用例之前执行。这里就先不举例子了。

autouse

在上面第三种使用方式中已经用到过该参数,该参数的意思自动调用默认是false。这里补充的是:如果前置函数的scope是function或者未设置,则每个测试用例都会自动调该前置函数;如果设置的class,则会在测试类中的第一个测试方法前自动调该前置函数;如果设置的是module,则会在测试模块中的第一个测试函数前自动调该前置函数;session级别同理

params

params参数可以实现前置函数的参数化,调用前置函数的测试用例可以根据前置函数不同的参数执行多次

我们来看一下小荔枝:我们先是在fixture标签中的params参数传入了列表类型的参数列表;我们又在前置函数中传入了request参数;最后在测试函数中我们通过request.param来表示参数(参数列表中的每个值)

#test_Pytest.py文件
#coding=utf-8

import pytest

@pytest.fixture(params=["参数1","参数2"])
def preMethod(request):
    print ("执行testPytest里的前置函数,%s" % request.param)

import pytest

def test_one(preMethod):
        print("test_one方法执行")
        assert 1==1

def test_two():
        print("test_two方法执行")
        assert "o" in "love"

def test_three():
        print("test_three方法执行")
        assert 3-2==1

if __name__=="__main__":
    pytest.main(['-s','test_Pytest.py'])

运行结果如图:可以看到调用该前置函数(test_one)的测试方法执行了两次,每次的前置的参数依次是params参数列表中的值。
执行结果图6

ids

如果我们通过params参数将前置函数参数化,则会根据参数的的不同执行多个前置函数,这时我们就可以他通过ids这个参数将区别不同的前置函数。这里先不做介绍(因为我还不知道具体有什么用,哈哈哈)

参考:
https://www.cnblogs.com/yoyoketang/tag/pytest/(感谢作者)

  • 17
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值