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+<old value>

    为更好理解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"
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342