Pytest學習-通過hooks函式(pytest_runtest_makereport)獲取用例結果
Pytest中提供了很多鉤子函式,可以方便我們基於此進行二次開發,另外通過對Pytest鉤子函式的學習,我們也能夠更好的理解到其在用例執行的各階段到底做了哪些工作。
今天我們將學習Pytest中的鉤子函式:pytest_runtest_makereport
,它可以讓我們獲取到用例執行結果。
鉤子函式的使用
我們可以在Pytest原始碼中的 runner.py
檔案下找到 pytest_runtest_makereport()
鉤子函式,大致如下:
def pytest_runtest_makereport(item, call): return TestReport.from_item_and_call(item, call)
該函式操作時傳入 測試用例 item 和 測試步驟 call,返回的資料是測試用例的執行結果。下面是簡單的示例:
# test_01.py
import pytest
def test_01():
"""用例描述:XXXXXX"""
print("測試一下")
assert 1
# conftest.py import pytest @pytest.hookimpl(hookwrapper=True, tryfirst=True) def pytest_runtest_makereport(item, call): print("------------------------Start---------------------------") out = yield res = out.get_result() print("執行結果:{}".format(res)) print("測試用例:{}".format(item)) print("測試步驟:{}".format(call)) print("------------------------End---------------------------")
把上面的用例執行後,得到如下結果:
從上方輸出的資訊可以知道,我們在 Pytest 中執行一條用例的時候,需要經過以下3個階段:
- 最先執行
when='setup'
的前置操作- 接著執行
when='call'
的用例部分- 最後執行
when='teardown'
的後置操作
上面的每一個階段,都會返回相應的執行結果,如果用例中不存在前置/後置操作,那麼該階段預設 outcome='passed'
。
當然對於這3個階段,也都可能會出現失敗的情況。為了更方便模擬操作失敗的情況,我們在 conftest.py
中使用 fixture
增加一個函式,然後設定為自動呼叫。
@pytest.fixture(scope="function", autouse=True) def setup_teardown(): print("------------------------這是setup前置操作---------------------------") yield print("------------------------這是teardown後置操作---------------------------")
setup前置操作失敗
為了讓用例在前置操作中出現失敗,我們可以簡單修改下 conftest.py
程式碼:
@pytest.fixture(scope="function", autouse=True)
def setup_teardown():
assert 0
print("------------------------這是setup前置操作---------------------------")
yield
print("------------------------這是teardown後置操作---------------------------")
然後重新執行用例,得到結果如下:
從用例結果中可以看到,我們在 Pytest 中執行用例時,如果在setup前置操作中就出現失敗,那麼其不會再呼叫測試用例和執行後置操作(上面 teardown 的資訊也沒有打印出來),而用例的執行結果為:error
。
call測試用例失敗
為了讓用例在 call 呼叫中出現失敗,我們可以簡單修改下 test_01.py
程式碼:
import pytest
def test_01():
"""用例描述:XXXXXX"""
print("斷言失敗")
assert 0
重新執行用例,得到結果如下:
從用例結果中可以看到,我們在 Pytest 中執行用例時,setup前置操作成功,但在call測試用例中出現失敗,那麼其會繼續執行後置操作,最後用例的執行結果為:failed
。
teardown後置操作失敗
為了讓用例在前置操作中出現失敗,我們可以簡單修改下 conftest.py
程式碼:
@pytest.fixture(scope="function", autouse=True)
def setup_teardown():
print("------------------------這是setup前置操作---------------------------")
yield
print("------------------------這是teardown前置操作---------------------------")
assert 0
重新執行用例,得到結果如下:
從用例結果中可以看到,我們在 Pytest 中執行用例時,teardown後置操作失敗,那麼最後用例的結果為:1 passed, 1 error
。
獲取用例執行時的資訊
有時候,我們想要獲取測試用例執行的詳細資訊,比如列印用例描述,或在用例執行失敗後列印日誌等資訊,那麼我們可以優化下程式碼:
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
print("------------------------Start---------------------------")
out = yield # 鉤子函式的呼叫結果
res = out.get_result() # 獲取用例執行結果
print("執行結果:{}".format(res))
if res.when == "call" and res.outcome == "failed": # 只獲取call用例失敗時的資訊
print("測試用例:{}".format(item))
print("用例描述:{}".format(item.function.__doc__))
print("測試步驟:{}".format(call))
print("用例失敗異常資訊:{}".format(call.excinfo))
print("用例失敗時的詳細日誌:{}".format(res.longrepr))
print("------------------------End---------------------------")
重新執行用例,得到結果如下: