<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Pytest自動(dòng)化測(cè)試-簡易入門教程

          共 11371字,需瀏覽 23分鐘

           ·

          2020-11-30 16:04


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


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

          一、簡介

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


          功能特征

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

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

          自動(dòng)發(fā)現(xiàn)測(cè)試模塊和功能(以test為標(biāo)識(shí))

          可以運(yùn)行unittest和nose框架的測(cè)試用例

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

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

          編寫規(guī)則

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

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

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

          斷言使用基本的assert即可

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

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

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

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

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

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


          二、安裝

          打開bash命令行,運(yùn)行以下命令:

          pip install?-U pytest


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

          $?pytest --version
          pytest 6.1.2


          三、示例

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

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

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

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


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

          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 ======================================================================


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


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

          •   pytest 使用 F 標(biāo)識(shí)測(cè)試失敗(FAILED)

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

          •   可以使用 -h 查看 pytest 的所有選項(xiàng)


          四、標(biāo)記

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


          1、如果你想指定運(yùn)行測(cè)試用例,可以通過 :: 顯式標(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、如果你想選擇一些測(cè)試用例,可以使用 -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、如果你想跳過個(gè)別測(cè)試用例,可以使用 pytest.mark.skip(),或者 pytest.mark.skipif(條件表達(dá)式)。

          # 測(cè)試失敗
          @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、如果你事先知道測(cè)試函數(shù)會(huì)執(zhí)行失敗,但又不想直接跳過,而是希望顯示的提示,可以使用pytest.mark.xfail()。

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


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


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

          # 測(cè)試成功
          @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 會(huì)在執(zhí)行測(cè)試函數(shù)之前(或之后)加載運(yùn)行它們。


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


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

          # conftest.py
          import?pytest

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



          # 測(cè)試成功
          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ù)處理,會(huì)在測(cè)試前執(zhí)行;yield 之后的代碼屬于后處理,將在測(cè)試完成后執(zhí)行。

          # conftest.py
          import?pytest

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



          # 測(cè)試成功
          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使用作用域來進(jìn)行指定固件的使用范圍。

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


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

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

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

          • session: 會(huì)話級(jí),一次測(cè)試只執(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



          # 測(cè)試成功
          ? @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ù)讓固件自動(dòng)執(zhí)行。


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


          • 可以使用 -s 選項(xiàng),顯示print打印信息

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


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

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

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

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

          • monkeypath:用于運(yùn)行時(shí)動(dòng)態(tài)修改類或模塊。

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


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


          END

          往期推薦

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

          拒絕伸手!新手如何正確對(duì)待代碼報(bào)錯(cuò)

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

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


          中獎(jiǎng)名單

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


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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  午夜成人在线 | 国产六区精品 | 人人燥狠狠干 | 日日撸夜夜草 | 欧美成人小黄片 |