自动化测试之httprunner框架hook函数实操

本篇介绍httprunner中hook函数的使用,以及通过编程能力实现建设自动化测试更全面的场景覆盖


前置:

互联网时代让我们更快的学习到什么是Httprunner

正文:

        经过上文了解到这个框架怎么使用之后,我们开始来探讨一下我们为什么要用hook函数?用hook函数能帮我们实现什么?能给我们带来什么收益?

举个例子:假设我们的业务系统目前是通过Kafka来实现消息的交互,A系统生产的消息B系统需要去消费处理后在生产消息给到下游系统

那么如果说我们需要为B系统编写这类流程的自动化,我们需要怎么实现呢?

一)设计

首先考虑一个问题:如果A系统是独立系统,如果我们写的自动化要依赖A系统的数据那就耦合度太高了。如果我们只考虑B系统的完整性,那么我们完全可以把A mock掉,将A生产的报文消息当作cases,通过python脚本来实现。

然后B系统消费后会操作数据库,那么我们断言是否可以也读数据库去判断是否预期

其次B会发消息来通知下游系统消费,那么我们是不是也可以写一个kafka监听消费消息,判断报文是否符合预期

二)实现

1、先写一个发送消息的函数,这个地方加一个参数是为了写多个cases

import json
from kafka import KafkaProducerdef sengMessage(tag):producer = KafkaProducer(bootstrap_servers='这个地方写集群名称')if('A' == tag):msg_dict = {"CMD": "这个地方是CMD","Data": "这个地方是消息体","Key": "这个是Key","LogID": "681533193628954414","Tag": "这个是标识","TimeStamp": "这是个时间","Topic": "这是个要发送的主题"}msg = json.dumps(msg_dict).encode()#partition这个地方写的是0表示放0这个Partition上了,如果要随机就看你有几个Partition,random一下producer.send("这个地方放主题topic", msg, partition=0)producer.close()

2、然后将这个函数放到debugtalk.py文件里面

3、编写一个cases,将此函数引用到setup_hooks

使用方式就是${函数名称(参数)},说明一下就是为啥要在setup_hooks里面使用,是因为需要在执行cases之前将消息发送之后系统消费到了才能走后面的流程(就是前置)

然后这个前置操作可以做:消息的发送、数据的处理(比如删除数据,更新数据等等)

4、编写一个操作数据库的函数

import pymysql
import yaml
from loguru import logger
from lib import utilsclass MySQL(object):"""Mysql数据库操作"""db = {}def __init__(self, db):"""初始化数据库对象Args:db (str): 数据库名字,代表了db配置的某个文件,数据库连接信息也在对应文件配置"""file = f"{utils.get_root_path()}/conf/{db}.yml"with open(file, encoding="utf-8") as conf:self.db = yaml.load(conf, Loader=yaml.FullLoader)def execute(self, sql):"""在mysql上执行一个sql语句,返回的结果为多条记录的元组,每条记录为dict,内容为字段-值字典Returns:[tuple]: 执行结果"""self.db['cursorclass'] = pymysql.cursors.DictCursortry:connection = pymysql.connect(**self.db)logger.info(f"execute sql: [{sql}]")with connection.cursor() as cursor:cursor.execute(sql)data = cursor.fetchall()logger.debug(f"execute ret: [{data}]")connection.commit()finally:connection.close()return data
#怎么使用呢,就是直接用这个函数传配置文件名称,sql
if __name__ == '__main__':MySQL("auto").execute("select * from A limit 1")

设置放置存储数据库配置文件的目录

数据库配置

host: IP
port: 端口
user: 用户名
passwd: 密码
db: 数据库

5、能操作数据库之后,那么我们是否可以将查询回来的全部重要字段(什么自增主键ID、时间啥的就不用断言了)进行判断了,写一个比较json的函数

class Check(object):def CheckSql(prama):db = 'auto'errmsgl_success = 'success'sql = 'SELECT A,B,C,D,E,F,G,H,I,J,K from AAA where aa=' + '\'' + str(prama) + '\''sql_count = 'SELECT count(1) from AAA  WHERE (aa = ' + "\'" + str(prama) + "\'" + ')'# 先查询条数,没有就重试,如果重试还没有就失败count = MySQL(db).execute(sql_count)[0]['count(1)']retry = 0while count == 0 and retry < 15:time.sleep(3)retry = retry + 1count = MySQL(db).execute(sql_count)[0]['count(1)']aa = MySQL(db).execute(sql)[0]response = json.dumps(aa)print(response)# 这个地方,假如A字段是一个JSON,这个地方是做了一个处理,让这个json排序,就不会出现每次查询这个json都是乱序得导致断言失败# 假设A字段:[{fee:1},{fee:2},{fee:3}],那么我们就用fee来排序A = eval(str(aa["A"]))aa["A"] = sorted(A, key=lambda x: (x['fee']), reverse=True)print(json.dumps(aa))# 这个地方用的直接是传进来得参数作为文件名称checkfile__detail = str(prama) detail_ret = Check.checkfile_json(aa, checkfile__detail)if detail_ret != errmsgl_success:return '文件名称:' + checkfile__detail + ', 失败原因: ' + detail_retreturn errmsgl_success# 读取对应的预期文件,这个函数可以抽出来,当一个公共方法def checkfile_json(requestdata, checkfile):# 文件地址当前项目/checkfile/checkfile.jsonbasic_url = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + '/checkfile'if checkfile:with open(basic_url + checkfile + '.json', 'r') as f:setdatas = json.load(f)return Check.cmp(requestdata, setdatas)def cmp(src_data, dst_data):msg = 'success'if isinstance(dst_data, dict):"""若为dict格式"""for key in dst_data:if key not in src_data:return 'key: ' + str(key) + ' 在请求中不存在'msg = Check.cmp(src_data[key], dst_data[key])if msg != 'success':return msgelif isinstance(dst_data, list):"""若为list格式"""for src_list, dst_list in zip((src_data), (dst_data)):"""递归"""msg = Check.cmp(src_list, dst_list)if msg != 'success':return msgelse:if str(src_data) != str(dst_data):return 'src_data != dst_data, src_data: ' + str(src_data) + ', dst_data: ' + str(dst_data)return msg

6、断言函数既然已经写好了,那就直接引用,同上面那个流程,加载到debugtaik.py文件之后,我们需要在cases断言处加上此函数,还是用${函数名称(参数)}来引用

7、最后编写一下消费kafka消息进行断言的函数

    def check_kafka_messgae(topic, bootstrap_servers, checkfile, enable_auto_commit=False, consumer_timeout_ms=300):# 参数分别是主题,集群,断言文件地址,自动提交,超时时间consumer = KafkaConsumer(bootstrap_servers=[bootstrap_servers], enable_auto_commit=enable_auto_commit,consumer_timeout_ms=consumer_timeout_ms)# 这个地方只监听一个partition == 0的topic_partition = TopicPartition(topic=topic, partition=0)lastoffset = consumer.end_offsets([topic_partition])[topic_partition]consumer.assign([topic_partition])consumer.seek(topic_partition, lastoffset - 1)messagelist = ''for message in consumer:messagelist = message.valuemessagelist = json.loads(json.loads(str(messagelist, 'utf-8'))['Data'])print('topic数据' + str(messagelist))# checkfile_json这个方法上面写得函数里面有,直接调用return checkfile_json(messagelist, checkfile)

8、同上,还是将这个函数加入到debugtaik.py,在validate里面进行断言判断

总结:

将上面的流程串起来之后发现,从kafak消息的发送、数据库的查询、文件读取/数据判断,到kafka消息监听断言整个流程能够完成上述的诉求。

通过一个例子来解读hook函数的作用。在真实的业务场景下,我们在编写自动化cases的时候完全可以用纯代码的方式来实现我的复杂的业务场景。通过这种方式能更有效的认可自动化去替代人工操作。


后话:

个人认为自动化的灵魂不是用什么工具,而是断言。不管是人工还是程序自动操作都需要有一个判断依据,如果这个判断依据十分有效,那么我们只需要完善场景cases就能实现自动化替换人工(百分之80吧)

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

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

相关文章

【教程】一个比较良心的C++代码混淆器

这是一个比较良心的C代码混淆器&#xff0c;用于信息竞赛训练和保护代码免受抄袭。本文将介绍这个混淆器的使用方法、混淆效果和已知的一些bug。同时&#xff0c;我们也会给出一些示例来演示混淆器的具体操作。 引言 在信息竞赛训练和实际开发中&#xff0c;保护代码的安全性和…

汇编程序设计

文章目录 第一章8086的存储器组织寻址方式立即数寻址方式寄存器寻址方式存储器寻址方式直接寻址方式寄存器间接寻址寄存器相对寻址方式寄存器基址变址寻址相对基址变址寻址相对方式的补充 数据寻址方式的组合 第一章 8086的存储器组织 存储单元的地址 “段基地址&#xff1a;段…

Adobe AE(After Effects)2021下载地址及安装教程

Adobe After Effects是一款专业级别的视觉效果和动态图形处理软件&#xff0c;由Adobe Systems开发。它被广泛用于电影、电视节目、广告和其他多媒体项目的制作。 After Effects提供了强大的合成和特效功能&#xff0c;可以让用户创建出令人惊艳的动态图形和视觉效果。用户可以…

【C语言】每日一题,快速提升(2)!

&#x1f525;博客主页&#x1f525;&#xff1a;【 坊钰_CSDN博客 】 欢迎各位点赞&#x1f44d;评论✍收藏⭐ 题目&#xff1a;杨氏矩阵 有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从上到下是递增的&#xff0c;请编写程序在这样的矩阵中查找某个…

error: failed to push some refs to ‘https://gitee.com/zhao-zhimin12/gk.git‘

git push origin master发现以下报错: 解决办法: 一、强制推送 git push origin master -f &#xff08;加上 -f 就是强制&#xff09; 二、 先拉取最新代码&#xff0c;再推送 1.git pull origin master 2.git push origin master

保护视力,从 CareUEyes 开始 —— 你的电脑护眼小助手

在数字化时代&#xff0c;我们的眼睛比以往任何时候都更频繁地面对屏幕。长时间盯着电脑工作&#xff0c;不仅影响视力&#xff0c;还可能导致眼疲劳和不适。今天&#xff0c;我要向大家推荐一款专为电脑用户设计的护眼软件——CareUEyes。 CareUEyes&#xff1a;你的视力守护者…

Linux系统中LVM与磁盘配额

目录 一、LVM逻辑卷管理 二、LVM的管理命令 物理卷管理 卷组管理 逻辑卷管理 *创建并使用LVM步骤 三、磁盘配额概述 实现磁盘限额的条件 Linux 磁盘限额的特点 四、磁盘配额管理 磁盘限额 一、LVM逻辑卷管理 能够在保持现有数据不变的情况下动态调整磁盘容量&#…

C++算法题 - 矩阵

目录 36. 有效的数独54. 螺旋矩阵48. 旋转图像73. 矩阵置零289. 生命游戏 36. 有效的数独 LeetCode_link 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现…

selenium反反爬虫,隐藏selenium特征

一、stealth.min.js 使用 用selenium爬网页时&#xff0c;常常碰到被检测到selenium &#xff0c;会被服务器直接判定为非法访问&#xff0c;这个时候就可以用stealth.min.js 来隐藏selenium特征&#xff0c;达到绕过检测的目的 from selenium import webdriver from seleniu…

Day 2 正式coding之基础模块的搭建

Day 2 正式coding之基础模块的搭建 这里会总结构建项目过程中遇到的问题&#xff0c;以及一些个人思考&#xff01;&#xff01; 学习方法&#xff1a; 1 github源码 文档 官网 2 内容复现 &#xff0c;实际操作 项目源码同步更新到github 欢迎大家star~ 后期会更新并上传前端…

Spring基础篇-快速面试笔记(速成版)

文章目录 1. Spring概述2. 控制反转&#xff08;IoC&#xff09;2.1 Spring声明Bean对象的方式2.2 Spring的Bean容器&#xff1a;BeanFactory2.3 Spring的Bean生命周期2.4 Spring的Bean的注入方式 3. Spring的事件监听器&#xff08;Event Listener&#xff09;3.1 Spring内置事…

自学Java的第二十四次笔记

一,方法重载 1.基本介绍 java 中允许同一个类中&#xff0c;多个同名方法的存在&#xff0c;但要求 形参列表不一致&#xff01; 比如&#xff1a; System.out.println(); out 是 PrintStream 类型 2.重载的好处 1) 减轻了起名的麻烦 2) 减轻了记名的麻烦 3.快速入门案…

认识海康摄像头的编码信息以及使用等

认识海康摄像头的编码信息以及使用等 主要是来源一下文章&#xff1a; 海康摄像头、NVR命名规则-弱电新人学习&#xff01; - 知乎 大体是分了三类&#xff0c;当然海康的产品实在是有点多&#xff0c;没找见官方权威的解答&#xff0c;参考着先看看。 网络摄像机、网络球机…

浅谈Java JVM

Java虚拟机&#xff08;Java Virtual Machine&#xff0c;简称JVM&#xff09;是Java语言的核心组成部分&#xff0c;它是一个抽象的计算机&#xff0c;负责执行Java字节码指令。JVM是Java平台无关性的基石&#xff0c;它为Java代码提供了一个标准的运行环境&#xff0c;使Java…

golang-基础语法

make 和 new 的区别 make 和 new 都是用来分配内存 make 只能对 slice map channel 进行初始化结构体实例。new 可以对任意类型进行初始化make 用于分配数据对象的具体实例&#xff0c;new 用于分配数据类型的默认值&#xff0c;并返回该数据的指针。 new 出来的 slice 、ma…

html5测试题整理--针对标签的概念性,我们究竟还要学习哪些软件测试知识

先自我介绍一下&#xff0c;小编浙江大学毕业&#xff0c;去过华为、字节跳动等大厂&#xff0c;目前阿里P7 深知大多数程序员&#xff0c;想要提升技能&#xff0c;往往是自己摸索成长&#xff0c;但自己不成体系的自学效果低效又漫长&#xff0c;而且极易碰到天花板技术停滞…

Ubuntu20.04版本命令行设置挂载磁盘,并设置开机自动挂载

最近部署应用 系统是Ubuntu20.4版本的Linux系统&#xff0c;加了数据盘&#xff0c;需要格式化后挂载&#xff0c;记录下&#xff1a; Linux 数据盘挂载(采用 parted 分区工具)-格式化为 ext4 1. 初始化 Linux 数据盘 挂载数据盘后或者随实例创建时一并创建的数据盘&#xff…

使用SpringBoot3+Vue3开发公寓管理系统

项目介绍 公寓管理系统可以帮助公寓管理员更方便的进行管理房屋。功能包括系统管理、房间管理、租户管理、收租管理、房间家具管理、家具管理、维修管理、维修师傅管理、退房管理。 功能介绍 系统管理 用户管理 对系统管理员进行管理&#xff0c;新增管理员&#xff0c;修改…

碳课堂|碳关税是什么?企业如何从容应对?

2023年10月1日&#xff0c;欧盟碳边境调节机制&#xff08;CBAM&#xff09;法规&#xff0c;即全球首个“碳关税”开始实施。据世界银行研究报告称&#xff0c;如果“碳关税”全面实施&#xff0c;在国际市场上&#xff0c;中国制造可能将面临平均26%的关税&#xff0c;出口量…

Android JetPack Compose+Room----实现搜索记录功能

文章目录 需求概述功能展示实现搜索功能使用的技术1.Android Jetpack room2.Android JetPack Compose 代码实现编写搜索界面接入Room实现搜索功能的管理引入依赖定义包结构定义操作表的Dao类定义数据库的基础配置定义数据库的Dao管理类使用数据库升级 源码地址 需求概述 搜索功…