Pytest06-內置fixture

6.內置fixture

    pytest內置的fixture可以大量簡化測試工作。如在處理臨時文件時,pytest內置的fixture可以識別命令行參數、在多個測試會話間通信、校驗輸出流、更改環境變量、審查錯誤報警等。內置fixture是對pytest核心功能的擴展。

6.1 使用tmpdir和tempdir_factory

    內置的tmpdir和tmpdir_factory負責在測試開始運行前創建臨時文件目錄,並在測試結束後刪除。其主要特性如下所示:

  • 1.如果測試代碼要對文件進行讀寫操作,可以使用tmpdir或tmpdir_factory來創建文件或目錄,單個測試使用tmpdir,多個測試使用tmpdir_factory
  • 2.tmpdir的作用範圍爲函數級別,tmpdir_factory作用範圍是會話級別

    示例代碼如下所示:

import pytest

def test_tmpDir(tmpdir):
    tmpfileA=tmpdir.join("testA.txt")
    tmpSubDir=tmpdir.mkdir("subDir")
    tmpfileB=tmpSubDir.join("testB.txt")
    tmpfileA.write("this is pytest tmp file A")
    tmpfileB.write("this is pytest tmp file B")

    assert tmpfileA.read()=="this is pytest tmp file A"
    assert tmpfileB.read()=="this is pytest tmp file B"

    tmpdir的作用範圍是函數級別,所以只能針對測試函數使用tmpdir創建文件或目錄。如果fixture作用範圍高於函數級別(類、模塊、會話),則需要使用tmpdir_factory。tmpdir與tmpdir_factory類似,但提供的方法有一些不同,如下所示:

import pytest

def test_tmpDir(tmpdir_factory):
    baseTmpDir=tmpdir_factory.getbasetemp()
    print(f"\nbase temp dir is :{baseTmpDir}")
    tmpDir_factory=tmpdir_factory.mktemp("tempDir")
    tmpfileA=tmpDir_factory.join("testA.txt")
    tmpSubDir=tmpDir_factory.mkdir("subDir")
    tmpfileB=tmpSubDir.join("testB.txt")
    tmpfileA.write("this is pytest tmp file A")
    tmpfileB.write("this is pytest tmp file B")

    assert tmpfileA.read()=="this is pytest tmp file A"
    assert tmpfileB.read()=="this is pytest tmp file B"

    getbasetemp()用於返回該會話使用的根目錄,pytest-NUM會隨着會話的增加而進行自增,pytest會記錄最近幾次會話使用的根目錄,更早的根目錄記錄則會被清理掉。另外也可在命令行指定臨時目錄,如下所示:

pytest --basetemp=dir

運行結果如下所示:

>>> pytest -s -v .\test_01.py
========================= test session starts ==============================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson04
collected 1 item

test_01.py::test_tmpDir
base temp dir is :C:\Users\Surpass\AppData\Local\Temp\pytest-of-Surpass\pytest-11
PASSED

========================= 1 passed in 0.12s ==================================

6.2 在其他作用範圍內使用臨時目錄

    tmpdir_factory的作用範圍是會話級別的,tmpdir的作用範圍是函數級別的。如果需要模塊級別或類級別的作用範圍的目錄,該如何解決了?針對這種情況,可以利用tmpdir_factory再創建一個fixture。

    假設有一個測試模塊,其中有很多測試用例需要讀取一個JSON文件,則可以在模塊本身或conftest.py中創建一個作用範圍爲模塊級別的fixture用於配置該誰的,示例如下所示:

conftest.py

import json
import pytest

@pytest.fixture(scope="module")
def readJson(tmpdir_factory):
    jsonData={
        "name":"Surpass",
        "age":28,
        "locate":"shangahi",
        "loveCity":{"shanghai":"shanghai",
                    "wuhai":"hubei",
                    "shenzheng":"guangdong"
                    }
    }

    file=tmpdir_factory.mktemp("jsonTemp").join("tempJSON.json")

    with open(file,"w",encoding="utf8") as fo:
        json.dump(jsonData,fo,ensure_ascii=False)

    # print(f"base dir is {tmpdir_factory.getbasetemp()}")
    return file

test_02.py

import json

def test_getData(readJson):
    with open(readJson,"r",encoding="utf8") as fo:
        data=json.load(fo)
    assert data.get("name")=="Surpass"

def test_getLoveCity(readJson):
    with open(readJson,"r",encoding="utf8") as fo:
        data=json.load(fo)
    getCity=data.get("loveCity")
    for k,v in getCity.items():
        assert len(v)>0

運行結果如下所示:

>>> pytest -v .\test_02.py
============================ test session starts ==============================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson04
collected 2 items

test_02.py::test_getData PASSED                                        [ 50%]
test_02.py::test_getLoveCity PASSED                                    [100%]

========================== 2 passed in 0.08s ==================================

    因爲創建的fixture級別爲模塊級別,因此JSON只會被創建一次。

6.3 使用pytestconfig

    內置的pytestconfig可以通過命令行參數、選項、配置文件、插件、運行目錄等方式來控制pytest。pytestconfig是request.config的快捷方式,在pytest中稱之爲”pytest配置對象“
    爲了理解pytestconfig是如何工作,可以查看如何添加一個自定義的命令行選項,然後在測試用例中讀取該選項。另外也可以直接從pytestconfig裏讀取自定義的命令行選項,爲了讓pytest能夠解析,還需要使用hook函數(hook函數是另一種控制pytest的方法,在插件中頻繁使用)。示例如下所示:

pytestconfig\conftest.py

def pytest_addoption(parser):
    parser.addoption("--myopt",action="store_true",help="test boolean option")
    parser.addoption("--foo",action="store",default="Surpass",help="test stroe")

運行結果如下所示:

>>> pytest --help
usage: pytest [options] [file_or_dir] [file_or_dir] [...]
...
custom options:
  --myopt               test boolean option
  --foo=FOO             test stroe

    下面來嘗試在測試用例中使用這些選項,如下所示:

pytestconfig\test_03.py

import pytest

def test_myOption(pytestconfig):
    print(f"--foo {pytestconfig.getoption('foo')}")
    print(f"--myopt {pytestconfig.getoption('myopt')}")

運行結果如下所示:

>>> pytest -s -q .\test_03.py
--foo Surpass
--myopt False
.
1 passed in 0.08s

>>> pytest -s -q --myopt .\test_03.py
--foo Surpass
--myopt True
.
1 passed in 0.02s

>>> pytest -s -q --myopt --foo Surpass .\te
st_03.py
--foo Surpass
--myopt True

    因爲pytestconfig是一個fixture,所以也可以被其他fixture使用。如下所示:

import pytest

@pytest.fixture()
def foo(pytestconfig):
    return pytestconfig.option.foo

@pytest.fixture()
def myopt(pytestconfig):
    return pytestconfig.option.myopt

def test_fixtureForAddOption(foo,myopt):
    print(f"\nfoo   -- {foo}")
    print(f"\nmyopt -- {myopt}")

運行結果如下所示:

>>> pytest -v -s .\test_option.py
======================== test session starts =============================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson04\pytestconfig
collected 1 item

test_option.py::test_fixtureForAddOption
foo   -- Surpass

myopt -- False
PASSED

======================= 1 passed in 0.14s ================================

    除了使用pytestconfig自定義之外,也可以使用內置的選項和pytest啓動時的信息,如目錄、參數等。如所示:

def test_pytestconfig(pytestconfig):
    print(f"args : {pytestconfig.args}")
    print(f"ini file is : {pytestconfig.inifile}")
    print(f"root dir is : {pytestconfig.rootdir}")
    print(f"invocation dir is :{pytestconfig.invocation_dir}")
    print(f"-q, --quiet {pytestconfig.getoption('--quiet')}")
    print(f"-l, --showlocals:{pytestconfig.getoption('showlocals')}")
    print(f"--tb=style: {pytestconfig.getoption('tbstyle')}")

運行結果如下所示:

>>> pytest -v -s .\test_option.py
========================== test session starts ==========================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson04\pytestconfig
collected 1 item

test_option.py::test_pytestconfig args : ['.\\test_option.py']
ini file is : None
root dir is : C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson04\pytestconfig
invocation dir is :C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson04\pytestconfig
-q, --quiet 1
-l, --showlocals:False
--tb=style: auto
PASSED

==========================1 passed in 0.07s =================================

6.4 使用cache

    通常情況下,每個測試用例彼此都是獨立的,互不影響。但有時,一個測試用例運行完成後,希望將其結果傳遞給下一個測試用例,這種情況下,則需要使用pytest內置的cache。
    cache的作用是存在一段測試會話信息,在下一段測試會話中使用。使用pytest內置的--last-failed和--failed-first標識可以很好的展示cache功能。示例如下所示:

def test_A():
    assert 1==1

def test_B():
    assert 1==2

運行結果如下所示:

>>> pytest -v --tb=no .\test_04.py
=========================== test session starts =========================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson04
collected 2 items

test_04.py::test_A PASSED                                    [ 50%]
test_04.py::test_B FAILED                                    [100%]

======================== 1 failed, 1 passed in 0.08s ========================

    上面有一個測試用例運行失敗,再次使用--ff或--failed-first,則之前運行失敗的測試用例會首先被運行,然後才運行其他的測試用例,如下所示:

>>> pytest -v --tb=no --ff .\test_04.py
===================== test session starts ===========================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson04
collected 2 items
run-last-failure: rerun previous 1 failure first

test_04.py::test_B FAILED                                        [ 50%]
test_04.py::test_A PASSED                                        [100%]

======================= 1 failed, 1 passed in 0.14s ===================

    另外也可以使用--lf或--last-failed僅運行上次運行失敗的測試用例,如下所示:

>>>  pytest -v --tb=no --lf .\test_04.py
=================== test session starts ===============================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson04
collected 1 item
run-last-failure: rerun previous 1 failure

test_04.py::test_B FAILED                                        [100%]

========================1 failed in 0.07s =============================

    pytest是如何存儲並優先調用的呢?我們先來看看以下這個測試用例,如下所示:

import pytest
from pytest import approx

testData=[
    #x,y,res
    (1,2,3),
    (2,4,6),
    (3,5,8),
    (-1,-2,0)
]

@pytest.mark.parametrize("x,y,expect",testData)
def test_add(x,y,expect):
    res=x+y
    assert res==approx(expect)

運行結果如下所示:

>>> pytest -v -q .\test_04.py
================== test session starts =============================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson04
collected 4 items

test_04.py ...F                                           [100%]

================== FAILURES =======================================
___________________ test_add[-1--2-0] _____________________________

x = -1, y = -2, expect = 0

    @pytest.mark.parametrize("x,y,expect",testData)
    def test_add(x,y,expect):
        res=x+y
>       assert res==approx(expect)
E       assert -3 == 0 ± 1.0e-12
E        +  where 0 ± 1.0e-12 = approx(0)

test_04.py:16: AssertionError
=================== short test summary info =======================
FAILED test_04.py::test_add[-1--2-0] - assert -3 == 0 ± 1.0e-12
=================== 1 failed, 3 passed in 0.26s ===================

    根據報錯提示信息,我們一眼就能找到錯誤,那針對不是那麼好定位的問題的測試用例了,這個時候就需要使用--showlocals(簡寫-l)來調試失敗的測試用例。如下所示:

>>> pytest -q --lf -l .\test_04.py
F                                                        [100%]
========================= FAILURES =============================
________________________ test_add[-1--2-0] _____________________

x = -1, y = -2, expect = 0

    @pytest.mark.parametrize("x,y,expect",testData)
    def test_add(x,y,expect):
        res=x+y
>       assert res==approx(expect)
E       assert -3 == 0 ± 1.0e-12
E        +  where 0 ± 1.0e-12 = approx(0)

expect     = 0
res        = -3
x          = -1
y          = -2

test_04.py:16: AssertionError
======================== short test summary info ====================
FAILED test_04.py::test_add[-1--2-0] - assert -3 == 0 ± 1.0e-12
1 failed in 0.17s

    通過以上信息,可以很直觀看出問題所在位置,爲記住上次測試失敗的用例,pytest存儲了上一個測試會話中測試失敗的信息,可以使用--cache-show標識來顯示存儲的信息。

>>> pytest --cache-show
======================= test session starts ============================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson04
cachedir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson04\.pytest_cache
----------------------------- cache values for '*' ------------------------
cache\lastfailed contains:
  {'pytestconfig/test_03.py::test_myOption': True,
   'test_04.py::test_B': True,
   'test_04.py::test_add[-1--2-0]': True}
cache\nodeids contains:
  ['test_01.py::test_tmpDir',
   'test_02.py::test_getLoveCity',
   'test_02.py::test_getData',
   'test_04.py::test_A',
   'test_04.py::test_B',
   'pytestconfig/test_03.py::test_myOption',
   'pytestconfig/test_option.py::test_pytestconfig',
   'test_04.py::test_add[1-2-3]',
   'test_04.py::test_add[2-4-6]',
   'test_04.py::test_add[3-5-8]',
   'test_04.py::test_add[-1--2-0]']
cache\stepwise contains:
  []

========================no tests ran in 0.03s ==============================

    如果需要清空cache,可以在測試會話之前,傳入--clear-cache標識即可,cache除了--lf和--ff兩個標識之外,還可以使用其接口,如下所示:

cache.get(key,default)
cache.set(key,value)

習慣上,鍵名以應用名字或插件名字開始,接着是 / ,然後是分隔開的鍵字符串。鍵值可以是任何可轉化成JSON的東西,因爲在cache目錄中是用JSON格式存儲的。

    下面來創建一個fixture,記錄測試的耗時,並存儲到cache中,如果後面的測試耗時大於之前的2倍,就拋出超時異常。

import datetime
import time
import random
import pytest

@pytest.fixture(autouse=True)
def checkDuration(request,cache):
    key="duration/"+request.node.nodeid.replace(":","_")
    startTime=datetime.datetime.now()
    yield
    endTime=datetime.datetime.now()
    duration=(endTime-startTime).total_seconds()
    lastDuration=cache.get(key,None)
    cache.set(key,duration)
    if lastDuration is not None:
        errorString="test duration over twice last duration"
        assert duration <= 2 * lastDuration,errorString

@pytest.mark.parametrize("t",range(5))
def test_duration(t):
    time.sleep(random.randint(0,5))

    nodeid是一個獨特的標識,即便在參數化測試中也能使用。按以下步驟運行測試用例

>>> pytest -q --cache-clear .\test_04.py
.....                                                     [100%]
5 passed in 10.14s

>>> pytest -q --tb=line .\test_04.py
.E....E                                                   [100%]
========================== ERRORS ========================================
_________________ ERROR at teardown of test_duration[0] __________________
    assert 5.006229 <= (2 * 1.003045)
E   AssertionError: test duration over twice last duration
_________________ ERROR at teardown of test_duration[4] ___________________
    assert 4.149226 <= (2 * 1.005112)
E   AssertionError: test duration over twice last duration
================== short test summary info ================================
ERROR test_04.py::test_duration[0] - AssertionError: test duration over twice last duration
ERROR test_04.py::test_duration[4] - AssertionError: test duration over twice last duration
5 passed, 2 errors in 14.50s

>>> pytest -q --cache-show
cachedir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson04\.pytest_cache
----------------------- cache values for '*' -----------------------------------------
cache\lastfailed contains:
  {'test_04.py::test_duration[0]': True, 'test_04.py::test_duration[4]': True}
cache\nodeids contains:
  ['test_04.py::test_duration[0]',
   'test_04.py::test_duration[1]',
   'test_04.py::test_duration[2]',
   'test_04.py::test_duration[3]',
   'test_04.py::test_duration[4]']
cache\stepwise contains:
  []
duration\test_04.py__test_duration[0] contains:
  5.006229
duration\test_04.py__test_duration[1] contains:
  0.001998
duration\test_04.py__test_duration[2] contains:
  1.006201
duration\test_04.py__test_duration[3] contains:
  4.007687
duration\test_04.py__test_duration[4] contains:
  4.149226

no tests ran in 0.03s

    因爲cache數據有前綴,可以直接看見duration數據。

6.5 使用capsys

    pytest內置的capsys主要有兩個功能

  • 允許使用代碼讀取stdout和stderr
  • 可以臨時禁止抓取日誌輸出

1.讀取stdout

def greeting(name):
    print(f"Hello,{name}")

def test_greeting(capsys):
    greeting("Surpass")
    out,err=capsys.readouterr()
    assert "Hello,Surpass" in out
    assert err==""

運行結果如下所示:

>>> pytest -v .\test_05.py
========================= test session starts ============================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson04
collected 1 item

test_05.py::test_greeting PASSED                                    [100%]

====================== 1 passed in 0.08s ==================================

2.讀取stderr

import sys

def greeting(name):
    print(f"Hello,{name}",file=sys.stderr)

def test_greeting(capsys):
    greeting("Surpass")
    out,err=capsys.readouterr()
    assert "Hello,Surpass" in err
    assert out==""

運行結果如下所示:

>>> pytest -v .\test_05.py
==========================test session starts =============================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson04
collected 1 item

test_05.py::test_greeting PASSED                             [100%]

============================ 1 passed in 0.11s ===========================

    pytest通常會抓取測試用例及被測試代碼的輸出。而且是在全部測試會話結束後,抓取到的輸出纔會隨着失敗的測試顯示出來。--s參數可以關閉該功能,在測試仍在運行時就把輸出直接發送到stdout,但有時僅需要其中的部分信息,則可以使用capsys.disable(),可以臨時讓輸出繞過默認的輸出捕獲機制,示例如下所示:

def test_capsysDisable(capsys):
    with capsys.disabled():
        print("\nalways print this information")
    print("normal print,usually captured")

運行結果如下所示:

>>> pytest -q .\test_05.py

always print this information
.                                                        [100%]
1 passed in 0.02s

>>> pytest -q -s .\test_05.py

always print this information
normal print,usually captured
.
1 passed in 0.02s

    不管有沒有捕獲到輸出,always print this information始終都會顯示,是因爲其包含在capsys.disabled()的代碼塊中執行的。其他的打印語句是正常命令,在傳入-s參數纔會顯示。

-s標識是--capture=no的簡寫,表示關閉輸出捕獲

6.6 使用monkeypatch

    monkey patch可以在運行期間對類或模塊進行動態修改。在測試中,monkey patch常用於替換被測試代碼的部分運行環境或裝飾輸入依賴或輸出依賴替換成更容易測試的對象或函數。在pytest內置的monkey patch 允許單一環境中使用,並在測試結束後,無論結果是失敗或通過,所有修改都會復原。monkeypatch常用的函數如下所示:

setattr(target, name, value=<notset>, raising=True):   # 設置屬性
delattr(target, name=<notset>, raising=True):          # 刪除屬性
setitem(dic, name, value):                             # 設置字典中一個元素
delitem(dic, name, raising=True):                      # 刪除字典中一個元素
setenv(name, value, prepend=None):                     # 設置環境變量
delenv(name, raising=True):                            # 刪除環境變量
syspath_prepend(path)                                  # 將path路徑添加到sys.path中
chdir(path)                                            # 改變當前的工作路徑
  • 1.raising參數用於指示pytest在記錄不存在時,是否拋出異常
  • 2.setenv()中的prepend可以是一個字符,如果是這樣設置,則環境變量的值就是value+prepend+

    爲更好理解monkeypatch的實際應用方式,我們先來看看以下示例:

import os
import json

defaulData={
        "name":"Surpass",
        "age":28,
        "locate":"shangahi",
        "loveCity":{"shanghai":"shanghai",
                    "wuhai":"hubei",
                    "shenzheng":"guangdong"
                    }
               }

def readJSON():
    path=os.path.join(os.getcwd(),"surpass.json")
    with open(path,"r",encoding="utf8") as fo:
        data=json.load(fo)
    return data

def writeJSON(data:str):
    path = os.path.join(os.getcwd(), "surpass.json")
    with open(path,"w",encoding="utf8") as fo:
        json.dump(data,fo,ensure_ascii=False,indent=4)

def writeDefaultJSON():
    writeJSON(defaulData)

    writeDefaultJSON()既沒有參數也沒有返回值,該如何測試?仔細觀察函數,它會在當前目錄中保存一個JSON文件,那就可以從側面來進行測試。通常比較直接的方法,運行代碼並檢查文件的生成情況。如下所示:

def test_writeDefaultJSON():
    writeDefaultJSON()
    expectd=defaulData
    actual=readJSON()
    assert expectd==actual

    上面這種方法雖然可以進行測試,但卻覆蓋了原有文件內容。函數裏面所傳遞的路徑爲當前目錄,那如果將目錄換成臨時目錄了,示例如下所示:

def test_writeDefaultJSONChangeDir(tmpdir,monkeypatch):
    tmpDir=tmpdir.mkdir("TestDir")
    monkeypatch.chdir(tmpDir)
    writeDefaultJSON()
    expectd=defaulData
    actual=readJSON()
    assert expectd==actual

    以上這種雖然解決了目錄的問題,那如果測試過程,需要修改數據,又該如何,示例如下所示:

def test_writeDefaultJSONChangeDir(tmpdir,monkeypatch):
    tmpDir=tmpdir.mkdir("TestDir")
    monkeypatch.chdir(tmpDir)
    # 保存默認數據
    writeDefaultJSON()
    copyData=deepcopy(defaulData)
    # 增加項
    monkeypatch.setitem(defaulData,"hometown","hubei")
    monkeypatch.setitem(defaulData,"company",["Surpassme","Surmount"])
    addItemData=defaulData
    # 再次保存數據
    writeDefaultJSON()
    # 獲取保存的數據
    actual=readJSON()
    assert addItemData==actual
    assert copyData!=actual

    因爲默認的數據是字典格式的,所以可以使用setitem來進行添加鍵值對。

6.7 使用recwarn

    內置的recwarn可以用來檢查待測代碼產生的警告信息。在Python中,我們可以添加警告信息,很像斷言,但不阻止程序運行。假如在一份代碼,想要停止支持一個已經過時的函數,則可以在代碼中設置警告信息,示例如下所示:

import warnings
import pytest

def depricateFunc():
    warnings.warn("This function is not support after 3.8 version",DeprecationWarning)


def test_depricateFunc(recwarn):
    depricateFunc()
    assert len(recwarn)==1
    warnInfo=recwarn.pop()
    assert warnInfo.category==DeprecationWarning
    assert str(warnInfo.message) == "This function is not support after 3.8 version"

    recwarn的值就是一個警告信息列表,列表中的每個警告信息都有4個屬性category、message、filename、lineno。警告信息在測試開始後收集,如果待測的警告信息在最後,則可以在信息收集前使用recwarn.clear()清除不需要的內容。
    除recwarn,還可以使用pytest.warns()來檢查警告信息。示例如下所示:

import warnings
import pytest

def depricateFunc():
    warnings.warn("This function is not support after 3.8 version",DeprecationWarning)

def test_depricateFunc():
    with pytest.warns(None) as warnInfo:
        depricateFunc()
    assert len(warnInfo)==1
    w=warnInfo.pop()
    assert w.category==DeprecationWarning
    assert str(w.message) == "This function is not support after 3.8 version"

原文地址:https://www.cnblogs.com/surpassme/p/13258526.html

本文同步在微信訂閱號上發佈,如各位小夥伴們喜歡我的文章,也可以關注我的微信訂閱號:woaitest,或掃描下面的二維碼添加關注:
MyQRCode.jpg

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章