Python+Pytest+Allure+Git+Jenkins数据驱动接口自动化测试框架

news2025/4/6 5:13:47

一、接口基础  

接口测试是对系统和组件之间的接口进行测试,主要是效验数据的交换,传递和控制管理过程,以及相互逻辑依赖关系。其中接口协议分为HTTP,RPC,Webservice,Dubbo,RESTful等类型。

  接口测试流程

    1、需求评审,熟悉业务和需求

    2、开发提供接口文档

    3、编写接口测试用例

    4、用例评审

    5、提测后开始测试

    6、提交测试报告

两种常见的 HTTP 请求方法:GET 和 POST

二、项目说明

  本框架是一套基于Python+Pytest+Requests+Allure+Jenkins而设计的数据驱动接口自动化测试的框架。

  技术栈

    Python、Pytest、Requests、Pactverity、Excel、Json、Mysql、Allure、Logbook、Git、Jenkins

三、接口测试框架结构图

四、项目功能

  Python+Pytest+Allure+Jenkins接口自动化框架,实现Excel或Json维护测试用例,支持数据库操作,利用封装的请求基类调取相应的测试用例接口,获取配置文件中的环境地址与环境变量,

结合Pytest进行单元测试,使用LogBook进行记录日志,并生成allure测试报告,最后进行Jenkins集成项目实现集成部署,并发送测试报告邮件。

五、代码设计与功能说明

1、工具类封装

1.1、log日志

  项目中的log日志是logbook进行日志记录的,方便测试开发调试时进行排错纠正或修复优化。日志可选择是否打印在屏幕上即运行时是否在终端输出打印。日志格式输出可调整。

  handle_log.py部分源码

def log_type(record, handler):
     log = "[{date}] [{level}] [{filename}] [{func_name}] [{lineno}] {msg}".format(
         date=record.time,  # 日志时间
         level=record.level_name,  # 日志等级
         filename=os.path.split(record.filename)[-1],  # 文件名
         func_name=record.func_name,  # 函数名
         lineno=record.lineno,  # 行号
         msg=record.message  # 日志内容
     )
     return log
 # 日志存放路径
 LOG_DIR = BasePath + '/log'
 print(LOG_DIR)
 if not os.path.exists(LOG_DIR):
     os.makedirs(LOG_DIR)
 # 日志打印到屏幕
 log_std = ColorizedStderrHandler(bubble=True)
 log_std.formatter = log_type
 # 日志打印到文件
 log_file = TimedRotatingFileHandler(
     os.path.join(LOG_DIR, '%s.log' % 'log'), date_format='%Y-%m-%d', bubble=True, encoding='utf-8')
 log_file.formatter = log_type
 
 # 脚本日志
 run_log = Logger("global_log")
 def init_logger():
     logbook.set_datetime_format("local")
     run_log.handlers = []
     run_log.handlers.append(log_file)
     run_log.handlers.append(log_std)

打印在终端的日志,如下图所示。

同时运行项目后,会在项目文件log中自动生成一个以当天日期命名的log文件。点击log日志文件可查看日志详情即项目运行时所记录的日志或报错日志。如下图所示。

1.2、配置文件

  项目中涉及到一些配置文件如username、password或环境变量时,我们可通过配置文件来获取配置值。通过配置文件中key与value的定义来确定获取配置文件的值。

  handle_init.py部分源码

class HandleInit:
     # 读取配置文件
     def load_ini(self):
         file_path = BasePath + "/config/config.ini"
         cf = configparser.ConfigParser()
         cf.read(file_path, encoding='UTF-8')
         return cf
 
     # 获取ini里面对应key的value
     def get_value(self, key, node=None):
         if node == None:
             node = 'Test'
         cf = self.load_ini()
         try:
             data = cf.get(node, key)
             logger.info('获取配置文件的值,node:{},key:{}, data:{}'.format(node, key, data))
         except Exception:
             logger.exception('没有获取到对应的值,node:{},key:{}'.format(node, key))
             data = None
         return data

获取配置文件中的值日志如下图所示。

1.3、Api接口请求

获取相关测试用例及接口用例配置,记录请求相关参数的日志,定义Allure测试报告的步骤。

handle_apirequest.py部分代码

class ApiRequest:
     def api_request(self, base_url, test_case_data, case_data):
         get_name = None
         get_url = None
         get_method = None
         get_headers = None
         get_cookies = None
         get_case_name = None
         get_case_params = None
         response_data = None
         try:
             get_name = test_case_data['config']['name']
             get_url = base_url + test_case_data['config']['url']
             get_method = test_case_data['config']['method']
             get_headers = test_case_data['config']['headers']
             get_cookies = test_case_data['config']['cookies']
         except Exception as e:
             logger.exception('获取用例基本信息失败,{}'.format(e))
         try:
             get_case_name = case_data['name']
             get_case_params = case_data['params']
         except Exception as e:
             logger.exception('获取测试用例信息失败,{}'.format(e))
         with allure.step("请求接口:%s,请求地址:%s,请求方法:%s,请求头:%s,请求Cookies:%s" % (
                 get_name, get_url, get_method, get_headers, get_cookies)):
             allure.attach("接口用例描述:", "{0}".format(get_case_name))
             allure.attach("接口用例请求参数:", "{0}".format(get_case_params))
         logger.info(
             '请求接口名:%r,请求地址:%r,请求方法:%r,请求头:%r,请求Cookies:%r' %\ 

1.4、Excel数据处理

1.4.1、Excel测试用例

  测试用例中维护在Excel文件中,类中定义如何获取Excel中的相关数据(如获取某个单元格的内容,获取单元格的行数,以及将数据写入Excel中等操作)。

  handle_exceldata.py部分源码

 1 class OperationExcel:
 2     def __init__(self, file_name=None, sheet_id=None):
 3         if file_name:
 4             self.file_name = file_name
 5             self.sheet_id = sheet_id
 6         else:
 7             self.file_name = ''
 8             self.sheet_id = 0
 9         self.data = self.get_data()
10 
11     # 获取sheets的内容
12     def get_data(self):
13         data = xlrd.open_workbook(self.file_name)
14         tables = data.sheets()[self.sheet_id]
15         return tables
16 
17     # 获取单元格的行数
18     def get_lines(self):
19         tables = self.data
20         return tables.nrows
21 
22     # 获取某一个单元格的内容
23     def get_cell_value(self, row, col):
24         return self.data.cell_value(row, col)

1.5、Json数据处理

1.5.1、Json测试用例

 1 {
 2     "config":{
 3         "name":"post接口名",
 4         "url":"/langdetect",
 5         "method":"POST",
 6         "headers":{
 7             "Content-Type":"application/json"
 8         },
 9         "cookies":{
10 
11         }
12     },
13     "testcase":[
14         {
15             "name":"测试用例1",
16             "params":{
17                 "query":"测试"
18             },
19             "validate":[
20                 {
21                     "check":"status_code",
22                     "comparator":"eq",
23                     "expect":"200"
24                 }
25             ]
26         },
27         {
28             "name":"测试用例2",
29             "params":{
30                 "query":"python"
31             },
32             "validate":[
33                 {
34                     "check":"msg",
35                     "comparator":"eq",
36                     "expect":"success"
37                 }
38             ]
39         }
40     ]
41 }

1.5.2、Json用例处理

  获取Json文件中里具体字段的值。

  handle.json.py部分源码

 1 class HandleJson:
 2     # 读取json文件
 3     def load_json(self, file_name):
 4         if file_name == None:
 5             file_path = ""
 6         else:
 7             file_path = file_name
 8         try:
 9             with open(file_path, encoding='UTF-8') as f:
10                 data = json.load(f)
11             return data
12         except Exception:
13             print("未找到json文件")
14             return {}
15 
16     # 读取json文件里具体的字段值
17     def getJson_value(self, key, file_name):
18         if file_name == None:
19             return ""
20         jsonData = self.load_json(file_name)
21         if key == None:
22             getJsonValue = ""
23         else:
24             getJsonValue = jsonData.get(key)
25         return getJsonValue

2、基类封装

2.1、请求基类封装

  接口支持Get、Post请求,调用requests请求来实现接口的调用与返回。接口参数包括,接口地址、接口请求参数、cookie参数、header参数。

 1 class BaseRequest:
 2 
 3     def send_get(self, url, data, header=None, cookie=None):
 4         """
 5         Requests发送Get请求
 6         :param url:请求地址
 7         :param data:Get请求参数
 8         :param cookie:cookie参数
 9         :param header:header参数
10         """
11         response = requests.get(url=url, params=data, cookies=cookie, headers=header)
12         return response
13 
14     def send_post(self, url, data, header=None, cookie=None):
15         """
16         Requests发送Post请求
17         :param url:请求地址
18         :param data:Post请求参数
19         :param data:Post请求参数
20         :param cookie:cookie参数
21         :param header:header参数
22         """
23         response = requests.post(url=url, json=data, cookies=cookie, headers=header)
24         return response
25 
26         # 主函数调用
27 
28     def run_main(self, method, url, data, header, cookie=None):
29         try:
30             result = ''
31             if method.upper() == 'GET':
32                 result = self.send_get(url, data, header, cookie)
33             elif method.upper() == 'POST':
34                 result = self.send_post(url, data, header, cookie)
35             return result
36         except Exception as e:
37             logger.exception('请求主函数调用失败:{}'.format(e))

3、接口测试用例编写

3.1、接口测试用例

  引用Pytest来进行接口的单元测试,通过JSON中多个测试用例来做为参数化数据驱动。结合Allure制定相应接口的测试报告。在接口返回断言之前,我们先进行该接口的契约测试,

我们采用的是Pactverity的全量契约校验测试。当契约测试通过时,我们再进行返回参数的相关校验测试。

  test_getRequestJson.py部分源码

 1 @allure.feature('测试GET请求模块')
 2 class TestRequestOne():
 3     @allure.title('测试标题')
 4     @allure.testcase('测试地址:https://www.imooc.com')
 5     @pytest.mark.parametrize('case_data', testCaseData['testcase'])
 6     def test_requestOne(self, case_data):
 7         try:
 8             api_response = apiRequest.api_request(baseurl, testCaseData, case_data)
 9             api_response_data = api_response.json()
10             # pactverity——全量契约校验
11             config_contract_format = Like({
12                 "msg": "成功",
13                 "result": 0,
14                 "data": EachLike({
15                     "word": Like("testng")
16                 })
17             })
18             mPactVerify = PactVerify(config_contract_format)
19             try:
20                 mPactVerify.verify(api_response_data)
21                 logger.info(
22                     'verify_result:{},verify_info:{}'.format(mPactVerify.verify_result, mPactVerify.verify_info))
23                 assert mPactVerify.verify_result == True
24             except Exception:
25                 err_msg = '契约校验错误'
26                 logger.exception('测试用例契约校验失败,verify_result:{},verify_info:{}'.format(mPactVerify.verify_result,
27                                                                                      mPactVerify.verify_info))
28             try:
29                 for case_validate in case_data['validate']:
30                     logger.info('断言期望相关参数:check:{},comparator:{},expect:{}'.format(case_validate['check'],
31                                                                                    case_validate['comparator'],
32                                                                                    case_validate['expect']))
33                     comparatorsTest.comparators_Assert(api_response, case_validate['check'],
34                                                        case_validate['comparator'], case_validate['expect'])
35                     logger.info('测试用例断言成功')
36             except Exception as e:
37                 logger.exception('测试用例断言失败')
38         except Exception as e:
39             logger.exception('测试用例请求失败,原因:{}'.format(e))

3.2、主运行

  运用Pytest和Allure的特性,命令行运行测试用例文件夹,并生成对应的allure测试报告。

1 if __name__ == "__main__":
2     pytest.main(['-s', '-v', 'test_case/testRequest/', '-q', '--alluredir', 'reports'])

4、Allure2测试报告

  当我们运行主函数时,并生成对应的测试用例报告时,我们可以看到在该文件夹中会生成对应的json文件的测试报告。将json文件的测试报告转换成html形式的。命令如下

  reports是json格式测试报告存放的目录位置,allure_reports是html测试报告文件生成的目录位置。allure命令如下。

1 allure generate reports -o allure_result/

  项目根目录下的allure_reports文件,存放的是allure生成的测试报告。可看出文件下有一个HTML文件,可通过Python的编辑器Pycharm来打开该HTML文件(测试报告),

或可通过allure命令来打开该HTML,展示HTML测试报告。如下所示。

测试报告文件,HTML测试报告如下。

allure命令打开HTML测试报告。命令如下所示。

1 allure open allure_result/

如下图所示。

打开生成的HTML测试报告如下图所示。

5、Jenkins集成

  Allure+Jenkins的分享,我之前在Pytest+Allure+Jenkins的博客中已经分享过了。这块可以出门左转看看。前期的准备就不在这里重复说明了。我们就直接来上手创建Item进行相关配置。

  General中GitHub项目地址的配置,将自己项目的Git复制至项目URL处。如下图所示。

   源码管理设置。勾选Git,填写相应的项目Git地址,Git项目权限所有者,以及对应的拉取代码的分支。如下图所示。

   配置构建命令。选择“执行windows批处理命令”,用python运行主函数运行脚本,命令如下图所示。

   当我们在Jenkins里面成功安装Allure插件后,直接可以在构建后操作中配置Allure的相关配置。在Pytest+Allure+Jenkins中已经说明过的。

Results应与项目运行时设置的Allure生成的Json格式报告的路径一致,Report path为Allure html报告结果生成文件存放的路径。

排除万难之后,我们就可以用Jenkins来运行项目了。如下图所示。

测试报告详情页,如下图所示。

六、后期优化

  1、接口测试用例之间的数据依赖

  2、测试报告邮件的发送

  。。。。。。

七、感想

   该框架是在涉及python的知识点比较多,将接口测试与契约测试结合起来。该框架是在工作之余学习多篇文章,实战上手逐步入门开始的,适合新手入门接口自动化实战练习,仅供参考学习。框架中有不少可优化点与不足点,希望大家多多提建议或想法。

进阶Python接口自动化测试必备教程(2023全网最详细)

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

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

相关文章

实用工具 | 语音文本对齐MFA的安装及使用

Montreal Forced Aligner(MFA)[1]是一个用于将音频和文本进行对齐的工具。它可以用于语音识别、语音合成和发音研究等领域。MFA支持多种语言和语音,用户可以根据需要自定义训练模型。 本博客介绍如何使用MFA对音频和文本进行对齐&#xff0c…

计算机网络实验:交换机划分Vlan配置

目录 前言实验目的实验内容实验过程总结 前言 计算机网络是当代信息技术的重要组成部分,也是现代社会的基础设施之一。为了提高计算机网络的性能和安全性,网络管理员需要对网络进行合理的规划和设计,包括对网络拓扑、地址分配、路由协议、交…

TP-LINK XDR6078 WiFi6路由器 简单开箱评测

TL-XDR6078易展版AX6000双频WiFi6路由器 简单开箱测评,新房快装修好了,先装上WiFi,挑了一会选中这个了,双2.5G电口,6000Mbps无线速率,还支持端口汇聚等等功能,感觉还不错。 TP-LINK XDR3040 Wi…

R语言 tidyverse系列学习笔记(系列2)表格的处理

创建一个得分表 score install.packages("dplyr") library(dplyr)install.packages("tibble") library(tibble)install.packages("stringr") library(stringr)score tibble(IDc("1222-1","2001-0","3321-1",&qu…

从JMeter Cookie管理器开始,轻松掌握接口测试技能!

目录 【前言】 【1. 添加Cookie管理器】 【2. 登录接口获取Cookie】 【3. Cookie关联】 【4. 动态修改Cookie值】 【结论】 【附录】 【前言】 在接口测试中,我们经常需要对Cookie进行处理和关联,来模拟用户在浏览器中的操作。特别是在登录和权限…

chatgpt赋能python:Python名字的由来

Python名字的由来 Python是一门高级编程语言,它的名字来源于一个非常有趣的故事。接下来的文章将介绍如何命名Python,并且揭示这个名字的真正含义。 Guido van Rossum设计Python Python是由Guido van Rossum设计的。在1989年,Guido在荷兰国…

用Flask-Login库和阿里云短信推送服务实现网站注册登录功能

诸神缄默不语-个人CSDN博文目录 本文介绍如何用Flask-Login库和阿里云短信推送服务实现网站注册登录功能。 大致逻辑是在注册和找回密码时调用阿里云短信服务,登录时使用手机号密码登录(别的安全功能还没有加)。 很多代码都是直接由ChatGP…

Zinx框架学习 - 连接管理

Zinx - V0.9 连接管理 每个服务器的能够处理的最大IO数量是有限的,根据当前服务器能开辟的IO数量决定,最终决定权是内存大小现在我们要为Zinx框架增加链接个数的限定,如果超过⼀定量的客户端个数,Zinx为了保证后端的及时响应&…

浏览器断点调试技巧

一、前言 日常开发中,当业务测试数据展示有问题时,我们需要快速去排查问题出现原因;但看了自己写的逻辑,很自信的觉得没问题但最终展示和逻辑对不上。这个需要我们便可以利用浏览器断点调试功能,来逐步调试对比逻辑来…

IDEA 终端命令行设置

一、说明 在使用 IDEA 进行程序开发时,需要使用到终端 Terminal 的功能,便于能够快速使用 shell 命令,进行各种相关的操作。 这些操作可以包括代码的版本控制、程序的打包部署等等 比如,前后端的集成开发环境(IDEA、We…

探究Cache缓存功能---【pytest】

前言 pytest运行完用例之后会生成一个 .pytest_cache的缓存文件夹,用于记录用例的ids和上一次失败的用例。 1、跑自动化时经常会出现这样一个情况,一轮自动化跑完后零星出现了几个失败测试用例,无法断定失败的原因,所以可能需要重…

2023新版Spring6全新讲解-核心内容之事务管理

Spring核心之事务 一、JdbcTemplate JdbcTemplate是Spring框架对JDBC操作进行的封装,可以简化方便对数据库的操作。 1.数据库表结构 准备一张普通的表 CREATE TABLE t_student (id int NOT NULL AUTO_INCREMENT,name varchar(32) DEFAULT NULL,age int DEFAULT N…

网络安全面试题大全(整理版)+附答案

随着国家政策的扶持,网络安全行业也越来越为大众所熟知,想要进入到网络安全行业的人也越来越多。 为了拿到心仪的 Offer 之外,除了学好网络安全知识以外,还要应对好企业的面试。 作为一个安全老鸟,工作这么多年&…

Vue.js 中的过渡动画是什么?如何使用过渡动画?

Vue.js 中的过渡动画是什么?如何使用过渡动画? 在 Vue.js 中,过渡动画是一种在元素插入、更新或删除时自动应用的动画效果,可以为应用程序增加一些动态和生动的效果。本文将介绍 Vue.js 中过渡动画的概念、优势以及如何使用过渡动…

谈“污”色变!如何应对测序中常见污染

微生物群落研究正在彻底改变人类对微生物学的理解,但是微生物污染的DNA存在于各种操作中包含从取样到测序结束。其中常用的DNA提取试剂盒和其他实验室试剂中也存在污染,其严重影响从微生物量较低的样品中获得的结果。 DNA污染的可能来源包括分子生物学级…

【嵌入式环境下linux内核及驱动学习笔记-(14)linux总线、设备、驱动模型之platform】

目录 1、新驱动架构的导入1.1 传统驱动方式的痛点1.2 总线设备驱动架构 2、platform 设备驱动2.1 platform总线式驱动的架构思想2.2 platform _device相关的数据类型2.2.1 struct platform_device2.2.2 struct platform_device_id2.2.3 struct resource2.2.4 struct device 2.3…

VSCode离线安装插件

一、前言 工作环境屏蔽外网,无法在VSCode客户端在线VSCode插件商店下载插件。因此,只能下载插件文件,并离线安装。 二、下载VSCode插件 1. 在VSCode插件商店中搜索需要的插件 2. 下载vsix格式插件 三、离线安装 VSCode 插件 1. 打开菜单Vi…

docker-compose部署hive数仓服务 —— 筑梦之路

1. docker创建网络 # 创建&#xff0c;注意不能使用hadoop-network docker network create hadoop_network# 查看 docker network ls 2. mysql部署 # 拉取镜像docker pull mysql:5.7# 生成配置mkdir -p conf/ data/db/cat > conf/my.cnf <<EOF [mysqld] character…

今天面了个字节跳动拿30k出来的测试大佬,让我见识到了什么是天花板

2022年堪称大学生就业最难的一年&#xff0c;应届毕业生人数是1076万。失业率超50%&#xff01; 但是我观察到一个数据&#xff0c;那就是已经就业的毕业生中&#xff0c;计算机通信等行业最受毕业生欢迎&#xff01; 计算机IT行业薪资高&#xff0c;平均薪资是文科其他岗位的…

Apache 日志解析和分析工具

ApacheWeb服务器在企业中广泛用于托管其网站和Web应用程序。Apache 服务器生成的原始日志提供了有关 Apache 服务器托管的网站如何处理用户请求以及访问您的网站时经常遇到的错误的宝贵信息。 什么是 Apache 日志 Apache 日志包含 Apache Web 服务器处理的所有事件的记录 - 从…