Python接口自动化之logging封装及实战

news2024/11/18 5:37:20

而在此之前介绍过yaml封装,数据驱动、配置文件、日志文件等独立的功能,我们将这些串联起来,形成一个完整的接口测试流程。

以下主要介绍将logging常用配置放入yaml配置文件、logging日志封装及结合登录用例讲解日志如何在接口测试中运用。

图片

yaml配置文件

将日志中的常用配置,比如日志器名称日志器等级格式化放在配置文件中,在配置文件config.yaml中添加:

1

2

3

4

logger:

  name: ITester

  level: DEBUG

  format'%(filename)s-%(lineno)d-%(asctime)s-%(levelname)s-%(message)s'

封装logging类,读取yaml中的日志配置。

读取yaml

之前读写yaml配置文件的类已经封装好,愉快的拿来用即可,读取yaml配置文件中的日志配置。

yaml_handler.py

1

2

3

4

5

6

7

8

9

10

11

12

13

import yaml

class YamlHandler:

    def __init__(selffile):

        self.file = file

    def read_yaml(self, encoding='utf-8'):

        """读取yaml数据"""

        with open(self.file, encoding=encoding) as f:

            return yaml.load(f.read(), Loader=yaml.FullLoader)

    def write_yaml(self, data, encoding='utf-8'):

        """向yaml文件写入数据"""

        with open(self.file, encoding=encoding, mode='w') as f:

            return yaml.dump(data, stream=f, allow_unicode=True)

yaml_data = YamlHandler('../config/config.yaml').read_yaml()

封装logging类

在common目录下新建文件logger_handler.py,用于存放封装的logging类。

封装思路:

  • 首先分析一下,logging中哪些数据可以作为参数?比如日志器名称、日志等级、日志文件路径、输出格式,可以将这些放到__init__方法里,作为参数。

  • 其次,要判断日志文件是否存在,存在就将日志输出到日志文件中。

  • 最后,logging模块已经封装好了Logger类,可以直接继承,减少代码量。

这里截取logging模块中Logger类的部分源码。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

class Logger(Filterer):

    """

    Instances of the Logger class represent a single logging channel. A

    "logging channel" indicates an area of an application. Exactly how an

    "area" is defined is up to the application developer. Since an

    application can have any number of areas, logging channels are identified

    by a unique string. Application areas can be nested (e.g. an area

    of "input processing" might include sub-areas "read CSV files", "read

    XLS files" and "read Gnumeric files"). To cater for this natural nesting,

    channel names are organized into a namespace hierarchy where levels are

    separated by periods, much like the Java or Python package namespace. So

    in the instance given above, channel names might be "input" for the upper

    level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.

    There is no arbitrary limit to the depth of nesting.

    """

    def __init__(self, name, level=NOTSET):

        """

        Initialize the logger with a name and an optional level.

        """

        Filterer.__init__(self)

        self.name = name

        self.level = _checkLevel(level)

        self.parent = None

        self.propagate = True

        self.handlers = []

        self.disabled = False

    def setLevel(self, level):

        """

        Set the logging level of this logger.  level must be an int or a str.

        """

        self.level = _checkLevel(level)

接下来,我们开始封装logging类。

logger_handler.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

import logging

from common.yaml_handler import yaml_data

class LoggerHandler(logging.Logger):

    # 继承Logger类

    def __init__(self,

                 name='root',

                 level='DEBUG',

                 file=None,

                 format=None

                 ):

        # 设置收集器

        super().__init__(name)

        # 设置收集器级别

        self.setLevel(level)

        # 设置日志格式

        fmt = logging.Formatter(format)

        # 如果存在文件,就设置文件处理器,日志输出到文件

        if file:

            file_handler = logging.FileHandler(file,encoding='utf-8')

            file_handler.setLevel(level)

            file_handler.setFormatter(fmt)

            self.addHandler(file_handler)

        # 设置StreamHandler,输出日志到控制台

        stream_handler = logging.StreamHandler()

        stream_handler.setLevel(level)

        stream_handler.setFormatter(fmt)

        self.addHandler(stream_handler)

# 从yaml配置文件中读取logging相关配置

logger = LoggerHandler(name=yaml_data['logger']['name'],

                       level=yaml_data['logger']['level'],

                       file='../log/log.txt',

                       format=yaml_data['logger']['format'])

  

logging实战

在登录用例中运用日志模块,到底在登录代码的哪里使用日志?

①将读取的用例数据写入日志、用来检查当前的用例数据是否正确;

②将用例运行的结果写入日志,用来检查用例运行结果是否与预期一致;

③将断言失败的错误信息写入日志。

接下来直接上代码,在登录用例中添加日志。

test_login.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

import unittest

from common.requests_handler import RequestsHandler

from common.excel_handler import ExcelHandler

import ddt

import json

from common.logger_handler import logger

@ddt.ddt

class TestLogin(unittest.TestCase):

    # 读取excel中的数据

    excel = ExcelHandler('../data/cases.xlsx')

    case_data = excel.read_excel('login')

    print(case_data)

    def setUp(self):

        # 请求类实例化

        self.req = RequestsHandler()

    def tearDown(self):

        # 关闭session管理器

        self.req.close_session()

    @ddt.data(*case_data)

    def test_login_success(self,items):

        logger.info('*'*88)

        logger.info('当前是第{}条用例:{}'.format(items['case_id'],items['case_title']))

        logger.info('当前用例的测试数据:{}'.format(items))

        # 请求接口

        res = self.req.visit(method=items['method'],url=items['url'],json=json.loads(items['payload']),

                             headers=json.loads(items['headers']))

        try:

            # 断言:预期结果与实际结果对比

            self.assertEqual(res['code'], items['expected_result'])

            logger.info(res)

            result = 'Pass'

        except AssertionError as e:

            logger.error('用例执行失败:{}'.format(e))

            result = 'Fail'

            raise e

        finally:

            # 将响应的状态码,写到excel的第9列,即写入返回的状态码

            TestLogin.excel.write_excel("../data/cases.xlsx"'login', items['case_id'+ 19, res['code'])

            # 如果断言成功,则在第10行(测试结果)写入Pass,否则,写入Fail

            TestLogin.excel.write_excel("../data/cases.xlsx"'login', items['case_id'+ 110, result)

if __name__ == '__main__':

    unittest.main()

控制台日志输出部分截图:

日志文件输出部分截图:

总结:本文主要介绍将logging常用配置放入yaml配置文件、logging日志封装及结合登录用例讲解日志如何在接口测试中运用。

下面是配套学习资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

软件测试面试小程序

被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!

涵盖以下这些面试题板块:

1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux

6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

资料获取方式 :

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

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

相关文章

网络安全 Day27-运维安全项目-堡垒机部署

运维安全项目-堡垒机部署 1. 运维安全项目-架构概述2. 运维安全项目之堡垒机2.1 堡垒机概述2.2 堡垒机选型2.3 环境准备2.4 部署Teleport堡垒机2.4.1 下载与部署2.4.2 启动2.4.3 浏览器访问teleport2.4.4 进行配置2.4.5 安装teleport客户端 2.5 teleport连接服务器 1. 运维安全…

探索Python异常世界:玩转异常、模块与包

文章目录 一 异常概念二 异常的捕获方法2.1 捕获异常的原因2.2 捕获常规异常2.3 捕获指定异常2.4 捕获多个异常2.5 捕获异常并输入异常信息2.6 捕获所有异常2.7 异常else2.8 异常finally 三 异常的传递四 python模块4.1 模块的导入方式4.2 自定义模块4.3 测试模块4.4 注意事项4…

流量,日志分析

wireshark wireshark中有捕获过滤器和显示过滤器 常用的捕获过滤表达式: 常见的显示过滤表达式: 语法: 1.过滤IP,如来源IP或者目标IP等于某个IP 例子: ip.src eq 192.168.1.107 or ip.dst eq 192.168.1.107 或者 ip.addr eq 1…

前端加密与解密的几种方式

1.base64加密方式 1. base64是什么? Base64,顾名思义,就是包括小写字母a-z、大写字母A-Z、数字0-9、符号""、"/"一共64个字符的字符集,(另加一个“”,实际是65个字符,至于…

vue3实现自定义select下拉框内容之城市区域篇

分享-2023年高级前端进阶:前端登顶之巅-最全面的前端知识点总结站点 *分享一个使用比较久的🪜 需求分析: 1、实现一个区域下拉选项与现有ui组件库不同,支持多选、单选需求 2、支持选中区域后-全选中当前区域下的所有城市信息 3、…

CommonCollections3链分析

先介绍一下URLClassLoader URLClassLoader可以从传入的URL上加载任意类 且支持http协议 实际上类加载最关键的地方在Classloader#definClass() 所以我们要去找有谁调用了该方法 在TemplatesImpl的内部类TransletClassLoader#defineClass()处调用 往前 TemplatesImpl#defin…

OpenCV 中的光流 (C++/Python)

什么是光流? 光流是一项视频中两个连续帧之间每像素运动估计的任务。基本上,光流任务意味着计算像素的位移矢量作为两个相邻图像之间的对象位移差。光流的主要思想是估计物体由其运动或相机运动引起的位移矢量。 理论基础 假设我们有一个灰度图像——具有像素强度的矩阵。我…

【YOLOX】《YOLOX:Exceeding YOLO Series in 2021》

arXiv-2021 文章目录 1 Background and Motivation2 Related Work3 Advantages / Contributions4 Method5 Experiments5.1 Datasets and Metrics 6 Conclusion(own) 1 Background and Motivation 2 Related Work 3 Advantages / Contributions 4 Meth…

自定义注解(Annontation)

目录 1.注解定义 2.元注解定义 3. 自定义注解(自定义的注解名称相同的会覆盖原注解) 4.Annotation架构(元注解参数介绍) 1.注解定义 注解是用来将任何的信息或元数据(metadata)与程序元素(类…

行业报告 | Q3策略汇报:持续看好AI+复苏、国产化

原创 | 文 BFT机器人 01 国产化是产业发展基石 1.1 设备:量测等环节国产化弹性大 刻蚀、清洗、CMP等环节国产化率较高。得益于北方华创、中微公司的产品突破和市占率提升,刻蚀环节国产化率在2022年已接近20%,鉴于刻蚀设备市场空间广阔&#…

电影订票选座商城开发--源码部署,快速搭建

一、技术选择 电影订票选座商城开发需要结合前端和后端技术来实现。 二、功能设计 电影订票选座商城需要具备以下功能: 用户注册登录:用户可以通过手机号、邮箱等方式注册账号,并通过登录验证获取权限。 电影票查询:用户可以查…

喆啡酒店十周年丨啡越时间限,ALL BY 10VE!

啡越时光热爱为伴 十年前,秉持对咖啡馆文化及复古风格的喜爱,喆啡酒店创造全新的Coffetel品类,将充满「温暖」「愉悦」「咖啡香」的格调体验带给消费者,成为无数人「旅途中的啡凡存在」。 十年间,喆啡酒店以热爱化为…

在Hierarchy层级面板上组织业务脚本流程——使用async和await

〇、把多个不同的脚本串联在一起顺序阻塞执行 把很多个脚本串联在一起,让他们按照先后顺序执行,等着前面的执行完毕,在执行后面的,这就是用【异步方法】实现的,能够顺序执行的流程。 如下图所示,流程脚本都…

CleanMyMac2023永久版Mac清理工具

CleanMyMac拥有超强的清理能力,能够快速清理Mac垃圾文件、陈旧数据,恢复Mac原本性能,保持电脑好状态!CleanMyMac中文版功能非常的强大,操作简单,使用起来高效快捷,自身拥有一个安全数据&#xf…

安装OpenCV依赖包libjasper-dev无法安装

记录在ubuntu22.04上编译OpenCV4.6,遇到依赖包无法安装的问题。 主要是源的问题 sudo gedit /etc/apt/sources.list我的源文件,######处的下一行是改动的地方,主要把自带的源都注释了,然后在末尾添加了清华源。 # deb cdrom:[Ubu…

详解C语言中的int8_t、uint8_t、int16_t、uint16_t、int32_t、uint32_t、int64_t、uint64_t

2023年8月8日,周二上午 目录 为什么会产生int8_t、uint8_t等这类数据类型int8_t、uint8_t等这类数据类型有什么用头文件int8_t、uint8_t等这类数据类型是怎么实现的 为什么会产生int8_t、uint8_t等这类数据类型 根本原因在于,C 语言标准只是规定了各个…

CentOS8装不上软件

App stream什么提示、或者找不到firewalld服务等类似提示时。可以尝试替换/etc/yum.repos.d文件夹下的文件内容。记得替换之前先备份原有的,防止意外情况便于恢复。 替换后文件如下: 文件下载地址: https://download.csdn.net/download/zhao…

也谈态势感知的嵌套与级联

不同颗粒度的态势感知可以嵌套在一起,形成一个层次结构,从而提供全面和多层次的信息获取和理解。 在态势感知中,颗粒度可以理解为观察、收集和分析信息的细节程度。较高颗粒度的态势感知关注的是具体的事件、行动或细节,提供了详细…

如何高性能、高效率地实现3D Web轻量化?

随着互联网和Web技术的发展,3D Web应用的需求越来越多。然而,复杂的3D模型在Web上展示和交互通常需要大量的带宽和计算资源。为了解决这一问题,HOOPS技术作为一套专业的3D图形技术开发工具包,发挥着关键作用。本文将探讨HOOPS技术…

问道管理:新创业板权限怎么开通?

在我国证券商场中,创业板能够被认为是相对较为年青的板块, 但在近几年中,创业板体现出了极高的投资价值。为了更好地促进我国立异企业开展,政府开放了新创业板权限。可是,对于很多人来说,新创业板权限是一个…