[接口测试_B] 04 Pytest断言处理_告警断言

pytest中对告警进行断言采用pytest.warns()方法,其断言的方法与pytest.raises()类似。pytest.warns()除了能断言告警外,还能够捕获告警信息,并对捕获的告警信息进行分类处理,可以设定出现特定告警信息时,则用例执行失败。

Pytest的pytest.warns()用法

  • pytest.warns()断言告警信息
  • pytest.warns()捕获告警信息,并对告警信息进行判断
  • pytest.warns()记录告警信息

1、pytest.warns()断言告警信息

pytest.warns()断言,适用于被测方法会抛出特定告警,当出现这类告警则用例通过,否则用例失败。

1.1采用pytest.warns()检查代码抛出的告警,如果没有对应的告警抛出,则用例失败.示例中设定了一个失败用例和一个成功用例:
# make_warnings.py
import warnings
def fxn():
    warnings.warn("deprecated", DeprecationWarning)
def not_warn():
    pass

对上面的2个方法进行测试:

import sys
sys.path.append(".")
import pytest
import make_warnings

class TestWarns():
    def test_depre(self):
        with pytest.warns(DeprecationWarning):
            make_warnings.fxn()

    def test_not_warn(self):
        with pytest.warns(DeprecationWarning):
            make_warnings.not_warn()

运行结果:

PS E:\python_interface_test\requests_practice> pytest -q .\test_warns.py
.F                                                                       [100%]
================================== FAILURES ===================================
___________________________ TestWarns.test_not_warn ___________________________

self = <requests_practice.test_warns.TestWarns object at 0x000001D3915AF2E8>

    def test_not_warn(self):
        with pytest.warns(DeprecationWarning):
>           make_warnings.not_warn()
E           Failed: DID NOT WARN. No warnings of type (<class 'DeprecationWarning'>,) was emitted. The list of emitted warnings is: [].

test_warns.py:14: Failed
1 failed, 1 passed in 0.06 seconds

从运行结果中看出,第2个用例执行失败,是因为该方法不会抛出告警。从失败结果中The list of emitted warnings is: []看出,告警信息存储在list中。

1.2 采用match正则匹配抛出的告警信息,若告警信息和告警类型不同时匹配,则用例执行失败
import warnings
import pytest

def warn_message():
    warnings.warn("I'm a warning message", UserWarning)

def test_warn_match():
    with pytest.warns(UserWarning, match=r'^I.*e'):
        warn_message()
    # warn_message() # 加上这句,执行用例会看到抛出的告警
1.3 将告警信息存入一个变量中,通过读取这个变量中的信息进行断言,包括:告警的个数、告警信息参数等。
import warnings
import pytest

def warn_message():
    warnings.warn("user", UserWarning)
    warnings.warn("runtime", RuntimeWarning)

def test_warn_match():
    with pytest.warns(UserWarning, match=r'.*t.*') as record:
        warn_message()
    assert len(record) == 2
    assert str(record[0].message) == "user"
    assert str(record[1].message) == "runtime"

运行结果:

PS E:\python_interface_test\requests_practice> pytest -q .\test_warns.py
F                                                                        [100%]
================================== FAILURES ===================================
_______________________________ test_warn_match _______________________________

    def test_warn_match():
        with pytest.warns(UserWarning, match=r'.*t.*') as record:
>           warn_message()

test_warns.py:13:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
....
E Failed: DID NOT WARN. No warnings of type (<class 'UserWarning'>,) matching ('.*t.*') was emitted. 
The list of emitted warnings is: [UserWarning('user',), RuntimeWarning('runtime',)].
...
1 failed in 0.07 seconds

从运行结果中,可以看到,返回的list中存储了2个warnings信息,即record是一个list,可以计算长度,并通过record[i].message获取告警信息。
PS:将示例中的match=r'.*t.*'更改为match=r'.*u.*'即可执行成功。


下面不是pytest.warns()的断言介绍了



pytest捕获告警信息

  • pytest默认捕获除DeprecationWarning和PendingDeprecationWarning外的所有告警信息,可以在pytest.ini中进行配置,使出现这两类告警时也会抛出告警信息:
# pytest.ini
[pytest]
filterwarnings =
    once::DeprecationWarning
    once::PendingDeprecationWarning
  • 如果出现特定告警需要使用例执行失败,可以采用-W命令:pytest -q test_show_warnings.py -W error::UserWarning
  • 可以在pytest.ini中设置过滤或者执行失败,在这个过滤条件中,除UserWarning外的告警都会识别为错误进行处理。
# pytest.ini
[pytest]
filterwarnings =
    error
    ignore::UserWarning
  • pytest的标记函数处理告警信息
# 忽略function中的告警
@pytest.mark.filterwarnings('ignore:function')

# 将用例中所有的告警都转换为错误,将装饰器作用于测试类,则测试类中的所有用例出现告警都会失败
@pytest.mark.filterwarnings('error')
  • 不捕获告警信息,可以在文件中进行配置,或者在命令行传递-p no:warnings,那么当用例存在告警信息时,都不会在结果中输出告警信息:
# pytest.ini
[pytest]
addopts = -p no:warnings

pytest记录告警信息

  • 可以采用recwarn fixture记录函数的全部告警信息
    每个告警记录包含以下属性:
  • message
  • category
  • filename
  • lineno
  • file
  • line

每个告警记录具有list的属性,可调用以下方法:

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

推荐阅读更多精彩内容