Pytest07--断言

断言

pytest测试结果通过还是失败与if等无关,只认识pytest断言
如果没有断言,执行pytest测试用例时,pytest始终会说测试通过

断言的形式

assert 表达式,断言失败消息文本
只能指定断言失败消息,不能指定断言成功消息
断言失败消息可以省略
当断言失败时,pytest会抛出断言失败异常

预期结果==实际结果
实际结果==预期结果
实际>预期   

表达式中使用运算符

  ==、!=
  <、<=、>、>=
  in、not  in

被测程序calc.py

class Calc:
    def add(self,a,b):
        return a+b
    def sub(self,a,b):
        return a--b

测试固件conftest.py

import pytest
# @pytest.fixture(scope='module',autouse=True) #每个模块之前执行
# def init():
#     print('每个模块之前执行')
@pytest.fixture(scope='session',autouse=True) #所有测试之前执行
def init():
    print('所有测试之前执行')

简化断言异常信息

[ ‘--tb= auto | long | native |short | line | no’ ]
tb表示错误跟踪
参数含义
①auto、long:显示完整的测试代码、断言异常信息、断言失败消息、异常总结信息
②native:显示出现异常的测试代码行、断言异常信息、断言失败消息、异常总结信息
③short:输出断言异常信息,断言失败消息,异常总结信息
④line:输出断言失败消息,以及异常总结信息
⑤no:不输出异常信息,只有异常总结信息

实现断言 demo01.py

# 断言
import calc, pytest


def test_add():
    case = [1, 2, 3]
    a, b, expect = case
    actual = calc.Calc().add(a, b)
    assert expect == actual, f'测试失败==预期:{expect}==实际:{actual}'  # assert:断言、断定


def test_sub():
    case = [1, 2, -1]
    a, b, expect = case
    actual = calc.Calc().sub(a, b)
    assert expect == actual, f'测试失败==预期:{expect}==实际:{actual}'


if __name__ == '__main__':
    pytest.main(['-sv', '--tb=line', 'demo01.py'])

调整断言结合异常处理 demo02.py

#断言
import calc, pytest
def test_add():
    case=[1,2,3]
    a,b,expect=case
    actual=calc.Calc().add(a,b)
    if expect==actual:
        res=True
        print('测试通过')
    else:
        res=False
        print(f'测试失败==预期:{expect}==实际:{actual}')
    assert res==True, f'测试失败==预期:{expect}==实际:{actual}' #assert:断言、断定
def test_sub():
    case=[1,2,-1]
    a,b,expect=case
    actual=calc.Calc().sub(a,b)
    try:
        assert expect==actual #如果断言失败,会抛出异常
        print('测试通过')
    except AssertionError: #AssertionError:断言失败异常
        print(f'测试失败==预期:{expect}==实际:{actual}')
        raise AssertionError(f'测试失败==预期:{expect}==实际:{actual}')
if __name__=='__main__':
    pytest.main(['-sv','--tb=line','demo02.py'])
    # pytest.main(['-s', '--tb=line', 'demo02.py']) 错误

断言失败继续运行执行测试 demo03.py

import calc, pytest
def testAddSub():
    case=[1,2,-3,-1]
    a,b,expect_add,expect_sub=case
    actual_add=calc.Calc().add(a,b)
    actual_sub=calc.Calc().sub(a,b)
    # assert actual_add == expect_add, f'测试sub失败==预期:{expect_add}==实际:{actual_add}'
    # print('测试加法完毕')
    # try:
    #     assert actual_sub==expect_sub, f'测试sub失败==预期:{expect_sub}==实际:{actual_sub}' #assert一旦测试失败,则停止当前函数中本轮测试
    # finally: #不论有无发生异常,均执行下面的代码
    #     print('测试减法完毕')
    try:
        assert actual_sub == expect_sub, f'测试sub失败==预期:{expect_sub}==实际:{actual_sub}'  # assert一旦测试失败,则停止当前函数中本轮测试
    finally:  # 不论有无发生异常,均执行下面的代码
        print('测试减法完毕')
        assert actual_add == expect_add, f'测试sub失败==预期:{expect_add}==实际:{actual_add}'
        print('测试加法完毕')
if __name__=='__main__':
    pytest.main(['-sv','--tb=no','demo03.py'])

断言失败停止执行

from calc import Calc
import pytest


def test_add_sub():
    c = Calc()
    actual = c.add(3, 4)
    expect = 7
    assert actual == expect, f'断言失败==预期:{expect}==实际:{actual}'
    actual = c.sub(3, 4)
    expect = -1
    assert actual == expect, f'断言失败==预期:{expect}==实际:{actual}'
    actual = c.sub(3, -1)  # 一旦断言失败,后续代码停止执行
    expect = 4
    assert actual == expect, f'断言失败==预期:{expect}==实际:{actual}'


if __name__ == '__main__':
    pytest.main(['-v', 'demo04.py'])

断言失败继续

assert断言的缺点

1)在一个测试函数或测试方法中,如果有多个断言,或者断言后面还有其他代码,一旦前面的断言失败(可能发现了缺陷),则断言后面的代码全部不再执行
2)但不影响下一条用例的执行,assert不执行的是断言失败的那条用例
3)有些流程测试,比如注册失败,则登录不需要测试了,可以考虑assert断言

pytest-assume断言

1)支持断言失败时,继续执行代码
2)步骤
①安装pytest-assume(插件)
②导入模块pytest
③形式

  pytest.assume(表达式,断言失败消息)

处理断言失败消息

from calc import Calc
import pytest


def test_add_sub():
    c = Calc()
    actual = c.add(3, 4)
    pytest.assume(actual == 7, f'断言失败==预期:7==实际:{actual}')
    actual = c.sub(3, 4)
    pytest.assume(actual == -1, f'断言失败==预期:-1==实际:{actual}')
    actual = c.sub(3, -1)
    pytest.assume(actual == 4, f'断言失败==预期:4==实际:{actual}')
    # assert actual==4, f'断言失败==预期:4==实际:{actual}'

if __name__ == '__main__':
    pytest.main(['-v', '--tb=short', 'demo02.py'])

上一篇:剑指offer系列之一:从尾到头打印链表


下一篇:接口自动化 - pytest-fixture -scope作用范围