前言
上一篇講到fixture通過scope參數控制setup級別,既然有setup作為用例之前前的操作,用例執行完之后那肯定也有teardown操作。
這里用到fixture的teardown操作並不是獨立的函數,用yield關鍵字呼喚teardown操作
scope="module"
1.fixture參數scope="module",module作用是整個.py文件都會生效,用例調用時,參數寫上函數名稱就行
# 新建一個文件test_f1.py
# coding:utf-8
import pytest
'''
** 作者:上海-悠悠 QQ交流群:588402570**
'''
@pytest.fixture(scope="module")
def open():
print("打開瀏覽器,並且打開百度首頁")
def test_s1(open):
print("用例1:搜索python-1")
def test_s2(open):
print("用例2:搜索python-2")
def test_s3(open):
print("用例3:搜索python-3")
if __name__ == "__main__":
pytest.main(["-s", "test_f1.py"])
運行結果:
============================= test session starts =============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: D:\, inifile:
collected 3 items
..\..\..\..\..\..\YOYO\test_f1.py 打開瀏覽器,並且打開百度首頁
用例1:搜索python-1
.用例2:搜索python-2
.用例3:搜索python-3
.
========================== 3 passed in 0.01 seconds ===========================
從結果看出,雖然test_s1,test_s2,test_s3三個地方都調用了open函數,但是它只會在第一個用例前執行一次
2.如果test_s1不調用,test_s2(調用open),test_s3不調用,運行順序會是怎樣的?
# 新建一個文件test_f1.py
# coding:utf-8
import pytest
'''
** 作者:上海-悠悠 QQ交流群:588402570**
'''
@pytest.fixture(scope="module")
def open():
print("打開瀏覽器,並且打開百度首頁")
def test_s1():
print("用例1:搜索python-1")
def test_s2(open):
print("用例2:搜索python-2")
def test_s3():
print("用例3:搜索python-3")
if __name__ == "__main__":
pytest.main(["-s", "test_f1.py"])
運行結果:
============================= test session starts =============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: D:\, inifile:
collected 3 items
..\..\..\..\..\..\YOYO\test_f1.py 用例1:搜索python-1
.打開瀏覽器,並且打開百度首頁
用例2:搜索python-2
.用例3:搜索python-3
.
========================== 3 passed in 0.01 seconds ===========================
從結果看出,module級別的fixture在當前.py模塊里,只會在用例(test_s2)第一次調用前執行一次
yield執行teardown
1.前面講的是在用例前加前置條件,相當於setup,既然有setup那就有teardown,fixture里面的teardown用yield來喚醒teardown的執行
# 新建一個文件test_f1.py
# coding:utf-8
import pytest
'''
** 作者:上海-悠悠 QQ交流群:588402570**
'''
@pytest.fixture(scope="module")
def open():
print("打開瀏覽器,並且打開百度首頁")
yield
print("執行teardown!")
print("最后關閉瀏覽器")
def test_s1(open):
print("用例1:搜索python-1")
def test_s2(open):
print("用例2:搜索python-2")
def test_s3(open):
print("用例3:搜索python-3")
if __name__ == "__main__":
pytest.main(["-s", "test_f1.py"])
運行結果:
============================= test session starts =============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: D:\, inifile:
collected 3 items
..\..\..\..\..\..\YOYO\test_f1.py 打開瀏覽器,並且打開百度首頁
用例1:搜索python-1
.用例2:搜索python-2
.用例3:搜索python-3
.執行teardown!
最后關閉瀏覽器
========================== 3 passed in 0.01 seconds ===========================
yield遇到異常
1.如果其中一個用例出現異常,不影響yield后面的teardown執行,運行結果互不影響,並且全部用例執行完之后,yield呼喚teardown操作
# 新建一個文件test_f1.py
# coding:utf-8
import pytest
'''
** 作者:上海-悠悠 QQ交流群:588402570**
'''
@pytest.fixture(scope="module")
def open():
print("打開瀏覽器,並且打開百度首頁")
yield
print("執行teardown!")
print("最后關閉瀏覽器")
def test_s1(open):
print("用例1:搜索python-1")
# 如果第一個用例異常了,不影響其他的用例執行
raise NameError # 模擬異常
def test_s2(open):
print("用例2:搜索python-2")
def test_s3(open):
print("用例3:搜索python-3")
if __name__ == "__main__":
pytest.main(["-s", "test_f1.py"])
運行結果:
\YOYO\test_f1.py 打開瀏覽器,並且打開百度首頁
用例1:搜索python-1
F
open = None
def test_s1(open):
print("用例1:搜索python-1")
# 如果第一個用例異常了,不影響其他的用例執行
> raise NameError # 模擬異常
E NameError
D:\YOYO\test_f1.py:16: NameError
用例2:搜索python-2
.用例3:搜索python-3
.執行teardown!
最后關閉瀏覽器
2.如果在setup就異常了,那么是不會去執行yield后面的teardown內容了
3.yield也可以配合with語句使用,以下是官方文檔給的案例
# 官方文檔案例
# content of test_yield2.py
import smtplib
import pytest
'''
** 作者:上海-悠悠 QQ交流群:588402570**
'''
@pytest.fixture(scope="module")
def smtp():
with smtplib.SMTP("smtp.gmail.com") as smtp:
yield smtp # provide the fixture value
addfinalizer終結函數
1.除了yield可以實現teardown,在request-context對象中注冊addfinalizer方法也可以實現終結函數。
# 官方案例
# content of conftest.py
import smtplib
import pytest
@pytest.fixture(scope="module")
def smtp_connection(request):
smtp_connection = smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
def fin():
print("teardown smtp_connection")
smtp_connection.close()
request.addfinalizer(fin)
return smtp_connection # provide the fixture value
2.yield和addfinalizer方法都是在測試完成后呼叫相應的代碼。但是addfinalizer不同的是:
-
他可以注冊多個終結函數。
-
這些終結方法總是會被執行,無論在之前的setup code有沒有拋出錯誤。這個方法對於正確關閉所有的fixture創建的資源非常便利,即使其一在創建或獲取時失敗
---------------------------------pytest結合selenium自動化完整版-------------------------
全書購買地址 https://yuedu.baidu.com/ebook/902224ab27fff705cc1755270722192e4536582b
作者:上海-悠悠 QQ交流群:874033608
也可以關注下我的個人公眾號:yoyoketang