单元测试&Pytest

本文深入介绍了Python的测试框架Pytest,包括其易用性、丰富的文档、对单元测试和功能测试的支持、参数化、跳过与标记功能、与持续集成的集成。此外,详细讲解了assert断言、异常断言和警告断言的使用,以及setup和teardown函数的作用。还展示了pytest.mark.parametrize的用法,以及如何读写Yaml文件。
摘要由CSDN通过智能技术生成

Pytest

  • 是一个命令行工具,编写用例简单,可读性强
  • 非常容易上手,入门简单,文档丰富,文档中有很多实例可以参考
  • 支持单元测试和功能测试
  • 支持参数化
  • 执行测试过程中可以将某些测试跳过,或者对某些预期失败的Case标记成失败
  • 支持重复执行失败的Case
  • 支持运行由unittest编写的测试Case
  • 具有很多第三方插件,并且可以自定义扩展
  • 方便的和持续集成工具集成
  • 可以运行以test开头或test结尾的包、文件和方法
  • 可以使用assert进行断言

下面是pytest例子

import pytest

def test_1():
    print('test_11111111')

def test_2():
    print('test_222222222')

def xxx_1(): # 不会执行
    print("xxx_11111111")

class TestDemo(object): # 如果类名不是以Test开头,也不执行
    def test_3(self):
        print('test_33333333')

    def test_4(self):
        print('test_44444444')

    def xxx_2(self): # 不会执行
        print("xxx_22222222")

if __name__ == '__main__':
    # 默认不打印,需要加上-s参数, []中元素是字符串
    pytest.main(['-s'])

=====================================================
pytest -s  # 运行当前目录所有test开头的文件
pytest -s xxx.py  # 运行指定的文件

# 代码
pytest.main(['-s'])
pytest.main(['-s', 'xxx.py'])

断言的处理

  • assert:预期结果、实际结果,对比
  • 异常断言:预期异常、实际异常,对比
  • 警告断言:预期警告、实际警告,对比
# assert断言语句
def test_1():
    num = 1 + 1
    # assert 条件, 产生异常的提示信息
    assert num == 3, 'num==2条件不满足'
==============================================
# 异常断言
# 前面加上_,为了不让其执行
def _test_1():
    # with pytest.raises(预期的异常类型):
    #           实际产生的异常
    # 如果实际产生的异常和预期的异常类型一样,测试通过
    # with pytest.raises(TypeError):
    with pytest.raises(ValueError):
        is_leap_year('2020') # 产生TypeError

def test_2():
    # with pytest.raises(预期的异常类型) as 异常对象:
    #           实际产生的异常
    # 如果实际产生的异常和预期的异常类型一样,测试通过
    with pytest.raises(TypeError) as err_info:
        is_leap_year('2020') # 产生TypeError

    if err_info.type == TypeError:
        print('err_info保存了异常信息')
       
# 通过异常的内容捕捉异常
def test_3():
    # 断言:预期异常为ValueError,同时内容为"传入的参数不是正整数"
    with pytest.raises(ValueError, match="传入的参数不是正整数") as err_info:
        is_leap_year(-100) # 产生ValueError

    if err_info.type == ValueError:
        print('err_info保存了异常信息')
==================================================================
# 警告断言
import warnings
import pytest


# 前面加上_,为了不让其执行
def _test_1():
    # with pytest.warns(预期的警告类型):
    #           实际产生的警告
    # 如果实际产生的警告和预期的警告类型一样,测试通过
    with pytest.warns(RuntimeWarning):
        warnings.warn("my warning", RuntimeWarning)

def _test_2():
    # 警告断言,可以同时断言多个,异常不可以
    with pytest.warns((RuntimeWarning, UserWarning)) as warn_info:
        warnings.warn("my warning aaaaa", RuntimeWarning)
        warnings.warn("value must be 0 or None", UserWarning)
        # print('11111111111111')

    # warn_info对象的成员,它是列表
    print(warn_info.__dict__)
    print(len(warn_info))
    print(warn_info[0].__dict__) # 第0个对象的成员信息
    print(warn_info[0].category)
    print(warn_info[0].message)

def test_3():
    # 断言: 警告为RuntimeWarning,通过内容包含warning
    with pytest.warns(RuntimeWarning, match='warning'):
        warnings.warn("my warning", RuntimeWarning)

if __name__ == '__main__':
    # 默认不打印,需要加上-s参数, []中元素是字符串
    pytest.main(['-s', 'test_5_warns.py'])

setup和teardown函数

  • 函数级别:

    • 作用域为普通函数
    • setup_function, teardown_function,普通测试用例函数前后执行一次
  • 类级别

    • 作用域为类:类、实例方法
    • setup_class 和 teardown_class , 类的前后执行1次
    • setup_method, teardown_method,测试用例实例方法前后各执行1次
  • 模块级别

    • 作用域:运行的文件
    • setup_module(), teardown_module() 定义在类外
    • 文件的前后,执行1次

pytest.mark.parametrize用法

import pytest

@pytest.mark.parametrize(['usrname', 'pwd'], [('mike', '123'), ('yoyo', 'abc')])
def test_login(usrname, pwd):
    print('usrname = %s, pwd = %s' % (usrname, pwd))

Yaml

Yaml 是一种所有编程语言可用的友好的数据序列化标准,类似于 json。其语法和其他高阶语言类似, 并且可以简单表达列表、字典、标量等资料形式。
<大部分以空格来间隔数据>

读取yaml文件
{ Search_Data: 
   { 
     search_test_001: { value: 456, expect: [ 4, 5, 6 ] },
     search_test_002: { value: '你好', expect: { value: '你好' } } 
   } 

}
====================================================================
import yaml

# 1. 只读方式打开文件,文件对象
# 2. 读取内容 = yaml.load(文件对象, Loader=yaml.FullLoader)

with open('./info.yaml') as f:
    ret = yaml.load(f, Loader=yaml.FullLoader)
    print(ret)
写入yaml文件内容
import yaml

data={'Search_Data': {
          'search_test_002': {'expect': {'value': '你好'}, 'value': '你好'},
          'search_test_001': {'expect': [4, 5, 6], 'value': 456}
                        }
}

# 1. 只写方式,指定utf-8编码打开文件,有一个文件对象
# 2. yaml.dump(写入文件的数据, 上一步的文件对象, allow_unicode=True)

with open('xxx.yaml', 'w', encoding='utf-8') as f:
    yaml.dump(data, f, allow_unicode=True)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值