pytest中的yeild以及固件函數的作用域

關於pytest中的yeild
yeild 在python中,是一個生成器,但是應用在pytest中的時候,結合固件使用,就變的有意思了,可以返回需要的值,
也可以作爲裝飾器插入部分,在沒設置返回值的時候,在執行到yield的時候,就會執行測試函數了。
(個人的理解就是此時yeild 結合固件函數使用時,當函數引用到的固件中存在yeild的時候,函數會先執行固件函數的yeild的前面部分,碰到yeild的時候,就去執行函數本身,函數本身執行完畢後,再去執行yield的後面部分。當yield 後面帶有返回值的時候,返回值就會帶入到函數中去)
看看下面的例子
在pytest中,是這樣的
conftest.py
@pytest.fixture()
def func1():
    a=1
    b=2
    yield a,b  #返回一個tuple
@pytest.fixture(scope='module')
def login():
    dr=webdriver.Chrome()
    dr.get('http://www.baidu.com')
    yield dr  #測試函數test_01引用後,會在執行完driver後去執行test_01 完畢後再去執行driver.quit()
    dr.quit()

test_01.py
def test_yeild(func1):
    print (type(func1))
    var1=func1[0]
    var2=func1[1]
    print (var1,var2)
def test_search1(login):
    dr=login  #將瀏覽器對象傳遞給dr,這個很重要
    dr.find_element_by_id('kw')..send_keys('aaa')
執行後顯示,func1是一個tuple類型的。這裏和通用的用法有點不一樣。我們可以看下常規下的操作
debug.py
def func1():
    for i in range(10):
        yield i
a=func1()
print (type(a))
for i in func1():
    print (i)  #結果順序輸出從0到9



作用域 一個重要的概念
function: 函數級,每個測試函數都會執行一次固件;
class: 類級別,每個測試類執行一次,所有方法都可以使用;
module: 模塊級,每個模塊執行一次,模塊內函數和方法都可使用;
session: 會話級,一次測試只執行一次,所有被找到的函數和方法都可用。
理解:這幾個作用域,在什麼場景下使用,需要結合自己的代碼和固件函數本身,某些配置信息,只希望執行一次,就可以使用session級別,autouse=True,如果測試用例分成幾個文件夾,每個文件夾下有單獨的conftest,這裏面的數據,只要在調用的時候執行一次,就可以設置爲module級別。class的,就是class調用的時候會執行,function同理。這些配置信息,使用的多了,就知道如果去正確的配置了。
結合代碼來說明
conftest.py
@pytest.fixture(scope='module')
def login():
    dr=webdriver.Chrome()
    dr.get('http://www.baidu.com')
    yield dr
    dr.quit()

test_01.py
def test_search1(login):
    dr=login
    dr.find_element_by_id('kw').send_keys('aaa')
    time.sleep(3)

def test_search2(login):
    dr=login
    dr.find_element_by_id('kw').send_keys('bbb')
    time.sleep(2)
 執行效果:在百度的輸入框裏面輸入了aaabbb 這是因爲scope設置的是modle級別執行的邏輯是login--test_search1--test_search2
再修改
conftest.py
@pytest.fixture(scope='function',autouse=True)
def login():
    dr=webdriver.Chrome()
    dr.get('http://www.baidu.com')
    print ('one')
    yield dr
    dr.quit()

test_01.py
def test_search1(login):
    dr=login
    dr.find_element_by_id('kw').send_keys('aaa')
    time.sleep(3)

def test_search2():
    print ('hello')

 結果如下:
 collected 2 items

test_01.py one
.one
hello
.
可以看到lgoin執行了兩次  這是因爲autouse 和scope共同作用的結果  function設置會讓每個def執行的時候都會去執行login(前提是def有引用該固件),
當def沒有引用該固件的時候,設置autouse爲Ture,每個def執行的時候也會默認先去執行login。
引申:當測試場景要求每個def都需要單獨開啓新的瀏覽器,我們就要將login設置爲默認值function,autouse設置爲ture。
當測試場景要求只在開始階段打開一個瀏覽器,我們就需要scope=session,
當測試場景要求每個class打開一個新瀏覽器,scope=class
當需要一個py文件打開一個新瀏覽器  scope=module(用兩個文件做了測試,設置module的時候,一個py文件會執行一次固件函數)
conftest.py
@pytest.fixture(scope='module')
def login():
    dr=webdriver.Chrome()
    dr.get('http://www.baidu.com')
    print ('one')
    yield dr
    dr.quit()

test_01.py
def test_search1(login):
    dr=login
    dr.find_element_by_id('kw').send_keys('aaa')
    time.sleep(3)
test_sample.py
def test_search1(login):
    dr=login
    dr.find_element_by_id('kw').send_keys('ccc')
    time.sleep(3)
執行:pytest.main(['-s','test_01.py',"test_sample.py"])
test_01.py one
.hello
.
test_sample.py EF.one
.
換一種方式cmd方式執行 也是會輸出兩個one ,結果一樣。



發佈了106 篇原創文章 · 獲贊 22 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章