pytest测试框架(一)

2022-02-18  本文已影响0人  在下YM

初识Pytest

Pytest 第一个例子

import pytest
import requests


def test_one():
    r = requests.get('https://www.baidu.com')
    print(r.status_code)

def test_two():
    r = requests.get('https://www.baidu.com')
    print(r.encoding)

class TestTask(object):
    def test_1(self):
        print('test 1')

    def test_2(self):
        print('test 2')

if __name__ == '__main__':
    pytest.main() # pytest
============================= test session starts ==============================
platform darwin -- Python 3.7.3, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: /Users/xiaoyidemac/Desktop/测试
plugins: tavern-1.16.3, openfiles-0.3.2, arraydiff-0.3, allure-pytest-2.9.45, doctestplus-0.3.0, remotedata-0.3.1collected 4 items

pytest_code.py .200
.ISO-8859-1
                                                      [100%]

============================== 4 passed in 0.29s ===============================

Process finished with exit code 0
.test 1
.test 2

pytest运行方式

通过代码中pytest.main()可以右键直接运行,相当于python test_1.py;也可以通过命令行的方式启动运行

代码中运行的方式
上述四种方式皆有对应的命令行运行的方式

注意:

断言的处理

assert

什么是断言

断言的使用场景

assert断言语句

assert expression [, arguments]
# expression 为 True 则 pass
# expression 为 False 则 抛出异常,有 argument 则输出 argument
'''
expression:
1)比较运算
2)逻辑运算  and | or | not
3)身份运算  is | is not
4)成员运算  in | not in
'''

示例代码:

import requests

def test_assert():
    r = requests.get('http://www.baidu.com')
    assert r.status_code == 200, "没有返回200,断言失败"

异常断言

pytest.raises()的使用

import pytest


def is_leap_year(year):
    # 先判断year是不是整型
    if isinstance(year, int) is not True:
        raise TypeError("传入的参数不是整数")
    elif year == 0:
        raise ValueError("公元元年是从公元一年开始!!")
    elif abs(year) != year:
        raise ValueError("传入的参数不是正整数")
    elif (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
        print("%d年是闰年" % year)
        return True
    else:
        print("%d年不是闰年" % year)
        return False


class TestAssert(object):
    """对判断是否是闰年的方法进行测试"""

    def test_exception_typeerror(self):
        # 使用 pytest.raises 作为上下文管理器,捕获给定异常类型TypeError
        # is_leap_year('2020')抛出TypeError,被pytest.raises捕获到,则测试用例执行通过
        with pytest.raises(TypeError):
            # 传入字符串引发类型错误
            is_leap_year('2020')

运行结果如下:

============================= test session starts ==============================
platform darwin -- Python 3.7.3, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: /Users/xiaoyidemac/Desktop/测试
plugins: tavern-1.16.3, openfiles-0.3.2, arraydiff-0.3, allure-pytest-2.9.45, doctestplus-0.3.0, remotedata-0.3.1collected 1 item

pytest_code.py                                                          [100%]

============================== 1 passed in 0.06s ===============================

把异常信息存储到变量

有时候我们可能需要在测试用到产生的异常信息,我们可以把异常信息存储到一个变量中,变量的类型为 异常类 ,包含异常的 type、value 或者 traceback 等信息。

import pytest

def is_leap_year(year):
    # 先判断year是不是整型
    if isinstance(year, int) is not True:
        raise TypeError("传入的参数不是整数")
    elif year == 0:
        raise ValueError("公元元年是从公元一年开始!!")
    elif abs(year) != year:
        raise ValueError("传入的参数不是正整数")
    elif (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
        print("%d年是闰年" % year)
        return True
    else:
        print("%d年不是闰年" % year)
        return False

class TestAssert(object):
    """对判断是否是闰年的方法进行测试"""

    def test_exception_typeerror(self):
        # 预测到参数不符合要求,会抛出TypeError异常;若出现该异常,则测试用例执行通过
        with pytest.raises(TypeError) as err_info:
            # 传入字符串引发类型错误
            is_leap_year('2020')
        # 断言异常的类型是 TypeError,断言成功则不会抛出异常
        assert err_info.type == TypeError, '错误类型不匹配'

通过异常的内容捕捉异常

import pytest

def is_leap_year(year):
    # 先判断year是不是整型
    if isinstance(year, int) is not True:
        raise TypeError("传入的参数不是整数")
    elif year == 0:
        raise ValueError("公元元年是从公元一年开始!!")
    elif abs(year) != year:
        raise ValueError("传入的参数不是正整数")
    elif (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
        print("%d年是闰年" % year)
        return True
    else:
        print("%d年不是闰年" % year)
        return False


class TestAssert(object):
    """对判断是否是闰年的方法进行测试"""
    def test_exception_typeerror(self):
        # 通过异常的内容捕捉异常,但具体是何种异常不清楚
        with pytest.raises(Exception, match='从公元一年开始') as err_info:
            is_leap_year(0)
        # 断言异常的类型是 ValueError,断言成功则不会抛出异常
        assert err_info.type == ValueError

警告断言

pytest.warns()的使用

import pytest
import warnings

def make_warn():
    # 抛出
    warnings.warn("deprecated", DeprecationWarning)

def not_warn():
    pass

def user_warn():
    warnings.warn("user warn", UserWarning)


class TestWarns(object):
    def test_make_warn(self):
        with pytest.warns(DeprecationWarning):
            make_warn()

    def test_not_warn(self):
        # 断言not_warn函数将会抛出警告
        # 但实际是没有抛出警告的,所以无法通过测试
        with pytest.warns(Warning):
            not_warn()

    def test_user_warn(self):
        with pytest.warns(UserWarning):
            user_warn()

运行结果如下:


================================================== test session starts ===================================================
platform linux -- Python 3.6.8, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
rootdir: /home/python/code/unit_testing/pytest_code
collected 3 items                                                                                                        

test_7.py .F.                                                                                                      [100%]

======================================================== FAILURES ========================================================
________________________________________________ TestWarns.test_not_warn _________________________________________________

self = 

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

test_7.py:24: Failed
================================================ short test summary info =================================================
FAILED test_7.py::TestWarns::test_not_warn - Failed: DID NOT WARN. No warnings of type (,) was emitted...
============================================== 1 failed, 2 passed in 0.04s ===============================================

把警告信息存储到变量

将告警信息存入一个变量中,通过读取这个变量中的信息进行断言,包括:告警的个数、告警信息参数等。

# pytest_code/test_8.py
import warnings
import pytest

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

def test_warn_match():
    with pytest.warns((UserWarning, RuntimeWarning)) as record:
        warn_message()
    assert len(record) == 2
    assert str(record[0].message) == "user"
    assert str(record[1].message) == "runtime"
    assert record[0].category == UserWarning
    assert record[1].category == RuntimeWarning

运行结果如下:

$ pytest test_8.py
================================================== test session starts ===================================================
platform linux -- Python 3.6.8, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
rootdir: /home/python/code/unit_testing/pytest_code
collected 1 item                                                                                                         

test_8.py .                                                                                                        [100%]

=================================================== 1 passed in 0.01s ====================================================

通过警告的内容捕捉警告

# pytest_code/test_9.py
import warnings
import pytest


def make_warn():
    # 抛出
    warnings.warn("deprecated", DeprecationWarning)


def not_warn():
    pass

def user_warn():
    warnings.warn("user warn", UserWarning)


class TestWarns(object):
    def test_make_warn(self):
        # 捕获警告内容为deprecated的警告
        with pytest.warns(Warning, match='deprecated'):
            make_warn()
上一篇下一篇

猜你喜欢

热点阅读