前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >pytest系列教程——2、pytest断言的使用

pytest系列教程——2、pytest断言的使用

作者头像
胡八万
发布2022-06-08 15:43:28
1K0
发布2022-06-08 15:43:28
举报
文章被收录于专栏:软件测试技术软件测试技术

上一章学习了pytest的基本用法,今天学习一下断言。

assert 基本用法

unitest单元测试框架中提供了丰富的断言方法,如assertEqual()、assertIn()、assertTrue()、assertIs()等,但是pytest没有。直接使用Python的assert进行断言

代码语言:javascript
复制
# MyPytest.py
import pytest

def inc(x):
    return x+1

# 判断结果不等于5
def test_inc_01():
    assert inc(3) != 5

# 判断结果等于4
def test_inc_02():
    assert inc(3) == 4

# 判断结果小于等于5
def test_inc_03():
    assert inc(3) <= 5

# 判断结果包含在列表内
def test_inc_04():
    assert inc(3)  in  [1,2,3,4]


# 判断结果不为True
def test_inc_06():
    a = 1 
    assert a ==  True
    assert a is not  True



if __name__ =="__main__":
    pytest.main(['MyPytest.py'])

执行结果:

代码语言:javascript
复制
collected 5 items

MyPytest.py .....                                                        [100%]

============================== 5 passed in 0.08s ==============================

***Repl Closed***

assert断言失败提示

当我们为了脚本报错后更容易的定位到原因时候,可以在断言的地方输出断言失败提示信息,比如:

代码语言:javascript
复制
# MyPytest.py
import pytest

def division(x):
    return 100/x


def test_division_01():
    res = division(3)
    assert res == 50 , f"判断 res 为50 ,当前 res 的值为{res}" 


if __name__ =="__main__":
    pytest.main(['MyPytest.py'])

执行结果:

代码语言:javascript
复制
collected 1 item

MyPytest.py F                                                            [100%]

================================== FAILURES ===================================
______________________________ test_division_01 _______________________________

    def test_division_01():
        res = division(3)
>       assert res == 50 , f"判断 res 为50 ,当前 res 的值为{res}"
E       AssertionError: 判断 res 为50 ,当前 res 的值为33.333333333333336
E       assert 33.333333333333336 == 50

MyPytest.py:10: AssertionError
=========================== short test summary info ===========================
FAILED MyPytest.py::test_division_01 - AssertionError: 判断 res 为50 ,当前 r...
============================== 1 failed in 0.21s ==============================

***Repl Closed***

预期内异常报错断言

有时候一些场景我们明知道它会报错,也知道这种报错,是正常的预期,比如:

代码语言:javascript
复制
# MyPytest.py
import pytest

def division(x):
    return 100/x


def test_division_01():
    res = division(0)


if __name__ =="__main__":
    pytest.main(['MyPytest.py'])

执行结果:

代码语言:javascript
复制
collected 1 item
MyPytest.py F                                                            [100%]

================================== FAILURES ===================================
______________________________ test_division_01 _______________________________
    def test_division_01():
>       res = division(0)
MyPytest.py:9: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
x = 0
    def division(x):
>       return 100/x
E       ZeroDivisionError: division by zero
MyPytest.py:5: ZeroDivisionError
=========================== short test summary info ===========================
FAILED MyPytest.py::test_division_01 - ZeroDivisionError: division by zero
============================== 1 failed in 0.21s ==============================

***Repl Closed***

100 \ 0的时候报错ZeroDivisionError: division by zero。为了对这种异常场景进行断言,我们需要使用pytest.raises,用法如下:

代码语言:javascript
复制
# MyPytest.py
import pytest

def division(x):
    return 100/x
    
def test_division_01():
    with pytest.raises(ZeroDivisionError) as e:
        division(0)
    assert e.type == ZeroDivisionError
    assert "division by zero" in str(e.value) 

if __name__ =="__main__":
    pytest.main(['MyPytest.py'])

注意:断言 type 的时候,异常类型是不需要加引号的,断言 value 值的时候需转 str

非预期内异常

如果我们不知道预期异常的是什么,我们可以使用matchraise进行自定义异常

代码语言:javascript
复制
# MyPytest.py
import pytest

def division(x):
    if x == 0:
        raise ValueError('value not 0 or None')
    if isinstance(x,str):
        raise TypeError('value not String')
    return 100/x


def test_division_01():
    with pytest.raises(ValueError,match = 'value not 0 or None') as e:
        division(0)
    assert e.type == ValueError
    assert "value not 0 or None" in str(e.value) 


def test_division_02():
    with pytest.raises(TypeError,match = 'value not String') as e:
        division("String")
    assert e.type == TypeError
    assert "value not String" in str(e.value) 

if __name__ =="__main__":
    pytest.main(['MyPytest.py'])

pytest-assume插件

pytest-assume是一个可以允许pytest测试用例中执行多个失败的断言的插件。安装

pip install pytest-assume

对比assert :

代码语言:javascript
复制
import pytest

def inc(x):
    return x+1

# assert断言
def test_inc_01():
    assert inc(3) == 5
    assert inc(3) == 4
    assert inc(3) == 3


# pytest.assume断言
def test_inc_02():
    pytest.assume(inc(3) == 5)
    pytest.assume(inc(3) == 4)
    pytest.assume(inc(3) == 3)


if __name__ =="__main__":
    pytest.main(['MyPytest.py'])

结果:

代码语言:javascript
复制
collected 2 items

MyPytest.py FF                                                           [100%]

================================== FAILURES ===================================
_________________________________ test_inc_01 _________________________________
    def test_inc_01():
>       assert inc(3) == 5
E       assert 4 == 5
E        +  where 4 = inc(3)
MyPytest.py:8: AssertionError
_________________________________ test_inc_02 _________________________________

tp = <class 'pytest_assume.plugin.FailedAssumption'>, value = None, tb = None
    def reraise(tp, value, tb=None):
        try:
            if value is None:
                value = tp()
            if value.__traceback__ is not tb:
>               raise value.with_traceback(tb)
E               pytest_assume.plugin.FailedAssumption: 
E               2 Failed Assumptions:
E               
E               MyPytest.py:15: AssumptionFailure
E               >> pytest.assume(inc(3) == 5)
E               AssertionError: assert False
E               
E               MyPytest.py:17: AssumptionFailure
E               >> pytest.assume(inc(3) == 3)
E               AssertionError: assert False

D:\software\python\lib\site-packages\six.py:718: FailedAssumption
=========================== short test summary info ===========================
FAILED MyPytest.py::test_inc_01 - assert 4 == 5
FAILED MyPytest.py::test_inc_02 - pytest_assume.plugin.FailedAssumption: 
============================== 2 failed in 0.26s ==============================
***Repl Closed***

对比发现,pytest.assume在第一个断言失败的情况下继续执行后续的断言,不会终止~

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 软件测试技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • assert 基本用法
  • assert断言失败提示
  • 预期内异常报错断言
  • 非预期内异常
  • pytest-assume插件
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档