最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

pytest自動(dòng)化測(cè)試fixture的作用域?qū)嵗樞蚣翱捎眯?/h1>
 更新時(shí)間:2021年10月09日 14:43:19   作者:愛(ài)測(cè)試的高胖胖  
這篇文章主要介紹了pytest自動(dòng)化測(cè)試中fixture的作用域、實(shí)例化順序及可用性的詳解示例有需要的朋友可以借鑒參考下,希望能夠有所幫助

1. fixture的作用域

1.1 scope

通過(guò)前面文章的介紹,我們知道@pytest.fixture()有一個(gè)scope參數(shù),并且有五個(gè)作用域級(jí)別,這五個(gè)作用域級(jí)別的說(shuō)明總結(jié)如下:

注意:fixture是在測(cè)試首次請(qǐng)求時(shí)創(chuàng)建的,并基于它們的作用域被銷(xiāo)毀。

scope 說(shuō)明
function 默認(rèn)值,函數(shù)或方法級(jí)別被調(diào)用,當(dāng)函數(shù)執(zhí)行結(jié)束后,fixture則被銷(xiāo)毀
class 類(lèi)級(jí)別調(diào)用一次,當(dāng)類(lèi)中的最后一個(gè)測(cè)試函數(shù)執(zhí)行結(jié)束后,fixture則被銷(xiāo)毀
module 模塊級(jí)別(每一個(gè).py文件)調(diào)用一次,當(dāng)模塊中最后一個(gè)測(cè)試函數(shù)執(zhí)行結(jié)束后,fixture則被銷(xiāo)毀
package 包(一個(gè)文件夾下的.py文件)級(jí)別調(diào)用一次,當(dāng)包中最后一個(gè)測(cè)試函數(shù)執(zhí)行結(jié)束后,fixture則被銷(xiāo)毀
session 多個(gè)文件調(diào)用一次,當(dāng)多文件中最后一個(gè)測(cè)試函數(shù)執(zhí)行結(jié)束后,fixture則被銷(xiāo)毀

單看說(shuō)明,還是不太好理解的,所以下面我們通過(guò)示例來(lái)了解一下scope的用法。

示例1:

1.function:

演示代碼:

import pytest
@pytest.fixture()
def login():
    print('登陸操作')
    yield
    print('注銷(xiāo)操作')
class TestClass:
    def test_case1(self,login):
        print("TestClass:test_case1")

    def test_case2(self):
        print("TestClass:test_case2")
        

運(yùn)行結(jié)果:

在這里插入圖片描述

說(shuō)明:

演示代碼中,我們定義了一個(gè)fixture函數(shù)——login 和兩個(gè)測(cè)試函數(shù) test_case1test_case2。

裝飾器@pytest.fixture()沒(méi)有指定scope參數(shù),因此使用默認(rèn)值:function

test_case1test_case2TestClass類(lèi)中,且test_case1調(diào)用了login,test_case2未調(diào)用。

通過(guò)運(yùn)行結(jié)果,我們可以看出來(lái),scope=function的fixture——login,只在調(diào)用了它的test_case1這個(gè)測(cè)試函數(shù)前后執(zhí)行。test_case2未執(zhí)行。

2.class:

演示代碼:

import pytest
@pytest.fixture(scope='class')   #名為login的fixture,完成登陸和注冊(cè)操作
def login():
    print('登陸操作')
    yield
    print('注銷(xiāo)操作')
class TestClass1:
    def test_case1(self,login):  #調(diào)用了login
        print("TestClass1:test_case1")
    def test_case2(self):
        print("TestClass1:test_case2")
class TestClass2:
    def test_case1(self):
        print("TestClass2:test_case1")
    def test_case2(self,login):  #調(diào)用了login
        print("TestClass2:test_case2")
@pytest.mark.usefixtures("login")  #TestClass3這個(gè)類(lèi),使用usefixtures調(diào)用了login
class TestClass3:
    def test_case1(self):
        print("TestClass3:test_case1")
    def test_case2(self):
        print("TestClass3:test_case2")

運(yùn)行結(jié)果:

在這里插入圖片描述

說(shuō)明:

演示代碼中我們定義了一個(gè)fixture——login;三個(gè)測(cè)試類(lèi)——TestClass1、TestClass2TestClass3,這個(gè)三個(gè)測(cè)試類(lèi)中都定了兩個(gè)測(cè)試函數(shù)——test_case1test_case2。

對(duì)fixture函數(shù)我們聲明了其作用域——scope='class'
TestClass1中,只有test_case1調(diào)用了login
TestClass2中,只有test_case1調(diào)用了login;
TestClass3,我們使用@pytest.mark.usefixtures("login"),讓整個(gè)類(lèi)調(diào)用了login

查看運(yùn)行結(jié)果我們可以發(fā)現(xiàn):
TestClass1中,test_case1運(yùn)行前有”登陸操作“打印,并在test_case2執(zhí)行后有”注銷(xiāo)操作“顯打印。
TestClass2中,只有test_case2運(yùn)行前有”登陸操作“打印,并在test_case2執(zhí)行后有”注銷(xiāo)操作“打印。而test_case1執(zhí)行前后并無(wú)任何數(shù)據(jù)打印。
TestClass3則與Testclass1執(zhí)行后數(shù)據(jù)顯示一致。

TestClass1TestClass2結(jié)果的不同是由什么原因造成的呢?
官方文檔在介紹fixture的scope的時(shí)候,有這樣一句話(huà),上文中也有提到:fixture是在測(cè)試首次請(qǐng)求時(shí)創(chuàng)建的,并基于它們的作用域被銷(xiāo)毀。(Fixtures are created when first requested by a test, and are destroyed based on their scope。)
對(duì)于TestClass1,test_case1調(diào)用了login,因此會(huì)在test_case1執(zhí)行的時(shí)候,創(chuàng)建login,并在其執(zhí)行之前打印了”登陸操作“。又根據(jù)login的scope——class,在TestClass1的最后一個(gè)測(cè)試函數(shù)test_case2執(zhí)行后,根據(jù)login的功能打印”注銷(xiāo)操作“,并銷(xiāo)毀login。
對(duì)于TestClass2login是由test_case2調(diào)用的,而test_case1test_case2先執(zhí)行,所以test_case1執(zhí)行的時(shí)候login還未被調(diào)用,fixture未被創(chuàng)建。直到執(zhí)行test_case2時(shí),login才被創(chuàng)建并進(jìn)行了對(duì)應(yīng)的操作。
后面其他類(lèi)型的作用域示例中將不會(huì)在演示此種情況。

3.module:

演示代碼:

import pytest
@pytest.fixture(scope='module')   #名為login的fixture,完成登陸和注冊(cè)操作
def login():
    print('登陸操作')
    yield
    print('注銷(xiāo)操作')
@pytest.mark.usefixtures("login")
class TestClass1:
    def test_case1(self):
        print("TestClass1:test_case1")
    def test_case2(self):
        print("TestClass1:test_case2")
class TestClass2:
    def test_case1(self):
        print("TestClass2:test_case1")
    def test_case2(self):
        print("TestClass2:test_case2")


運(yùn)行結(jié)果:

在這里插入圖片描述

說(shuō)明:

演示代碼中,我們定義了:
一個(gè)fixture——login(),并且聲明其scope=”module“
兩個(gè)測(cè)試類(lèi)——TestClass1TestClass2;
兩個(gè)測(cè)試類(lèi)中分別定義了兩個(gè)測(cè)試函數(shù)——test_case1test_case2
TestClass1使用@pytest.mark.usefixtures("login")的方法,調(diào)用了login()

運(yùn)行結(jié)果顯示:
執(zhí)行時(shí),自第一個(gè)測(cè)試函數(shù)TestClass1中的test_case1調(diào)用login()時(shí),該fixture被創(chuàng)建,并且按照login()實(shí)現(xiàn)的功能打印"登陸操作",并在當(dāng)前模塊中(一個(gè).py文件)最后一個(gè)測(cè)試函數(shù)TestClass2中的test_case2執(zhí)行結(jié)束后,按照login()實(shí)現(xiàn)的功能打印"注銷(xiāo)操作",然后被銷(xiāo)毀。

4.package:

演示代碼:

首先看一下測(cè)試包目錄,新增一個(gè)conftest.py。里面所有的模塊都是上面的演示代碼。修改這些模塊里代碼,注釋調(diào)feature函數(shù),刪掉調(diào)用即可。

在這里插入圖片描述

conftest.py

import pytest
@pytest.fixture(scope='package',autouse=True)   #名為login的fixture,完成登陸和注冊(cè)操作
def login():
    print('登陸操作')
    yield
    print('注銷(xiāo)操作')
    

使用命令行運(yùn)行:

在這里插入圖片描述

運(yùn)行結(jié)果:

在這里插入圖片描述

說(shuō)明:
conftest.py中聲明了一個(gè)fixture——login(),并且設(shè)置scope='package'autouse=True。

使用命令行方式運(yùn)行test_scope這個(gè)測(cè)試包中的所有模塊。查看運(yùn)行結(jié)果,在test_scope中第一個(gè)測(cè)試函數(shù)調(diào)用login()的時(shí)候,login創(chuàng)建,并按照功能打印”登陸操作“。在test_scope中最后一個(gè)測(cè)試函數(shù)運(yùn)行結(jié)束后,按照login()功能打印出”注銷(xiāo)操作“,并銷(xiāo)毀login()。

5.session:

使用package的演示代碼,需改conftest.pylogin()scope='session',然后我們直接在終端中使用命令行運(yùn)行多個(gè)文件。

運(yùn)行以下命令:

在這里插入圖片描述

運(yùn)行結(jié)果:

在這里插入圖片描述

說(shuō)明:

使用命令行方式運(yùn)行test_scope這個(gè)測(cè)試包中的test_class.py和test_function.py。查看運(yùn)行結(jié)果,在test_class.py中第一個(gè)測(cè)試函數(shù)調(diào)用login()的時(shí)候,login創(chuàng)建,并按照功能打印”登陸操作“。在test_function.py中最后一個(gè)測(cè)試函數(shù)運(yùn)行結(jié)束后,按照login()功能打印出”注銷(xiāo)操作“,并銷(xiāo)毀login()

1.2 動(dòng)態(tài)作用域(Dynamic scope)

在某些情況下,我希望在不更改代碼的情況下更改feature的作用域。pytest的從5.2版本開(kāi)始,提供了動(dòng)態(tài)作用域的方法,來(lái)解決這種情況。

通過(guò)官方文檔的說(shuō)明,我們了解到,可以將一個(gè)可調(diào)用對(duì)象傳遞給scope來(lái)實(shí)現(xiàn)動(dòng)態(tài)作用域。這個(gè)可調(diào)用對(duì)象必須滿(mǎn)足以下三個(gè)條件:

1.這個(gè)可調(diào)用對(duì)象返回類(lèi)型需是string,且必須是有效的scope級(jí)別,即只能返回"function"、"class""module""package"、"session"中的一個(gè)。
2.在fixture定義期間,這個(gè)可調(diào)用對(duì)象只能被執(zhí)行一次,不能被多次調(diào)用。
3.這個(gè)可調(diào)用對(duì)象定義的時(shí)候,必須使用fixture_nameconfig作為參數(shù)。

下面通過(guò)示例給大家演示以下用法。

示例2:

演示代碼:

import pytest
def dynamic_fixture_scope(fixture_name,config):
    if config.getoption("-k",None):   
        return "function"
    return "class"
@pytest.fixture(scope=dynamic_fixture_scope,autouse=True)
def login():
    print('登陸操作')
    yield
    print('注銷(xiāo)操作')
class TestClass1:
    def test_A(self):
        print("這是TestClass1:test_A")
    def test_B(self):
        print("這是TestClass1:test_B")
class TestClass2:
    def test_A(self):
        print("這是TestClass2:test_A")

說(shuō)明:

dynamic_fixture_scope:用來(lái)管理fixture的作用域,這個(gè)函數(shù)按照pytest官方文檔的要求,帶有fixture_nameconfig兩個(gè)關(guān)鍵字作為參數(shù),并且實(shí)現(xiàn)下述功能:

1.當(dāng)用命令行運(yùn)行測(cè)試時(shí),運(yùn)行命令中帶有‘-k'參數(shù),則被調(diào)的fixture函數(shù)的作用域?yàn)?code>"function"

2.其余情況下,被調(diào)的fixture的函數(shù)為"class"。

login:一個(gè)使用動(dòng)態(tài)作用域方法的fixture,其scope=dynamic_fixture_scope。為了方便演示,autouse也被設(shè)置為True

下面我們分兩種情況來(lái)運(yùn)行看看:

1.帶參數(shù)-k運(yùn)行

運(yùn)行命令:我們只運(yùn)行測(cè)試名稱(chēng)中包含test_A的測(cè)試函數(shù)。

pytest -vs -k 'test_A' test_dynamicscope.py

運(yùn)行結(jié)果:

在這里插入圖片描述

通過(guò)運(yùn)行結(jié)果可以看到,當(dāng)命令行中出現(xiàn)-k參數(shù)的時(shí)候,loginscope確實(shí)是function級(jí)別的。兩個(gè)被選中的測(cè)試函數(shù)分別在不同的測(cè)試類(lèi)中,但是都調(diào)用了login。

2.無(wú)參數(shù)-k運(yùn)行

運(yùn)行命令:我們不帶參數(shù)-k運(yùn)行。

pytest -vs test_dynamicscope.py 

運(yùn)行結(jié)果:

在這里插入圖片描述

通過(guò)運(yùn)行結(jié)果可以看到,無(wú)-k參數(shù)的時(shí)候,loginscope確實(shí)是class級(jí)別的。

2. fixture的實(shí)例化順序

根據(jù)官方文檔,我們了解到影響fixture實(shí)例化順序的三個(gè)因素是:

1. 作用域(scope)
2. 依賴(lài)項(xiàng)
3. 自動(dòng)調(diào)用(autouse)

而fixture名稱(chēng)、測(cè)試函數(shù)名稱(chēng)以及定義它們的位置一般都不會(huì)影響執(zhí)行順序。

下面介紹一下這個(gè)三個(gè)因素是如何影響實(shí)例化順序的。

2.1 作用域級(jí)別高的fixture先執(zhí)行

我們直接使用官方文檔提供的示例來(lái)說(shuō)明。

示例3:

演示代碼:

import pytest
@pytest.fixture(scope="session")
def order():
    return []
@pytest.fixture
def func(order):
    order.append("function")
@pytest.fixture(scope="class")
def cls(order):
    order.append("class")
@pytest.fixture(scope="module")
def mod(order):
    order.append("module")
@pytest.fixture(scope="package")
def pack(order):
    order.append("package")
@pytest.fixture(scope="session")
def sess(order):
    order.append("session")
class TestClass:
    def test_order(self, func, cls, mod, pack, sess, order):
        assert order == ["session", "package", "module", "class", "function"]

運(yùn)行結(jié)果:

在這里插入圖片描述

說(shuō)明:
演示代碼中我們定義了:
六個(gè)fixture函數(shù):

order:scope為session級(jí)別,返回一個(gè)空l(shuí)ist。func: 調(diào)用了order,scope為默認(rèn)的function級(jí)別,并實(shí)現(xiàn)向order返回的列表中插入”function“的操作。cls:調(diào)用了order,scope為class級(jí)別,并實(shí)現(xiàn)向order返回的列表中插入”class“的操作。mod:調(diào)用了order,scope為module級(jí)別,并實(shí)現(xiàn)向order返回的列表中插入”module“的操作。pack:調(diào)用了order,scope為package級(jí)別,并實(shí)現(xiàn)向order返回的列表中插入”package“的操作。sess:調(diào)用了order,scope為session級(jí)別,并實(shí)現(xiàn)向order返回的列表中插入”session“的操作。

一個(gè)測(cè)試函數(shù):
test_order:主要目的是通過(guò)list中元素的順序來(lái)判斷是否按照預(yù)想的順序執(zhí)行fixture。

根據(jù)運(yùn)行結(jié)果顯示,測(cè)試斷言通過(guò),也就是fixture的執(zhí)行順序是按照我們預(yù)期的scope的級(jí)別由高到低去執(zhí)行的。

test_order調(diào)用fixture的順序是func, cls, mod, pack, sess, order,而實(shí)際執(zhí)行的順序是order, sess, pack, mod, cls, func。由此可見(jiàn),我們?cè)谡{(diào)用時(shí)定義的順序不會(huì)影響到fixture的實(shí)際執(zhí)行順序的。

官網(wǎng)執(zhí)行順序圖:

在這里插入圖片描述

其中sessorder的scope都是session級(jí)別的,但是因?yàn)?code>order是sess的依賴(lài)項(xiàng),所以會(huì)先調(diào)用order,這個(gè)一點(diǎn)正好我們下面要說(shuō)明。

2.2 fixture函數(shù)的依賴(lài)項(xiàng)先執(zhí)行

前面文章中有說(shuō)過(guò),fixture函數(shù)是可以調(diào)用另外一個(gè)fixture函數(shù)的。在執(zhí)行的時(shí)候,也是先執(zhí)行調(diào)用的那個(gè)fixture函數(shù)。舉了例子,fixture a 調(diào)用了fixture b,當(dāng)測(cè)試函數(shù)調(diào)用fixture a的時(shí)候,會(huì)先去執(zhí)行fixture b 然后再執(zhí)行fixture a,最后執(zhí)行測(cè)試函數(shù)。

這是因?yàn)閒ixture b 是fixture a 的依賴(lài)項(xiàng),fixture a 可能會(huì)需要fixture b提供一些條件才能正常被執(zhí)行。

下面我們來(lái)看一下官方文檔提供的一個(gè)例子,

示例4:

演示代碼:

import pytest
@pytest.fixture
def order():
    return []
@pytest.fixture
def a(order):
    order.append("a")
@pytest.fixture
def b(a, order):
    order.append("b")
@pytest.fixture
def c(a, b, order):
    order.append("c")
@pytest.fixture
def d(c, b, order):
    order.append("d")
@pytest.fixture
def e(d, b, order):
    order.append("e")
@pytest.fixture
def f(e, order):
    order.append("f")
@pytest.fixture
def g(f, c, order):
    order.append("g")
def test_order(g, order):
    assert order == ["a", "b", "c", "d", "e", "f", "g"]

運(yùn)行結(jié)果:

在這里插入圖片描述

說(shuō)明:

演示代碼中定義了八個(gè)fixture函數(shù)和一個(gè)測(cè)試函數(shù),其中:
fixture函數(shù)有:orde、a、bc、d、ef、g
測(cè)試函數(shù)有:test_order

a調(diào)用了order;
b調(diào)用了a, order;
c調(diào)用了a, b, order
d調(diào)用了c, b, order;
f調(diào)用了e, order
g調(diào)用了f, c, order;
test_order調(diào)用了g、order。

我們來(lái)整理以上所有函數(shù)的依賴(lài)關(guān)系,他們之間的依賴(lài)關(guān)系如圖所示:

在這里插入圖片描述

之前文章也有說(shuō)過(guò),在同一次測(cè)試執(zhí)行過(guò)程中,fixture是可以被多次調(diào)用的,但是不會(huì)被多次執(zhí)行。執(zhí)行一次后,fixture的實(shí)例對(duì)象和返回值會(huì)存在緩存中,下次再被調(diào)用的時(shí)候是直接從緩存中獲取的。

所以上面的順序我們可以再簡(jiǎn)化一下:

在這里插入圖片描述

執(zhí)行完所有依賴(lài)的fixture函數(shù)后,我們得到的order的結(jié)果為:['a','b','c','d','e'],因此測(cè)試斷言通過(guò)。

2.3 自動(dòng)使用的fixture在其作用域內(nèi)首先執(zhí)行

根據(jù)官方文檔的說(shuō)明,我們可以得到一下兩點(diǎn)重要內(nèi)容:

1.當(dāng)測(cè)試函數(shù)調(diào)用的fixture的作用域級(jí)別都一樣,那么會(huì)首先調(diào)用自動(dòng)使用的fixture。

示例5:

import pytest
@pytest.fixture
def order():
    return []
@pytest.fixture
def func(order):
    order.append("function")
@pytest.fixture(autouse=True) #修改cls為自動(dòng)使用fixture
def cls(order):
    order.append("class")
@pytest.fixture
def mod(order):
    order.append("module")
@pytest.fixture
def pack(order):
    order.append("package")
@pytest.fixture
def sess(order):
    order.append("session")
class TestClass:
    def test_order(self, func, cls, mod, pack, sess, order):
        print(order)
        assert order == ["session", "package", "module", "class", "function"]

運(yùn)行結(jié)果:

在這里插入圖片描述

說(shuō)明:

我們把示例3的代碼拿過(guò)來(lái)修改一下,把所有fixture的scope都改為function級(jí)別,并且對(duì)cls試著autouse=True。
test_order請(qǐng)求fixture的順序是:func, cls, mod, pack, sess。

當(dāng)scope級(jí)別一樣的時(shí)候,且無(wú)依賴(lài)關(guān)系的時(shí)候,fixture的執(zhí)行順序應(yīng)該與調(diào)用順序一致,也應(yīng)該是func, cls, mod, pack, sess。但是實(shí)際運(yùn)行的結(jié)果卻是['class', 'function', 'module', 'package', 'session']。由此可以判斷出,在scope一致且無(wú)依賴(lài)的情況下,自動(dòng)執(zhí)行的fixture是最先被執(zhí)行的。

2.對(duì)一個(gè)autouse的fixture A來(lái)說(shuō),若調(diào)用了非autouse的fixture B,那么對(duì)于調(diào)用了fixture A的測(cè)試函數(shù)來(lái)說(shuō),fixture B也相當(dāng)于是autouse的。

我們?cè)賮?lái)看一下官方給的一個(gè)示例。

示例6:

演示代碼:

import pytest
@pytest.fixture
def order():
    return []
@pytest.fixture
def a(order):
    order.append("a")
@pytest.fixture
def b(a, order):
    order.append("b")
@pytest.fixture(autouse=True)
def c(b, order):
    order.append("c")
@pytest.fixture
def d(b, order):
    order.append("d")
@pytest.fixture
def e(d, order):
    order.append("e")
@pytest.fixture
def f(e, order):
    order.append("f")
@pytest.fixture
def g(f, c, order):
    order.append("g")
def test_order_and_g(g, order):
    assert order == ["a", "b", "c", "d", "e", "f", "g"]

說(shuō)明:

演示代碼中定義了八個(gè)fixture函數(shù)和一個(gè)測(cè)試函數(shù),其中:
fixture函數(shù)有:orde、a、b、c、d、e、f、g
測(cè)試函數(shù)有:test_order

a調(diào)用了order;
b調(diào)用了a, order;
c調(diào)用了 b, order,且是自動(dòng)使用fixture;
d調(diào)用了 b, order;
f調(diào)用了e, order;
g調(diào)用了f, c, order
test_order調(diào)用了g、order

若c是非自動(dòng)使用的fixture,代碼中fixture的一個(gè)執(zhí)行順序是什么樣的呢?

下圖是運(yùn)行結(jié)果:

在這里插入圖片描述

根據(jù)上面的運(yùn)行結(jié)果和下面的順序圖,我們可以看到,除了g調(diào)用了c之外,其他函數(shù)都沒(méi)有調(diào)用c,而g也調(diào)用了f,所以現(xiàn)在還不清楚c應(yīng)該在d、e、f之前還是之后執(zhí)行。對(duì)c來(lái)說(shuō)他只需在b之后、g之前執(zhí)行即可。而實(shí)際運(yùn)行結(jié)果,c是在d、e、f之后和g之前執(zhí)行的。

對(duì)于pytest來(lái)說(shuō),fixture的執(zhí)行順序就是不明確,這種情況很可能會(huì)影響測(cè)試函數(shù)的執(zhí)行行為,影響了測(cè)試結(jié)果。

在這里插入圖片描述

所以,我們需要明確fixture的執(zhí)行順序。

當(dāng)我們使c為自動(dòng)使用fixture時(shí),這個(gè)順序又會(huì)發(fā)生什么變化呢?

下圖為運(yùn)行結(jié)果:

在這里插入圖片描述

根據(jù)上圖的運(yùn)行結(jié)果和下圖的順序圖,我們可以看出來(lái),當(dāng)自動(dòng)使用c后,它的執(zhí)行優(yōu)先級(jí)就比d要高,所以可以保證c是在d之前執(zhí)行的。這樣使執(zhí)行順序明確了。

在這里插入圖片描述

當(dāng)c是自動(dòng)使用的fixture后,根據(jù)fixture函數(shù)的依賴(lài)項(xiàng)先執(zhí)行這一規(guī)則,c所依賴(lài)的b、b所依賴(lài)的a和a所依賴(lài)的order都會(huì)被執(zhí)行。這樣對(duì)于調(diào)用了c的g來(lái)說(shuō),order、a、b也相當(dāng)于是自動(dòng)使用的fixture了,但是當(dāng)有其他fixture調(diào)用order、a、b時(shí),order、a、b仍然保持自己的特性。

本節(jié)總結(jié)

我們來(lái)總結(jié)一下fixture實(shí)例化順序的一個(gè)規(guī)則:

1.fixture的scope級(jí)別越高,那么它執(zhí)行的優(yōu)先級(jí)越高。優(yōu)先級(jí)為:session>package>module>class>function

2.fixture如果存在依賴(lài)項(xiàng),那么它所依賴(lài)的fixture函數(shù)會(huì)先被執(zhí)行。

3.同scope級(jí)別fixture中,自動(dòng)使用的fixture會(huì)最先執(zhí)行;若該fixture存在依賴(lài)項(xiàng),則對(duì)于調(diào)用了fixture的測(cè)試函數(shù)來(lái)說(shuō),這些依賴(lài)項(xiàng)也可以看做是自動(dòng)使用的。

4.我們?cè)诰幋a的時(shí)候最好可以依照以上規(guī)則為pytest提供一個(gè)清晰的fixture執(zhí)行順序,以免影響測(cè)試函數(shù)的行為和測(cè)試結(jié)果。

3. fixture的可用性

對(duì)于測(cè)試函數(shù)來(lái)說(shuō),能夠調(diào)用那些fixture,是由fixture定義的位置決定。

1.當(dāng)fixture定義在一個(gè)測(cè)試類(lèi)中時(shí),只有該類(lèi)中的測(cè)試函數(shù)可調(diào)用此fixture,其他測(cè)試函數(shù)無(wú)法調(diào)用該fixture。當(dāng)測(cè)試函數(shù)在模塊的全局范圍內(nèi)定,則模塊下的所有測(cè)試函數(shù)都可以調(diào)用它。該特點(diǎn)與全局變量和局部變量相似。

示例7:

演示代碼:

import pytest
class TestClass1:
    @pytest.fixture()
    def login(self):
        print("login")
    def test_case1(self,login):
        print("TestClass1::test_case1")
class TestClass2:
    def test_case2(self,login):
        print("test_case2")

運(yùn)行結(jié)果:

在這里插入圖片描述

說(shuō)明:

演示代碼中定義了兩個(gè)測(cè)試類(lèi):TestClass1TestClass2。
TestClass1中定義了一個(gè)fixture——login,和測(cè)試函數(shù)test_case1,test_case1有調(diào)用login
TestClass1中定義了一個(gè)測(cè)試函數(shù)test_case2,test_case2有調(diào)用login。

通過(guò)運(yùn)行結(jié)果我們可以看到,與login在同一測(cè)試類(lèi)中的test_case1成功調(diào)用了login,但是TestClass2test_case2調(diào)用login的時(shí)候報(bào)錯(cuò)了,報(bào)錯(cuò)原因:未發(fā)現(xiàn)fixture函數(shù)“l(fā)ogin”。

2.conftest.py中定義的fixture,可以被同目錄下的所有模塊中定義的測(cè)試函數(shù)調(diào)用。

示例8:

演示代碼:

test_availability/conftest.py:

import pytest
@pytest.fixture()
def login():
    print("login")
    

test_availability/test_availability.py:

class TestClass1:
    def test_case1(self,login):
        print("TestClass1::test_case1")
class TestClass2:
    def test_case2(self,login):
        print("test_case2")

運(yùn)行結(jié)果:

在這里插入圖片描述

說(shuō)明:

我們?cè)趖est_availability目錄下創(chuàng)建了一個(gè)conftest.py,并且定義了一個(gè)fixture——login。
在test_availability.py中,我們定義了兩個(gè)測(cè)試函數(shù)test_case1test_case1,兩個(gè)測(cè)試函數(shù)都調(diào)用了login

查看運(yùn)行結(jié)果,測(cè)試函數(shù)都成功調(diào)用了login。

3.如果安裝的第三方插件提供了fixture,任何測(cè)試函數(shù)都可以正常使用,無(wú)需考慮位置因素。

文末說(shuō)明:
以上內(nèi)容是我在閱讀pytest官方文檔后,依照個(gè)人理解進(jìn)行整理。內(nèi)容可能會(huì)有理解錯(cuò)誤之處,歡迎大家留言指正。謝謝

更多關(guān)于fixture作用域?qū)嵗樞蚣翱捎眯缘馁Y料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 手把手帶你用Python實(shí)現(xiàn)一個(gè)計(jì)時(shí)器

    手把手帶你用Python實(shí)現(xiàn)一個(gè)計(jì)時(shí)器

    雖然Python是一種有效的編程語(yǔ)言,但純Python程序比C、Rust和Java等編譯語(yǔ)言中的對(duì)應(yīng)程序運(yùn)行得更慢,為了更好地監(jiān)控和優(yōu)化Python程序,今天將為大家介紹如何使用?Python?計(jì)時(shí)器來(lái)監(jiān)控程序運(yùn)行的速度,以便正對(duì)性改善代碼性能
    2022-06-06
  • python數(shù)據(jù)結(jié)構(gòu)之線(xiàn)性表的順序存儲(chǔ)結(jié)構(gòu)

    python數(shù)據(jù)結(jié)構(gòu)之線(xiàn)性表的順序存儲(chǔ)結(jié)構(gòu)

    這篇文章主要為大家詳細(xì)介紹了python數(shù)據(jù)結(jié)構(gòu)之線(xiàn)性表的順序存儲(chǔ)結(jié)構(gòu),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • python3常用的數(shù)據(jù)清洗方法(小結(jié))

    python3常用的數(shù)據(jù)清洗方法(小結(jié))

    這篇文章主要介紹了python3常用的數(shù)據(jù)清洗方法(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • python通過(guò)cython加密代碼

    python通過(guò)cython加密代碼

    這篇文章主要介紹了python通過(guò)cython實(shí)現(xiàn)加密的示例代碼,幫助大家加密自己的python代碼,提高安全性,感興趣的朋友可以參考下
    2020-12-12
  • 利用python實(shí)現(xiàn)漢字轉(zhuǎn)拼音的2種方法

    利用python實(shí)現(xiàn)漢字轉(zhuǎn)拼音的2種方法

    這篇文章主要給大家介紹了關(guān)于如何利用python實(shí)現(xiàn)漢字轉(zhuǎn)拼音的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Python中關(guān)于字典的常規(guī)操作范例以及介紹

    Python中關(guān)于字典的常規(guī)操作范例以及介紹

    今天小編幫大家簡(jiǎn)單介紹下Python的一種數(shù)據(jù)結(jié)構(gòu): 字典,字典是 Python 提供的一種常用的數(shù)據(jù)結(jié)構(gòu),它用于存放具有映射關(guān)系的數(shù)據(jù),通讀本篇對(duì)大家的學(xué)習(xí)或工作具有一定的價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Python UnicodeEncodeError: ''gbk'' codec can''t encode character 解決方法

    Python UnicodeEncodeError: ''gbk'' codec can''t encode chara

    這篇文章主要介紹了Python UnicodeEncodeError: 'gbk' codec can't encode character 解決方法,需要的朋友可以參考下
    2015-04-04
  • Python檢查端口是否打開(kāi)的七種方法總結(jié)

    Python檢查端口是否打開(kāi)的七種方法總結(jié)

    在信息安全領(lǐng)域,端口掃描是一項(xiàng)常見(jiàn)的技術(shù),用于逐個(gè)檢測(cè)目標(biāo)主機(jī)上的端口是否開(kāi)放,這篇文章主要給大家介紹了關(guān)于Python檢查端口是否打開(kāi)的七種方法總結(jié),需要的朋友可以參考下
    2023-12-12
  • Python工程師面試題 與Python Web相關(guān)

    Python工程師面試題 與Python Web相關(guān)

    這篇文章主要為大家分享了Python工程師面試題,面試題的內(nèi)容主要與Python Web相關(guān),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-01-01
  • 利用Python編寫(xiě)一個(gè)Windows桌面小組件

    利用Python編寫(xiě)一個(gè)Windows桌面小組件

    這篇文章主要為大家詳細(xì)介紹了如何讓ChatGPT按要求編寫(xiě)Python代碼實(shí)現(xiàn)一個(gè)Windows桌面小組件,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2023-06-06

最新評(píng)論

蒲江县| 讷河市| 丹阳市| 陈巴尔虎旗| 漠河县| 堆龙德庆县| 绩溪县| 泾川县| 镇平县| 镇平县| 台湾省| 浪卡子县| 东辽县| 克拉玛依市| 清徐县| 扬中市| 鹤山市| 宁陵县| 米泉市| 濉溪县| 喜德县| 温州市| 呈贡县| 老河口市| 万全县| 淮阳县| 卫辉市| 丰都县| 芒康县| 图木舒克市| 美姑县| 榆树市| 兴安盟| 乐都县| 那坡县| 盐源县| 辽源市| 桐柏县| 托里县| 犍为县| 临清市|