unittest | 使用unittest模块来测试logging日志模块功能

news2025/3/12 21:33:14

我们在这篇文章实现了在项目工程中编写一个logging模块,但是我们如何确定我们编写的模块功能的是否正常?

你可能想到将全部代码写完后运行测试,但这是一个非常不好的习惯。❌

最好的方式,是每写出来一个功能或者方法就对它进行测试,这样可以确保,当你完成代码后并运行,可以很少出现Bug,能直接运行成功。可以使用Python自带的unittest模块来做✔

单元测试

  • unittest
  • logging单元测试
    • logger = init_logger()
      • logging.getLogger() 源码
    • RootLogger
      • from logging import RootLogger
    • 小结

unittest

unittest 是 Python 标准库中的一个模块,它提供了一套编写和运行自动化测试的框架。unittest 支持自动化测试,设置和关闭代码以供测试,聚合测试到集合中以及独立的测试脚本运行。

以下是 unittest 的一些核心概念和用法:

  • 测试用例(Test Cases):
    测试用例是测试的基本单元。在 unittest 中,你通过创建一个继承自 unittest.TestCase 的类来编写测试用例。
  • 测试方法(Test Methods):
    测试方法以 test 开头。它们包含了实际的测试逻辑,unittest 会自动运行所有以 test 开头的方法
  • 断言方法(Assert Methods):
    unittest 提供了一系列的断言方法,如assertEqualassertTrueassertFalse 等,用于检查测试结果是否符合预期。
  • 测试套件(Test Suites):
    测试套件是一组测试用例的集合。你可以使用 unittest.TestSuite 或 unittest.TestLoader 来创建和管理测试套件。
  • 测试运行器(Test Runners):
    测试运行器负责运行测试套件,并收集结果。unittest 提供了 unittest.TextTestRunner 来在命令行中运行测试。
  • 测试夹具(Test Fixtures):
    测试夹具是测试之前和之后运行的代码,用于设置和关闭测试环境。setUp 方法在每个测试方法之前运行tearDown 方法在每个测试方法之后运行

setUp : 可以理解为测试前需要提前执行的代码 例如连接数据库
tearDown : 可以理解为收尾工作 例如关闭数据库

logging单元测试

在test文件夹中创建测试文件:test_logging_util.py

from unittest import TestCase
from util.logging_util import init_logger
from logging import RootLogger

class MyTest(TestCase):
    def setUp(self) -> None: # 测试前需要提前执行的代码  例如连接数据库
        pass

    def test_myfunc(self):
        logger = init_logger() 
        result = isinstance(logger,RootLogger) #判断是不是  某个类的实例
        self.assertEqual(result,True)
        self.assertIsInstance(logger,RootLogger)

    def tearDown(self)-> None: # 收尾工作
        pass
  • 结果
    在这里插入图片描述

python是动态类型的语言 只有执行到这里才知道这个变量是什么类型的

logger = init_logger()

class Logging():
    def __init__(self,level=20):
        self.logger = logging.getLogger()
        self.logger.setLevel(level)


def init_logger():
    logger = Logging(level).logger

    # 缓存机制 避免日志重复输出
    if logger.handlers:
        return logger

    path = log_root_path+log_filename
    # 创建并打开文件
    with open(path, 'w') as file:
        # 文件被创建,但这里不写入任何内容,所以它是空的
        pass
    # 构造handler
    # 优化日志存储文件 StreamHandler
    stream_handler = logging.StreamHandler()
    file_handler = logging.FileHandler(
        filename=path,
        mode='a',
        encoding='utf-8'
    )

    fmt = logging.Formatter('%(asctime)s - [%(levelname)s] - %(filename)s[%(lineno)d]:%(message)s')

    stream_handler.setFormatter(fmt)
    file_handler.setFormatter(fmt)

    # 组合
    logger.addHandler(stream_handler)
    logger.addHandler(file_handler)

    return logger

logging.getLogger() 源码

def getLogger(name=None):
    """
    Return a logger with the specified name, creating it if necessary.

    If no name is specified, return the root logger.
    """
    if name:
        return Logger.manager.getLogger(name)
    else:
        return root

没有指定日志记录器的名称则就是默认是根日志记录器

  • 解答:-> None 方便我们写出更健壮的语言
# -> xxx  :方便我们写出更健壮的语言
def setUp(self) -> None: # 返回是None
	pass
	
def add(a,b)->str:
	return str(a+b)

def add(a:float,b:float)->float:
	return str(a+b)

RootLogger

在Python的logging模块中,RootLogger是日志系统的最高级别的记录器。每个日志记录器都有一个层次结构,而RootLogger是这个层次结构的根。当你创建一个日志记录器(logger)时,如果没有明确指定它的父记录器,它默认会继承RootLogger的配置。

from logging import RootLogger

class RootLogger(Logger):
    """
    A root logger is not that different to any other logger, except that
    it must have a logging level and there is only one instance of it in
    the hierarchy.
    """
    def __init__(self, level):
        """
        Initialize the logger with the name "root".
        """
        Logger.__init__(self, "root", level)

因此这三行代码才可以执行:

 result = isinstance(logger,RootLogger) #判断是不是  某个类的实例
 self.assertEqual(result,True)
 self.assertIsInstance(logger,RootLogger)

小结

RootLogger的默认级别是WARNING,这意味着默认情况下,只有WARNING级别及以上(ERRORCRITICAL)的日志消息会被处理。如果你想要记录所有级别的日志,你需要将RootLogger的级别设置得更低,比如DEBUG

import logging

# 获取RootLogger
root_logger = logging.getLogger()

# 设置日志级别为DEBUG
root_logger.setLevel(logging.DEBUG)

# 创建一个handler,例如控制台处理器
console_handler = logging.StreamHandler()

# 为handler设置级别
console_handler.setLevel(logging.DEBUG) # ⭐ 设置成级别更低的日志记录器

# 创建一个日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# 设置handler的格式
console_handler.setFormatter(formatter)

# 将handler添加到RootLogger
root_logger.addHandler(console_handler)

# 测试日志输出
root_logger.debug('这是一个DEBUG级别的消息')
root_logger.info('这是一个INFO级别的消息')
root_logger.warning('这是一个WARNING级别的消息')
root_logger.error('这是一个ERROR级别的消息')
root_logger.critical('这是一个CRITICAL级别的消息')

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2102037.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 存储引擎有哪些?InnoDB 和 MyISAM 存储引擎有什么区别?

MySQL 存储引擎有哪些? MySQL 存储引擎主要负责查询的执行和数据的存储,存储引擎主要有 InnoDB,MyISAM,Memery InnoDB 是 MySQL 默认的存储引擎,支持事务和行级锁,以及外键的约束,具有事务提交…

揭秘推荐算法:深度学习如何读懂你的购物心思

时间:2024年09月03日 作者:小蒋聊技术 邮箱:wei_wei10163.com 微信:wei_wei10 音频:https://xima.tv/1_L8HH40?_sonic0 希望大家帮个忙!如果大家有工作机会,希望帮小蒋内推一下&#xff0c…

帅地:秋招入职腾讯,后裸辞创业年入百万,一位全职程序员博主的第六年

这是《开发者说》的第17期,这次我们采访的是知名的程序员博主:帅地。 帅地从大学开始接触公众号,在大学毕业时就沉淀了10w垂直粉丝,月入近10w。在秋招阶段,帅地靠扎实的算法基础和技术功底顺利入职腾讯。“还没折腾够”…

【分布式注册中心】NACOS_2.3.0部署与实战

部署 一 准备 1 依赖:MYSQL 2 创建数据库 CREATE database if NOT EXISTS nacos default character set utf8mb4 collate utf8mb4_unicode_ci; 3 导入初始化SQL https://raw.githubusercontent.com/alibaba/nacos/develop/distribution/conf/mysql-schema.sql…

了解Spring Data JPA

1、Spring Data JPA 1.1、概述 Spring Data JPA 是 Spring 基于JPA 规范的基础上封装的⼀套 JPA 应⽤框架,可使开发者⽤极简的代码即可实现对数据库的访问和操作。它提供了包括增删改查等在内的常⽤功能!学习并使⽤Spring Data JPA 可以极⼤提⾼开发效率…

cefsharp128_cef128_chromium6613_x64_h264版本抢险体验

一、本博测试版本cef128及兼容性测试 1.1 版本 128.0.6613.x (全网保持最新更新测试体验) 感谢您:关注我,关注栏目,总有您想要的资源,推荐好友有优惠 1.2 兼容性测试,支持h264 1.3 视频播放测试 版本兼容 cef128.xx.xx <

哈希 详解

目录 1. “哈希”是什么&#xff1f; 2. 哈希冲突 3. 哈希函数 3.1 设计原则 3.2 常见哈希函数 4. 解决哈希冲突的两种常见方法 4.1 闭散列 4.2 开散列 4.3 散列表的扩容问题 5. 哈希表的实现 并 封装模拟实现unordered系列容器 6. 哈希的应用 6.1 位图 -- bitset …

vue3+ts项目新建后找不到模块vue或类型{}上不存在属性

新建的项目&#xff0c;不影响功能&#xff0c;但是红色的波浪线很不好看。 在tsconfig.json文件中增加一行代码&#xff1a;让ts识别vue文件 "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue&quo…

特异性心肌细胞靶向肽(PCM);WLSEAGPVVTVRALRGTGSW;CAS:771479-86-8

【特异性心肌细胞靶向肽(PCM) 简介】 特异性心肌细胞靶向肽&#xff08;PCM&#xff09;是一种设计用于识别和结合心肌细胞特有的受体或分子标记的多肽序列。PCM可以通过其氨基酸序列的特定配置和表面特性实现对心肌细胞的选择性靶向&#xff0c;从而在心脏病治疗中递送药物、作…

Idea_服务器自动化部署_傻瓜式教程

使用Alibaba Cloud Toolkit 在 IntelliJ IDEA 中一键部署项目到服务器 1. 安装 Alibaba Cloud Toolkit 插件 确保 IntelliJ IDEA 版本为 2018.3 或以上。打开 IntelliJ IDEA&#xff0c;进入 File -> Settings -> Plugins&#xff0c;搜索并安装 Alibaba Cloud Toolkit…

【重学 MySQL】一、数据库概述

【重学 MySQL】一、数据库概述 为什么要使用数据库数据库与数据库管理系统数据库&#xff08;Database&#xff09;数据库管理系统&#xff08;DBMS&#xff09;数据库与数据库管理系统的关系数据库是数据存储的容器数据库管理系统是数据库的管理者相互依存的关系数据库系统的组…

论斜率优化dp

论斜率优化dp 1问题2暴力算法-线性dp3斜率优化线性dp4后记 1问题 如下图 看到这题&#xff0c;题面很复杂 其实可以转化为如下问题 有 n n n个任务&#xff0c;排成一个有序序列&#xff0c;我们要解决这些任务 总费用是每一个任务的完成时间乘以费用系数求和 每个任务之前…

RAG 进阶:零成本 chat_with_readthedocs

Readthedocs 是知名的文档托管平台&#xff0c;通常用于免费存放 GitHub 和 GitLab 的项目文档。当项目文档较多时&#xff0c;简单的搜索难以满足读者需求&#xff0c;此外在 AI 2.0 时代&#xff0c;“主动寻找答案”这类用户体验已经逐渐落后。 本文将介绍如何基于 Huixian…

4款AI智能改写工具,轻松快速改出优质文章

在当今数字化内容创作的时代&#xff0c;高质量的文章对于个人和企业来说都具有至关重要的意义。然而&#xff0c;有时候我们可能会面临需要对已有文章进行改写的情况&#xff0c;以避免重复、优化语言表达或者适应不同的受众。这时&#xff0c;AI智能改写工具就成为了我们的得…

解决AutoDL远程服务器训练大模型的常见问题:CPU内存不足与 SSH 断开

在使用远程服务器&#xff08;如 AutoDL&#xff09;进行深度学习训练时&#xff0c;通常会遇到一些常见问题&#xff0c;比如由于数据加载导致的内存消耗过高&#xff0c;以及 SSH 连接中断后训练任务被迫停止。这篇文章将介绍我在这些问题上遇到的挑战&#xff0c;并分享相应…

前缀和专题——一维模版+二维模版力扣实战应用

目录 1、模版 1.1【模版】一维前缀和 1.1.1 算法思想 1.1.2 算法代码 1.2【模版】二维前缀和 1.2.1 算法思想 1.2.2 算法代码 2、算法应用【leetcode】 2.1 题一&#xff1a;寻找数组的中心下标 2.1.1 算法思想 2.1.2 算法代码 2.2 题二&#xff1a;除自身以外数组…

Leetcode每日刷题之30.串联所有单词的子串

1.题目解析 本题的题目要求给出一个字符串 s 与一个字符数组 words &#xff0c;并且 words 中的所有单词长度均相同&#xff0c;我们要寻找出 s 中是否存在子串符合 words 中单词的任意组合而成&#xff0c;注意重要的一点是 words 中的所有单词的长度均相同&#xff0c;这是解…

汇总1000+国内外AI工具合集,工作效率提升10倍的秘诀!

工具合集在文章末尾有领取方式。记得点在看收藏&#xff0c;每天默默的学习&#xff0c;然后惊艳所有人。 很多AI&#xff0c;都是开发商在自己的领域&#xff0c;或是借助某个领域的资源进行算法的模型训练。就目前来讲&#xff0c;每款AI都具备它自身的功能特性&#xff0c;没…

C++刷怪笼(2)类和对象的探索-上

1.前言 了解完C的一些入门干货之后&#xff0c;我们来对C的第一个重点就行学习——那就是类和对象&#xff0c;该重点我们分为三篇文章进行学习&#xff0c;请大家跟紧我的脚步&#xff0c;认真学知识哦~ 2.正文——类和对象 2.1类的定义 2.2.1类的定义格式 • class为定义…

认识git和git的基本使用,本地仓库,远程仓库和克隆远程仓库

本地仓库 #安装git https://git-scm.com/download/win #git是什么&#xff1f;有什么用&#xff1f; git相当于一个版本控制系统&#xff0c;版本控制是一种记录一个或若干文件内容变化&#xff0c;以便将来查阅特定版本修订情况的系统。 作用: 记录&#xff08;项目&#…