1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Pytest自動化測試-簡易入門教程

        共 11371字,需瀏覽 23分鐘

         ·

        2020-11-30 16:04


        為了感謝大家對“Python客棧”的關(guān)注與支持,我們每天會在留言中隨機抽取三位粉絲發(fā)放6.6元小紅包。快來參與吧!


        作者:LeoZhanggg
        原文:https://www.cnblogs.com/leozhanggg/p/14035202.html
        感謝原作者的創(chuàng)作

        一、簡介

        pytest是動態(tài)編程語言Python專用的測試框架,它具有易于上手、功能強大、可擴展性好、兼容性強、效率高、第三方插件豐富等特點。


        功能特征

        完整的文檔,包括安裝,教程和PDF文檔

        簡單而又詳細(xì)的斷言模式(使用純assert語句)

        自動發(fā)現(xiàn)測試模塊和功能(以test為標(biāo)識)

        可以運行unittest和nose框架的測試用例

        靈活的固件,用于管理小型或參數(shù)化的長期測試資源

        豐富的插件架構(gòu),擁有三百多個外部插件和豐富的社區(qū)

        編寫規(guī)則

        測試文件以test_開頭(以_test結(jié)尾也可以)

        測試類以Test開頭,并且不能帶有 init 方法

        測試函數(shù)以test_開頭

        斷言使用基本的assert即可

        自動發(fā)現(xiàn)規(guī)則:

        如果未指定任何參數(shù),則從testpaths(如果已配置)或當(dāng)前目錄開始收集。

        另外,命令行參數(shù)可以在目錄、文件名或節(jié)點ID的任何組合中使用。

        在這些目錄中,搜索包含 test_*.py 或 *_test.py 的測試文件。

        從這些文件中,收集以test前綴的測試方法,或者在Test前綴的測試類(無__init__方法)中的以test前綴的測試方法。

        官方文檔:https://docs.pytest.org/en/latest/contents.html


        二、安裝

        打開bash命令行,運行以下命令:

        pip install?-U pytest


        檢查是否安裝了正確的版本:

        $?pytest --version
        pytest 6.1.2


        三、示例

        創(chuàng)建一個簡單的測試函數(shù):

        # test_sample.py
        # 被測功能
        def?func(x):
        ????return?x + 1

        # 測試成功
        def?test_pass():
        ????assert?func(3) == 4

        # 測試失敗
        def?test_fail():
        ????assert?func(3) == 5


        現(xiàn)在開始執(zhí)行測試功能:

        E:\workspace-py\Pytest>pytest
        ========================================================================== test session starts ==========================================================================
        platform win32 -- Python 3.7.3, pytest-6.0.2, py-1.9.0, pluggy-0.13.0
        rootdir: E:\workspace-py\Pytest
        plugins: allure-pytest-2.8.18, cov-2.10.1, html-2.1.1, metadata-1.8.0, rerunfailures-9.1, xdist-2.1.0
        collected 2?items

        test_sample.py .F [100%]

        =============================================================================== FAILURES ================================================================================
        _______________________________________________________________________________ test_fail _______________________________________________________________________________

        ????def?test_fail():
        > assert?func(3) == 5
        E assert?4?== 5
        E + where 4?= func(3)

        test_sample.py:16: AssertionError
        ======================================================================== short test summary info ========================================================================
        FAILED test_sample.py::test_fail - assert?4?== 5
        ====================================================================== 1?failed, 1?passed in?0.16s ======================================================================


        這里未指定測試用例,pytest將依據(jù)自動發(fā)現(xiàn)規(guī)則檢索并執(zhí)行測試,等同于 pytest ./test_sample.py


        •   pytest 使用 . 標(biāo)識測試成功(PASSED)

        •   pytest 使用 F 標(biāo)識測試失?。‵AILED)

        •   可以使用 -v 選項,顯示測試的詳細(xì)信息

        •   可以使用 -h 查看 pytest 的所有選項


        四、標(biāo)記

        默認(rèn)情況下,pytest 會遞歸查找當(dāng)前目錄下所有以 test 開始或結(jié)尾的 Python 腳本,并執(zhí)行文件內(nèi)的所有以 test 開始或結(jié)束的函數(shù)和方法。


        1、如果你想指定運行測試用例,可以通過 :: 顯式標(biāo)記(文件名:: 類名::方法名)。

        E:\workspace-py\Pytest>pytest test_sample.py::test_pass
        ========================================================================== test session starts ==========================================================================
        platform win32 -- Python 3.7.3, pytest-6.0.2, py-1.9.0, pluggy-0.13.0
        rootdir: E:\workspace-py\Pytest
        plugins: allure-pytest-2.8.18, cov-2.10.1, html-2.1.1, metadata-1.8.0, rerunfailures-9.1, xdist-2.1.0
        collected 1?item

        test_sample.py . [100%]

        =========================================================================== 1?passed in?0.05s ===========================================================================


        2、如果你想選擇一些測試用例,可以使用 -k 模糊匹配。

        E:\workspace-py\Pytest>pytest -k pass?test_sample.py
        ========================================================================== test session starts ==========================================================================
        platform win32 -- Python 3.7.3, pytest-6.0.2, py-1.9.0, pluggy-0.13.0
        rootdir: E:\workspace-py\Pytest
        plugins: allure-pytest-2.8.18, cov-2.10.1, html-2.1.1, metadata-1.8.0, rerunfailures-9.1, xdist-2.1.0
        collected 2?items / 1?deselected / 1?selected

        test_sample.py . [100%]

        ==================================================================== 1?passed, 1?deselected in?0.02s ====================================================================


        3、如果你想跳過個別測試用例,可以使用 pytest.mark.skip(),或者 pytest.mark.skipif(條件表達式)。

        # 測試失敗
        @pytest.mark.skip()
        def?test_fail():
        ????assert?func(3) == 5



        E:\workspace-py\Pytest>pytest -v test_sample.py
        ========================================================================== test session starts ==========================================================================
        platform win32 -- Python 3.7.3, pytest-6.0.2, py-1.9.0, pluggy-0.13.0?-- c:\python37\python.exe
        cachedir: .pytest_cache
        metadata: {'Python': '3.7.3', 'Platform': 'Windows-7-6.1.7601-SP1', 'Packages': {'pytest': '6.0.2', 'py': '1.9.0', 'pluggy': '0.13.0'}, 'Plugins': {'allure-pytest': '2.8.
        18'
        , 'cov': '2.10.1', 'html': '2.1.1', 'metadata': '1.8.0', 'rerunfailures': '9.1', 'xdist': '2.1.0'}}
        rootdir: E:\workspace-py\Pytest
        plugins: allure-pytest-2.8.18, cov-2.10.1, html-2.1.1, metadata-1.8.0, rerunfailures-9.1, xdist-2.1.0
        collected 2?items

        test_sample.py::test_pass PASSED [ 50%]
        test_sample.py::test_fail SKIPPED [100%]

        ===================================================================== 1?passed, 1?skipped in?0.07s ======================================================================


        4、如果你想捕捉一些異常,可以使用pytest.raises()。

        # test_raises.py

        def?test_raises():
        ????with?pytest.raises(TypeError) as?e:
        ????????connect('localhost', '6379')
        ????exec_msg = e.value.args[0]
        ????assert?exec_msg == 'port type must be int'


        5、如果你事先知道測試函數(shù)會執(zhí)行失敗,但又不想直接跳過,而是希望顯示的提示,可以使用pytest.mark.xfail()。

        # 測試失敗
        @pytest.mark.xfail()
        def?test_fail():
        ????assert?func(3) == 5


        6、如果你想對某個測試點進行多組數(shù)據(jù)測試,可以使用 pytest.mark.parametrize(argnames, argvalues) 參數(shù)化測試,即每組參數(shù)都獨立執(zhí)行一次測試。


        注意:以往我們可以把這些參數(shù)寫在測試函數(shù)內(nèi)部進行遍歷,但是當(dāng)某組參數(shù)導(dǎo)致斷言失敗,測試則就終止了。

        # 測試成功
        @pytest.mark.parametrize('data', [1, 2, 3])
        def?test_pass(data):
        ????assert?func(data) == 4



        E:\workspace-py\Pytest>pytest -k pass?test_sample.py
        ========================================================================== test session starts ==========================================================================
        platform win32 -- Python 3.7.3, pytest-6.0.2, py-1.9.0, pluggy-0.13.0
        rootdir: E:\workspace-py\Pytest
        plugins: allure-pytest-2.8.18, cov-2.10.1, html-2.1.1, metadata-1.8.0, rerunfailures-9.1, xdist-2.1.0
        collected 4?items / 1?deselected / 3?selected

        test_sample.py FF. [100%]

        =============================================================================== FAILURES ================================================================================
        _____________________________________________________________________________ test_pass[1] ______________________________________________________________________________

        data = 1

        [email protected]('data', [1, 2, 3])
        ????def?test_pass(data):
        > assert?func(data) == 4
        E assert?2?== 4
        E + where 2?= func(1)

        test_sample.py:11: AssertionError
        _____________________________________________________________________________ test_pass[2] ______________________________________________________________________________

        data = 2

        [email protected]('data', [1, 2, 3])
        ????def?test_pass(data):
        > assert?func(data) == 4
        E assert?3?== 4
        E + where 3?= func(2)

        test_sample.py:11: AssertionError
        ======================================================================== short test summary info ========================================================================
        FAILED test_sample.py::test_pass[1] - assert?2?== 4
        FAILED test_sample.py::test_pass[2] - assert?3?== 4
        =============================================================== 2?failed, 1?passed, 1?deselected in?0.17s ===============================================================


        五、固件

        固件(Fixture)是一些函數(shù),pytest 會在執(zhí)行測試函數(shù)之前(或之后)加載運行它們。


        我們可以利用固件做任何事情,其中最常見的可能就是數(shù)據(jù)庫的初始連接和最后關(guān)閉操作。


        1、Pytest使用pytest.fixture()定義固件,為了在實際工程中可以更大程度上復(fù)用,我們更多的是使用文件conftest.py集中管理固件(pytest會自動調(diào)用)。

        # conftest.py
        import?pytest

        @pytest.fixture()
        def?data():
        ????return?3



        # 測試成功
        def?test_pass(data):
        ????assert?func(data) == 4



        E:\workspace-py\Pytest>pytest -k pass?test_sample.py
        ========================================================================== test session starts ==========================================================================
        platform win32 -- Python 3.7.3, pytest-6.0.2, py-1.9.0, pluggy-0.13.0
        rootdir: E:\workspace-py\Pytest
        plugins: allure-pytest-2.8.18, cov-2.10.1, html-2.1.1, metadata-1.8.0, rerunfailures-9.1, xdist-2.1.0
        collected 2?items / 1?deselected / 1?selected

        test_sample.py . [100%]

        ==================================================================== 1?passed, 1?deselected in?0.05s ====================================================================


        2、Pytest 使用 yield 關(guān)鍵詞將固件分為兩部分,yield 之前的代碼屬于預(yù)處理,會在測試前執(zhí)行;yield 之后的代碼屬于后處理,將在測試完成后執(zhí)行。

        # conftest.py
        import?pytest

        @pytest.fixture()
        def?db():
        ????print('opened')
        ????yield
        ????print('closed')



        # 測試成功
        def?test_pass(db):
        ????assert?func(3) == 4



        E:\workspace-py\Pytest>pytest -s -k pass?test_sample.py
        ========================================================================== test session starts ==========================================================================
        platform win32 -- Python 3.7.3, pytest-6.0.2, py-1.9.0, pluggy-0.13.0
        rootdir: E:\workspace-py\Pytest
        plugins: allure-pytest-2.8.18, cov-2.10.1, html-2.1.1, metadata-1.8.0, rerunfailures-9.1, xdist-2.1.0
        collected 2?items / 1?deselected / 1?selected

        test_sample.py opened
        .closed


        ==================================================================== 1?passed, 1?deselected in?0.02s ====================================================================


        3、為了更精細(xì)化控制固件,pytest使用作用域來進行指定固件的使用范圍。

        在定義固件時,通過 scope 參數(shù)聲明作用域,可選項有:


        • function: 函數(shù)級,每個測試函數(shù)都會執(zhí)行一次固件(默認(rèn)值);

        • class: 類級別,每個測試類執(zhí)行一次,所有方法都可以使用;

        • module: 模塊級,每個模塊執(zhí)行一次,模塊內(nèi)函數(shù)和方法都可使用;

        • session: 會話級,一次測試只執(zhí)行一次,所有被找到的函數(shù)和方法都可用。


        # conftest.py
        import?pytest

        @pytest.fixture(scope='function', autouse=True)
        def?func_scope():
        ????pass

        @pytest.fixture(scope='module', autouse=True)
        def?mod_scope():
        ????pass

        @pytest.fixture(scope='session')
        def?sess_scope():
        ????pass

        @pytest.fixture(scope='class')
        def?class_scope():
        ????pass



        # 測試成功
        ? @pytest.mark.usefixtures('sess_scope')
        ? def?test_pass(class_scope):
        ? ? ? assert?func(3) == 4



        E:\workspace-py\Pytest>pytest --setup-show -k pass?test_sample.py
        ========================================================================== test session starts ==========================================================================
        platform win32 -- Python 3.7.3, pytest-6.0.2, py-1.9.0, pluggy-0.13.0
        rootdir: E:\workspace-py\Pytest
        plugins: allure-pytest-2.8.18, cov-2.10.1, html-2.1.1, metadata-1.8.0, rerunfailures-9.1, xdist-2.1.0
        collected 2?items / 1?deselected / 1?selected

        test_sample.py
        SETUP S sess_scope
        ????SETUP M mod_scope
        ??????SETUP C class_scope
        ????????SETUP F func_scope
        ????????test_sample.py::test_pass (fixtures used: class_scope, func_scope, mod_scope, sess_scope).
        ????????TEARDOWN F func_scope
        ??????TEARDOWN C class_scope
        ????TEARDOWN M mod_scope
        TEARDOWN S sess_scope

        ==================================================================== 1?passed, 1?deselected in?0.02s ====================================================================


        我們可以把固件作為入?yún)ⅲ€可以使用@pytest.mark.usefixtures('class_scope'),或者指定autouse參數(shù)讓固件自動執(zhí)行。


        并且還可以指定params參數(shù)來實現(xiàn)固件的參數(shù)化,以及指定name參數(shù)來修改固件名。


        • 可以使用 -s 選項,顯示print打印信息

        • 可以使用 --setuo-show 選項,顯示詳細(xì)的固件信息


        4、內(nèi)置固件:

        • tmpdir & tmpdir_factory:用于臨時文件和目錄管理,默認(rèn)會在測試結(jié)束時刪除。

        • pytestconfig:用于讀取命令行參數(shù)和配置文件

        • capsys:用于捕獲 stdout 和 stderr 的內(nèi)容,并臨時關(guān)閉系統(tǒng)輸出。

        • monkeypath:用于運行時動態(tài)修改類或模塊。

        • recwarn:用于捕獲程序中 warnings 產(chǎn)生的警告。


        ?Pytest學(xué)習(xí)手冊:https://learning-pytest.readthedocs.io/zh/latest/index.html


        END

        往期推薦

        阿里云盤又雙叒叕上線啦!嘗鮮下載

        拒絕伸手!新手如何正確對待代碼報錯

        Python 下載文件的七種方式,你get了嗎?

        資深開發(fā)者都經(jīng)常使用的10個 PyCharm 技巧


        中獎名單

        以上三位小伙伴,快來聯(lián)系小編領(lǐng)取小小紅包一份哦!小編微信:Mayyy530


        轉(zhuǎn)發(fā),點贊,在看,安排一下?
        瀏覽 54
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            特黄AAAAAAA片免费视频 | 超碰碰人人 | 久久久无码人妻精品无码 | 97人人操人人 | 欧美成人精品在线观看 | 51国产精品 | 又黄又爽视频网站 | 国产在线不卡 | 少妇小依的哀羞1~60小说 | 中国精品一级毛片 |