2023年pytest自动化测试框架教程 - 断言 - assert

以下总结基于:7.2.x

官网:https://docs.pytest.org/en/7.2.x/how-to/assert.html

延续Python标准库中的assert语句进行断言

支持显示常见的子表达式的值,包括调用、属性、比较以及二元和一元运算符

官方的例子:https://docs.pytest.org/en/7.2.x/example/reportingdemo.html#tbreportdemo

实战例子:判定接口返回的code是否为200

import requests

def get_user_info_api(user_id: int):
  	"""
  	获取指定user_id的用户信息并返回
  	"""
    payload = {'user_id': user_id}
	  response = requests.get('https://www.example.com/user', params=payload)
	  return response.json()
	  
def test_api_status():
  	"""
  	判定接口返回的`code`是否为`200`
  	"""
    code = get_user_info_api(user_id=1)['code']
    assert code == 200
    # assert code == 200, '返回的code非200,请检查.'  可以指定断言的msg
    

给预期异常断言

使用场景:测试时预计可能会发生某些异常,如RuntimeError/ZeroDivisionError/ValueError,可以使用pytest.raises()来管理上下文

  • 例子1:pytest.raises()捕获到预期的异常
import pytest


def test_zero_division():
    """
    1 / 0 会引发`ZeroDivisionError`异常,`pytest.raises()`捕获到预期的异常,用例执行成功
    相当于`python`中的`try except`捕获异常
    """
    with pytest.raises(ZeroDivisionError):
        1 / 0
    # 成功捕获后,做一些其他操作
  • 例子2:pytest.raises()未能捕获到预期的异常
def test_no_zero_division():
    """
    如果没有发生预期的异常,则该测试用例会执行失败
    """
    with pytest.raises(ZeroDivisionError):
        1 / 1
    # def test_zero_division():
    #     with pytest.raises(ZeroDivisionError):
    # >       1 / 1
    # E   Failed: DID NOT RAISE <class 'ZeroDivisionError'>
  • 例子3:获取异常的具体信息
import pytest

def test_user_status_value():
    """
		exc_info是`ExceptionInfo`的实例
    """
    with pytest.raises(ValueError) as exc_info:
        raise ValueError('用户状态必须为0.')
    assert exc_info.type is ValueError
    assert exc_info.value.args[0] == '用户状态必须为0.'  # 要获取到实际的value,需要用`.args[0]`
    assert exc_info.traceback is None
    
    # >       assert exc_info.traceback is None
    # E       AssertionError: assert [<TracebackEntry /Users/xxx/Desktop/pytest-starter/test_raise.py:53>] is None
    # E        +  where [<TracebackEntry /Users/xxx/Desktop/pytest-starter/test_raise.py:53>] = <ExceptionInfo ValueError('用户状态必须为0.') tblen=1>.traceback
  • 例子4:正则匹配异常
import pytest

# 正则匹配异常
def test_match_raise():
    """
    正则匹配异常
    """
    with pytest.raises(ValueError, match=r".* 1234 .*"):  # 底层通过`re.search`来正则匹配
        raise ValueError("Exception 123 raised")
    # with pytest.raises(ValueError, match=r".* 1234 .*"):
    # >    raise ValueError("Exception 123 raised")
    # E    AssertionError: Regex pattern did not match.
    # E    Regex: '.* 1234 .*'
    #      Input: 'Exception 123 raised'

标记预计会执行失败的测试用例

使用@pytest.mark.xfail()语法糖来标记

使用场景:期望该用例未来执行会失败,但是不会影响测试用例继续往下执行

注意:如果执行失败,结果会被标记为XFAIL,同时不会输出错误信息;相反,被标记@pytest.mark.xfail()的测试用例如果执行成功,结果会被标记为XPASS

import pytest

@pytest.mark.xfail()
def test_expected_fail():
    """
    执行失败的用例,会被标记为`XFAIL`
    """
    assert '这个用例预期会失败' == ''  # test_raise.py::test_expected_fail XFAIL
    
@pytest.mark.xfail()
def test_expected_fail():
    """
    执行成功的用例,会被标记为`XPASS`
    """
    assert 1 == 1  # test_raise.py::test_expected_fail XPASS
    

class TestXfail():
    """
    被`@pytest.mark.xfail()`标记后,不会影响后续用例执行
    """
    @pytest.mark.xfail()
    def test_expected_fail(self):
        assert 1 == 2

    def test_success(self):
        assert 1 == 1
    # test_raise.py::TestXfail::test_expected_fail XFAIL
    # test_raise.py::TestXfail::test_success PASSED

pytest.raises()@pytest.mark.xfail()使用区别

  • 对未来已知可能会发生的异常,建议使用pytest.raises()
  • 对系统中未修复的bug未完全实现的case,建议使用@pytest.mark.xfail()来标记,后续变更,类似// TODO

附:pytest.raises()API说明

官方:https://docs.pytest.org/en/7.2.x/reference/reference.html#pytest.raises

import pytest

pytest.raises(ExpectedException, func, *args, **kwargs)
# 可以传递一个将使用给定的 *args 和 **kwargs 执行的func,并断言引发了给定的ExpectedException
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值