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后置操作---------------------------")

然后重新運行用例,得到結果如下:

setup前置操作失敗

從用例結果中可以看到,我們在 Pytest 中執行用例時,如果在setup前置操作中就出現失敗,那么其不會再調用測試用例和執行后置操作(上面 teardown 的信息也沒有打印出來),而用例的執行結果為:error

call測試用例失敗

為了讓用例在 call 調用中出現失敗,我們可以簡單修改下 test_01.py 代碼:

import pytest


def test_01():
    """用例描述:XXXXXX"""
    print("斷言失敗")
    assert 0

重新運行用例,得到結果如下:

call測試用例失敗

從用例結果中可以看到,我們在 Pytest 中執行用例時,setup前置操作成功,但在call測試用例中出現失敗,那么其會繼續執行后置操作,最后用例的執行結果為:failed

teardown后置操作失敗

為了讓用例在前置操作中出現失敗,我們可以簡單修改下 conftest.py 代碼:

@pytest.fixture(scope="function", autouse=True)
def setup_teardown():
    print("------------------------這是setup前置操作---------------------------")
    yield
    print("------------------------這是teardown前置操作---------------------------")
    assert 0

重新運行用例,得到結果如下:

teardown后置操作失敗

從用例結果中可以看到,我們在 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---------------------------")

重新運行用例,得到結果如下:

獲取用例執行時的信息g


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM