Pytest框架实战--2--print--loguru--封装

Pytest教程

Pytest框架中print的奇怪现象

test_02_01.py

"""
pytest 中print的使用
"""
from assertpy import assert_that
import pytest


# fun1为我们测试的函数:传一个参数自动+1
def fun1(x):
    """
    假如我们开发的时候不小心把1写成了0.1
    :param x:
    :return:
    """
    return x + 0.1


def test_fun1():
    print('这是失败的用例,这个print会打印')
    assert_that(fun1(10)).is_equal_to(11)


def test_fun2():
    print('这是成功的用例,这个print不会打印')
    assert_that(fun1(10)).is_instance_of(float)

我们在终端执行

pytest .\test_02_01.py

输出结果:

PS D:\code\pytest_test\test_2_day> pytest .\test_02_01.py
============================================================ test session starts 
        print('这是失败的用例,这个print会打印')
>       assert_that(fun1(10)).is_equal_to(11)
E       AssertionError: Expected <10.1> to be equal to <11>, but was not.

test_02_01.py:20: AssertionError
----------------------------------------------------------- Captured stdout call -----------------------------------------
这是失败的用例,这个print会打印
========================================================== short test summary info =======================================
FAILED test_02_01.py::test_fun1 - AssertionError: Expected <10.1> to be equal to <11>, but was not.
======================================================== 1 failed, 1 passed in 0.14s =====================================
PS D:\code\pytest_test\test_2_day>

可以看到---- Captured stdout call ---下面打印了这是失败的用例,这个print会打印,而没有打印出这是成功的用例,这个print不会打印

这里我们需要注意下test_fun1是失败用例test_fun2是一条执行成功的用例.所以总结一下:

若,用例执行结果为Pass,那用例中的print不会打印出来
若,用例执行结果为Fail,那用例中的print都会打印出来

如果我就是想打印出所有的print的呢?

我们在终端执行:

pytest .\test_02_01.py -s

输出结果:

PS D:\code\pytest_test\test_2_day> pytest .\test_02_01.py -s
============================================================ test session starts ==============================================
platform win32 -- Python 3.10.5, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\code\pytest_test\test_2_day
collected 2 items                                                                                                                             

test_02_01.py 这是失败的用例,这个print会打印
F这是成功的用例,这个print不会打印
.

================================================================= FAILURES ===================================================
_________________________________________________________________ test_fun1 ____________________________________________________

    def test_fun1():
        print('这是失败的用例,这个print会打印')
>       assert_that(fun1(10)).is_equal_to(11)
E       AssertionError: Expected <10.1> to be equal to <11>, but was not.

test_02_01.py:20: AssertionError
========================================================== short test summary info ============================================
FAILED test_02_01.py::test_fun1 - AssertionError: Expected <10.1> to be equal to <11>, but was not.
======================================================== 1 failed, 1 passed in 0.11s ==========================================
PS D:\code\pytest_test\test_2_day> 

这样我们的print都打印出来了,就是很丑~

接下来我们引入日志~

不不不~

Loguru第三方日志库

我们不用python自带的logging模块,我们今天介绍的是第三方库:Loguru

Loguru is a library which aims to bring enjoyable logging in Python.

安装logurn

pip install loguru

这次我们先创建一个mytest_02_02.py 消除pytest框架自动捕获test开头文件.

"""
loguru使用
"""
from assertpy import assert_that
from loguru import logger
import pytest
logger.debug('这是我第一次使用loguru')

输出结果:

2022-07-06 23:12:35.809 | DEBUG    | __main__:<module>:7 - 这是我第一次使用loguru

我瞌睡了,明天继续

今天我们继续loguru....

打印的日志存到文件中

创建一个mytest_02_03.py

from loguru import logger
logger.add("mytest.log", rotation="500 MB")  # 这样就创建了一个mytest.log文件,若文件大于500m就会重新存,并且下面log信息都存在文件中

# 下面功能自行理解啊
logger.add("file_2.log", rotation="12:00")     # New file is created each day at noon

logger.add("file_3.log", rotation="1 week")    # Once the file is too old, it's rotated

logger.add("file_X.log", retention="10 days")  # Cleanup after some time

logger.add("file_Y.log", compression="zip")    # Save some loved space

继续修改mytest_02_03.py

from loguru import logger

logger.add("mytest.log", rotation="500 MB")  # 这样就创建了一个mytest.log文件,若文件大于500m就会重新存,并且下面log信息都存在文件中


logger.info('这是一个info')  # 文件存储  终端会打印
logger.debug('这是一个debug')
logger.warning('这是一个warning')
logger.error('这是一个error')

继续:

Loguru favors the much more elegant and powerful {}formatting over%, logging functions are actually equivalent to str.format().

# loguru 支持自动字符串格式化
logger.info("If you're using Python {}, prefer {feature} of course!", 3.6, feature="f-strings")
# print就必须加上format
print("If you're using Python {}, prefer {feature} of course!".format(3.6, feature="f-strings"))

当我们的项目越来越大的时候我们的py文件机会很多,都会调用一个公共log模块,如果出错了我们就需要知道哪个文件\函数调用了:@logger.catch

继续修改mytest_02_03.py

from loguru import logger

logger.add("mytest.log", rotation="500 MB")  # 这样就创建了一个mytest.log文件,若文件大于500m就会重新存,并且下面log信息都存在文件中


@logger.catch
def my_function(x, y, z):
    # An error? It's caught anyway!
    return 1 / (x + y + z)


my_function(0, 0, 0) # 这样传参可定会报错误,我们看看输出

控制台输出:

2022-07-07 23:30:07.902 | ERROR    | __main__:<module>:16 - An error has been caught in function '<module>', process 'MainProcess' (16084), thread 'MainThread' (15688):
Traceback (most recent call last):

> File "D:\code\pytest_test\test_2_day\my_test_02_02.py", line 16, in <module>
    my_function(0, 0, 0)
    └ <function my_function at 0x0000019D1CCE4310>

  File "D:\code\pytest_test\test_2_day\my_test_02_02.py", line 13, in my_function
    return 1 / (x + y + z)
                │   │   └ 0
                │   └ 0
                └ 0

ZeroDivisionError: division by zero

Process finished with exit code 0

mytest.log文件中输出的结果:

2022-07-07 23:30:07.902 | ERROR    | __main__:<module>:16 - An error has been caught in function '<module>', process 'MainProcess' (16084), thread 'MainThread' (15688):
Traceback (most recent call last):

> File "D:\code\pytest_test\test_2_day\my_test_02_02.py", line 16, in <module>
    my_function(0, 0, 0)
    └ <function my_function at 0x0000019D1CCE4310>

  File "D:\code\pytest_test\test_2_day\my_test_02_02.py", line 13, in my_function
    return 1 / (x + y + z)
                │   │   └ 0
                │   └ 0
                └ 0

ZeroDivisionError: division by zero

好了,学废了吧~,我们接下来就要封装这个log功能方法了

我们在项目目录下面创建了一个:public_fun\log_fun.py名字随便起

from loguru import logger
import os


# 获取项目路径
def get_pro_path():
    pro_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    return pro_path


def get_logger():
    logger.add(os.path.join(get_pro_path(), "mytest.log"), rotation="500 MB")
    return logger


我们创建一个测试用例test_02_04.py

"""
loguru使用
"""
from public_fun.log_fun import get_logger
from assertpy import assert_that
logger = get_logger()


def test_fun1():
    logger.info('我需要比较1')
    assert_that(1).is_not_equal_to(1)

项目目录下面出现了mytest.log内容是

2022-07-07 23:48:06.382 | INFO | test_02_02:test_fun1:10 - 我需要比较1

这里自动的会带上调用他的文件\方法\行数.

真的是太棒了

如果过感觉不感到棒,请使用logging模块后再来看看

2022-07-07 23:51

posted @ 2022-07-08 00:14  Tarzen  阅读(1047)  评论(0编辑  收藏  举报