1. fixture的作用域
1.1 scope
通過前面文章的介紹,我們知道@pytest.fixture()有一個(gè)scope參數(shù),并且有五個(gè)作用域級(jí)別,這五個(gè)作用域級(jí)別的說明總結(jié)如下:
注意:fixture是在測(cè)試首次請(qǐng)求時(shí)創(chuàng)建的,并基于它們的作用域被銷毀。
scope | 說明 |
---|---|
function | 默認(rèn)值,函數(shù)或方法級(jí)別被調(diào)用,當(dāng)函數(shù)執(zhí)行結(jié)束后,fixture則被銷毀 |
class | 類級(jí)別調(diào)用一次,當(dāng)類中的最后一個(gè)測(cè)試函數(shù)執(zhí)行結(jié)束后,fixture則被銷毀 |
module | 模塊級(jí)別(每一個(gè).py文件)調(diào)用一次,當(dāng)模塊中最后一個(gè)測(cè)試函數(shù)執(zhí)行結(jié)束后,fixture則被銷毀 |
package | 包(一個(gè)文件夾下的.py文件)級(jí)別調(diào)用一次,當(dāng)包中最后一個(gè)測(cè)試函數(shù)執(zhí)行結(jié)束后,fixture則被銷毀 |
session | 多個(gè)文件調(diào)用一次,當(dāng)多文件中最后一個(gè)測(cè)試函數(shù)執(zhí)行結(jié)束后,fixture則被銷毀 |
單看說明,還是不太好理解的,所以下面我們通過示例來了解一下scope的用法。
示例1:
1.function:
演示代碼:
import pytest @pytest.fixture() def login(): print('登陸操作') yield print('注銷操作') class TestClass: def test_case1(self,login): print("TestClass:test_case1") def test_case2(self): print("TestClass:test_case2")
運(yùn)行結(jié)果:
說明:
演示代碼中,我們定義了一個(gè)fixture函數(shù)——login
和兩個(gè)測(cè)試函數(shù) test_case1
和test_case2
。
裝飾器@pytest.fixture()
沒有指定scope
參數(shù),因此使用默認(rèn)值:function
。
test_case1
和test_case2
在TestClass
類中,且test_case1
調(diào)用了login
,test_case2
未調(diào)用。
通過運(yùn)行結(jié)果,我們可以看出來,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('注銷操作') 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è)類,使用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é)果:
說明:
演示代碼中我們定義了一個(gè)fixture——login
;三個(gè)測(cè)試類——TestClass1
、TestClass2
和TestClass3
,這個(gè)三個(gè)測(cè)試類中都定了兩個(gè)測(cè)試函數(shù)——test_case1
和test_case2
。
對(duì)fixture函數(shù)我們聲明了其作用域——scope='class'
。TestClass1
中,只有test_case1
調(diào)用了login
;TestClass2
中,只有test_case1
調(diào)用了login
;TestClass3
,我們使用@pytest.mark.usefixtures("login")
,讓整個(gè)類調(diào)用了login
。
查看運(yùn)行結(jié)果我們可以發(fā)現(xiàn):TestClass1
中,test_case1
運(yùn)行前有”登陸操作“打印,并在test_case2
執(zhí)行后有”注銷操作“顯打印。TestClass2
中,只有test_case2
運(yùn)行前有”登陸操作“打印,并在test_case2
執(zhí)行后有”注銷操作“打印。而test_case1
執(zhí)行前后并無任何數(shù)據(jù)打印。TestClass3
則與Testclass1
執(zhí)行后數(shù)據(jù)顯示一致。
TestClass1
和TestClass2
結(jié)果的不同是由什么原因造成的呢?
官方文檔在介紹fixture的scope的時(shí)候,有這樣一句話,上文中也有提到:fixture是在測(cè)試首次請(qǐng)求時(shí)創(chuàng)建的,并基于它們的作用域被銷毀。(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
的功能打印”注銷操作“,并銷毀login
。
對(duì)于TestClass2
,login
是由test_case2
調(diào)用的,而test_case1
比test_case2
先執(zhí)行,所以test_case1
執(zhí)行的時(shí)候login
還未被調(diào)用,fixture未被創(chuàng)建。直到執(zhí)行test_case2
時(shí),login
才被創(chuàng)建并進(jìn)行了對(duì)應(yīng)的操作。
后面其他類型的作用域示例中將不會(huì)在演示此種情況。
3.module:
演示代碼:
import pytest @pytest.fixture(scope='module')#名為login的fixture,完成登陸和注冊(cè)操作 def login(): print('登陸操作') yield print('注銷操作') @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é)果:
說明:
演示代碼中,我們定義了:
一個(gè)fixture——login()
,并且聲明其scope=”module“
;
兩個(gè)測(cè)試類——TestClass1
和TestClass2
;
兩個(gè)測(cè)試類中分別定義了兩個(gè)測(cè)試函數(shù)——test_case1
和test_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)的功能打印"注銷操作",然后被銷毀。
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('注銷操作')
使用命令行運(yùn)行:
運(yùn)行結(jié)果:
說明:
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()
功能打印出”注銷操作“,并銷毀login()
。
5.session:
使用package的演示代碼,需改conftest.py
中login()
的scope='session'
,然后我們直接在終端中使用命令行運(yùn)行多個(gè)文件。
運(yùn)行以下命令:
運(yùn)行結(jié)果:
說明:
使用命令行方式運(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()
功能打印出”注銷操作“,并銷毀login()
1.2 動(dòng)態(tài)作用域(Dynamic scope)
在某些情況下,我希望在不更改代碼的情況下更改feature的作用域。pytest的從5.2版本開始,提供了動(dòng)態(tài)作用域的方法,來解決這種情況。
通過官方文檔的說明,我們了解到,可以將一個(gè)可調(diào)用對(duì)象傳遞給scope來實(shí)現(xiàn)動(dòng)態(tài)作用域。這個(gè)可調(diào)用對(duì)象必須滿足以下三個(gè)條件:
1.這個(gè)可調(diào)用對(duì)象返回類型需是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_name
和config
作為參數(shù)。
下面通過示例給大家演示以下用法。
示例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('注銷操作') 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")
說明:
dynamic_fixture_scope
:用來管理fixture的作用域,這個(gè)函數(shù)按照pytest官方文檔的要求,帶有fixture_name
和config
兩個(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
。
下面我們分兩種情況來運(yùn)行看看:
1.帶參數(shù)-k運(yùn)行
運(yùn)行命令:我們只運(yùn)行測(cè)試名稱中包含test_A
的測(cè)試函數(shù)。
pytest -vs -k 'test_A' test_dynamicscope.py
運(yùn)行結(jié)果:
通過運(yùn)行結(jié)果可以看到,當(dāng)命令行中出現(xiàn)-k
參數(shù)的時(shí)候,login
的scope
確實(shí)是function
級(jí)別的。兩個(gè)被選中的測(cè)試函數(shù)分別在不同的測(cè)試類中,但是都調(diào)用了login
。
2.無參數(shù)-k運(yùn)行
運(yùn)行命令:我們不帶參數(shù)-k
運(yùn)行。
pytest -vs test_dynamicscope.py
運(yùn)行結(jié)果:
通過運(yùn)行結(jié)果可以看到,無-k
參數(shù)的時(shí)候,login
的scope
確實(shí)是class
級(jí)別的。
2. fixture的實(shí)例化順序
根據(jù)官方文檔,我們了解到影響fixture實(shí)例化順序的三個(gè)因素是:
1. 作用域(scope)
2. 依賴項(xiàng)
3. 自動(dòng)調(diào)用(autouse)
而fixture名稱、測(cè)試函數(shù)名稱以及定義它們的位置一般都不會(huì)影響執(zhí)行順序。
下面介紹一下這個(gè)三個(gè)因素是如何影響實(shí)例化順序的。
2.1 作用域級(jí)別高的fixture先執(zhí)行
我們直接使用官方文檔提供的示例來說明。
示例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é)果:
說明:
演示代碼中我們定義了:
六個(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
:主要目的是通過list中元素的順序來判斷是否按照預(yù)想的順序執(zhí)行fixture。
根據(jù)運(yùn)行結(jié)果顯示,測(cè)試斷言通過,也就是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
。由此可見,我們?cè)谡{(diào)用時(shí)定義的順序不會(huì)影響到fixture的實(shí)際執(zhí)行順序的。
官網(wǎng)執(zhí)行順序圖:
其中sess
與order
的scope都是session級(jí)別的,但是因?yàn)?code>order是sess的依賴項(xiàng),所以會(huì)先調(diào)用order
,這個(gè)一點(diǎn)正好我們下面要說明。
2.2 fixture函數(shù)的依賴項(xiàng)先執(zhí)行
前面文章中有說過,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 的依賴項(xiàng),fixture a 可能會(huì)需要fixture b提供一些條件才能正常被執(zhí)行。
下面我們來看一下官方文檔提供的一個(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é)果:
說明:
演示代碼中定義了八個(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)用了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
。
我們來整理以上所有函數(shù)的依賴關(guān)系,他們之間的依賴關(guān)系如圖所示:
之前文章也有說過,在同一次測(cè)試執(zhí)行過程中,fixture是可以被多次調(diào)用的,但是不會(huì)被多次執(zhí)行。執(zhí)行一次后,fixture的實(shí)例對(duì)象和返回值會(huì)存在緩存中,下次再被調(diào)用的時(shí)候是直接從緩存中獲取的。
所以上面的順序我們可以再簡(jiǎn)化一下:
執(zhí)行完所有依賴的fixture函數(shù)后,我們得到的order的結(jié)果為:['a','b','c','d','e']
,因此測(cè)試斷言通過。
2.3 自動(dòng)使用的fixture在其作用域內(nèi)首先執(zhí)行
根據(jù)官方文檔的說明,我們可以得到一下兩點(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é)果:
說明:
我們把示例3的代碼拿過來修改一下,把所有fixture的scope都改為function級(jí)別,并且對(duì)cls試著autouse=True。
test_order請(qǐng)求fixture的順序是:func, cls, mod, pack, sess
。
當(dāng)scope級(jí)別一樣的時(shí)候,且無依賴關(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一致且無依賴的情況下,自動(dòng)執(zhí)行的fixture是最先被執(zhí)行的。
2.對(duì)一個(gè)autouse的fixture A來說,若調(diào)用了非autouse的fixture B,那么對(duì)于調(diào)用了fixture A的測(cè)試函數(shù)來說,fixture B也相當(dāng)于是autouse的。
我們?cè)賮砜匆幌鹿俜浇o的一個(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"]
說明:
演示代碼中定義了八個(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ù)都沒有調(diào)用c,而g也調(diào)用了f,所以現(xiàn)在還不清楚c應(yīng)該在d、e、f之前還是之后執(zhí)行。對(duì)c來說他只需在b之后、g之前執(zhí)行即可。而實(shí)際運(yùn)行結(jié)果,c是在d、e、f之后和g之前執(zhí)行的。
對(duì)于pytest來說,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é)果和下圖的順序圖,我們可以看出來,當(dāng)自動(dòng)使用c后,它的執(zhí)行優(yōu)先級(jí)就比d要高,所以可以保證c是在d之前執(zhí)行的。這樣使執(zhí)行順序明確了。
當(dāng)c是自動(dòng)使用的fixture后,根據(jù)fixture函數(shù)的依賴項(xiàng)先執(zhí)行這一規(guī)則,c所依賴的b、b所依賴的a和a所依賴的order都會(huì)被執(zhí)行。這樣對(duì)于調(diào)用了c的g來說,order、a、b也相當(dāng)于是自動(dòng)使用的fixture了,但是當(dāng)有其他fixture調(diào)用order、a、b時(shí),order、a、b仍然保持自己的特性。
本節(jié)總結(jié)
我們來總結(jié)一下fixture實(shí)例化順序的一個(gè)規(guī)則:
1.fixture的scope級(jí)別越高,那么它執(zhí)行的優(yōu)先級(jí)越高。優(yōu)先級(jí)為:session>package>module>class>function
2.fixture如果存在依賴項(xiàng),那么它所依賴的fixture函數(shù)會(huì)先被執(zhí)行。
3.同scope級(jí)別fixture中,自動(dòng)使用的fixture會(huì)最先執(zhí)行;若該fixture存在依賴項(xiàng),則對(duì)于調(diào)用了fixture的測(cè)試函數(shù)來說,這些依賴項(xiàng)也可以看做是自動(dòng)使用的。
4.我們?cè)诰幋a的時(shí)候最好可以依照以上規(guī)則為pytest提供一個(gè)清晰的fixture執(zhí)行順序,以免影響測(cè)試函數(shù)的行為和測(cè)試結(jié)果。
3. fixture的可用性
對(duì)于測(cè)試函數(shù)來說,能夠調(diào)用那些fixture,是由fixture定義的位置決定。
1.當(dāng)fixture定義在一個(gè)測(cè)試類中時(shí),只有該類中的測(cè)試函數(shù)可調(diào)用此fixture,其他測(cè)試函數(shù)無法調(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é)果:
說明:
演示代碼中定義了兩個(gè)測(cè)試類:TestClass1
和TestClass2
。TestClass1
中定義了一個(gè)fixture——login
,和測(cè)試函數(shù)test_case1
,test_case1
有調(diào)用login
。TestClass1
中定義了一個(gè)測(cè)試函數(shù)test_case2
,test_case2
有調(diào)用login
。
通過運(yùn)行結(jié)果我們可以看到,與login
在同一測(cè)試類中的test_case1
成功調(diào)用了login
,但是TestClass2
中test_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é)果:
說明:
我們?cè)趖est_availability目錄下創(chuàng)建了一個(gè)conftest.py,并且定義了一個(gè)fixture——login
。
在test_availability.py中,我們定義了兩個(gè)測(cè)試函數(shù)test_case1
和test_case1
,兩個(gè)測(cè)試函數(shù)都調(diào)用了login
。
查看運(yùn)行結(jié)果,測(cè)試函數(shù)都成功調(diào)用了login
。
3.如果安裝的第三方插件提供了fixture,任何測(cè)試函數(shù)都可以正常使用,無需考慮位置因素。
文末說明:
以上內(nèi)容是我在閱讀pytest官方文檔后,依照個(gè)人理解進(jìn)行整理。內(nèi)容可能會(huì)有理解錯(cuò)誤之處,歡迎大家留言指正。謝謝
更多關(guān)于fixture作用域?qū)嵗樞蚣翱捎眯缘馁Y料請(qǐng)關(guān)注本站其它相關(guān)文章!
版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。