如何用Python3+requests+unittest实现接口自动化测试实战

news2024/11/28 8:42:13

一、Requests介绍

首先让我们来看 Requests 官方的介绍:

Requests is an elegant and simple HTTP library for Python, built for human beings.

翻译过来就是:Requests 是为人类写的一个优雅而简单的 Python HTTP 库。这个介绍很直白了,让我们先来感受一下 Requests 的威力。

import requests
 
# 发送请求
response = requests.get(url="http://www.baidu.com/s", params={'wd':'python'})
# 处理响应
print(response.status_code)
 
#返回
200

 这个请求如果用 urllib 来实现,代码如下:

import urllib.parse
import urllib.request
 
url = "http://www.baidu.com/s"
params = urllib.parse.urlencode({'wd':'python'})
# 发送请求
response = urllib.request.urlopen('?'.join([url, params]))
# 处理响应
print(response.getcode())
 
#返回
200

从感官上就能看出来,使用 urllib 在 URL 、参数等方面会复杂一些。这只是冰山一角,实际使用中 Requests 还有好多方面超越 urllib ,它并不是浪得虚名,接下来的学习中你就会感受到。

二、unittest介绍

说到 Python 的单元测试框架,想必接触过 Python 的朋友脑袋里第一个想到的就是unittest。 的确,作为 Python 的标准库,它很优秀,并被广泛用于各个项目。但你知道吗?其实在 Python 众多项目中,主流的单元测试框架远不止这一个。

本系列文章将为大家介绍目前流行的 Python 的单元测试框架,讲讲它们的功能和特点并比较其异同,以让大家在面对不同场景、不同需求的时候,能够权衡利弊,选择最佳的单元测试框架。

三、Python3+requests+unittest

首先,我们可以捋一捋思路,想一想接口测试的流程

其次,选择合适的框架

流程清晰之后,我们需要选择一个合适的框架,于是选择了Python3+requests+unittest框架

Requests模块发送http的网络请求,请求类型主要包含了post,get, PUT,DELETE,HEAD

python+unittest单元测试框架构成,和测试报告生成(HTMLTestRunner)

框架详解不在此赘述,requests可参考

unittest参考点击查看

基于以上,我们来一步步搭建我们的框架。在这个过程中,我们需要做到业务和数据的分离,这样才能灵活,达到我们写框架的目的。接下来,我们来进行结构的划分。

我们的结构是这样的

 

data:存放自动化测试所用到的数据文档

log:存放生成的日志文件

base:存放公共的方法

report:存放生成的自动化测试报告

testcase:存放测试脚本

接下来,公共方法的开发

整体结构有了划分,接下来就该一步步的填充整个框架了,我们先来看看Base文件中的公共类或函数,这主要用于后续测试case的调用,所有公共的、一成不变的数据都可以放在这里,维护也方便

配置文档如下

[DATABASE]
data_address = ./data/
report_address = ./report/
 
[HTTP]
base_url = http://xxx.xx
 

 想知道怎样从配置文档中得到或写入相应的数据吗?那继续看吧

import os
import configparser
 
# 获取当前py文件地址
proDir = os.path.split(os.path.realpath(__file__))[0]
# 组合config文件地址
configPath = os.path.join(proDir,"config.ini")
 
class ReadConfig:
    def __init__(self):
        #获取当前路径下的配置文件
        self.cf = configparser.ConfigParser()
        self.cf.read(configPath)
 
    def get_config(self,field,key):
        #获取配置文件中的key值
        result = self.cf.get(field,key)
        return result
 
    def set_config(self,field,key,value):
        #向配置文件中写入配置信息
        fb = open(configPath,'w')
        self.cf.set(field,key,value)
        self.cf.write(fb)
 

那问题又来了,我们的测试数据放在哪里?怎么取值?怎么写入?怎么保存?。。。

别急,接着往下看

测试数据优先考虑放在excel或database中,此处以excel为例做个简单介绍

这里需要用到两个操作表格的库,xlrd数据驱动的读取,作用于excel文档,但xlrd不能写入数据,所以引入xlutils数据驱动的读取和写入

安装方法可以用pip3 install xlrd和pip3 install xlutils 来安装。

import xlrd
import xlutils.copy
from Base.readConfig import ReadConfig
import time
 
class ReadExcel:
 
    def __init__(self,section,field,sheet):
        # 打开工作表,并定位到sheet
        data_address = ReadConfig().get_config(section,field)
        workbook = xlrd.open_workbook(data_address)
        self.table = workbook.sheets()[sheet]
 
 
    def get_rows(self):
        # 获取excel行数
        rows = self.table.nrows
        return rows
 
    def get_cell(self,row,col):
        # 获取单元格数据
        cell_data = self.table.cell(row,col).value
        return cell_data
 
    def get_col(self,col):
        # 获取整列数据
        col_data = self.table.col_value(col)
        return col_data
 
class WriteExcel:
    def __init__(self,section,field,sheet):
        # 打开工作表
        self.address = ReadConfig().get_config(section,field)
        self.workbook = xlrd.open_workbook(self.address)
        self.wf = xlutils.copy.copy(self.workbook)
        self.ws = self.wf.get_sheet(sheet)
 
    def set_cell(self,row,col,value):
        #设置单元格数据
        self.ws.write(row,col,value)
 
    def save_excel(self,filename,format):
        #获取当前时间
        self.time = time.strftime("%Y%m%d%H%M%S", time.localtime())
        #生成文件的文件名及格式
        self.report = filename + '_' +self.time + format
        #保存文件
        self.wf.save(self.report)

然后,测试脚本的编辑

一切准备就绪,下面通过一个简单的、完整的代码进行演示公共函数的调用,框架的使用及报告的生成

import unittest
import requests
from Base.readConfig import ReadConfig
from Base.readExcel import ReadExcel
from Base.readExcel import WriteExcel
#实例化
readexcel = ReadExcel('DATABASE','data_address',0)
writeexcel = WriteExcel('DATABASE','data_address',0)
 
class testcase(unittest.TestCase):
    #初始化
    def setUp(self):
        #获取url
        self.base_url = ReadConfig().get_config('HTTP', 'base_url')
        self.url = self.base_url + readexcel.get_cell(1,1)
        #获取请求头
        self.headers = readexcel.get_cell(1,4)
 
    def test_case(self):
        nok = 0
        ner = 0
        # 循环读取excel中的测试数据,进行结果验证,并生成excel形式的测试报告
        for i in range(3,readexcel.get_rows()):
            #发送网络请求,得到响应值
            response = requests.post(self.url, headers=self.headers,   data=readexcel.get_cell(i,4).encode('utf-8'))
            actualresult = response.json()
            #获取excel中的预期结果
            expectresult = eval(readexcel.get_cell(i,6))
            # 获取需验证的数据
            key = eval(readexcel.get_cell(i, 5))
            keylen = len(key)
            j = 0
            for k in range(keylen):
                aresult = 'actualresult' + key[k]
                eresult = 'expectresult' + key[k]
                if eval(aresult) == eval(eresult):
                    #预期结果和实际结果一致
                    j = j + 1
            if j == keylen:
                #测试数据执行通过
                nok = nok + 1
                writeexcel.set_cell(i, 8, 'SUCCESS')
            else:
                # 测试数据执行失败,并将实际结果写入excel
                ner = ner + 1
                writeexcel.set_cell(i, 8, 'FAILURE')
                writeexcel.set_cell(i, 7, str(actualresult))
                print('第', i + 1, '行用例执行失败:预期结果是', expectresult, '实际结果是', actualresult)
            # 保存测试报告
            writeexcel.save_excel('testreport', '.xls')
            print('测试数据中总共', nok, '条用例执行通过', ner, '条用例执行失败')
 
    #释放资源
    def tearDown(self):
        pass
 
if __name__ == '__main__':
    #构造测试集合
    suite = unittest.TestSuite()
    suite.addTest(testcase('test_case'))
    #创建html文件
    filename = ReadConfig().get_config('DATABASE', 'report_address') + 'testreport.html'
    fb = open(filename,"wb")
    #执行测试并生成html测试报告
    runner = HTMLTestRunner.HTMLTestRunner(stream = fb,description = '针对接口的描述信息',title = '某某的自动化测试报告')
    runner.run(suite)
    #关闭文件
    fb.close()
 

最后,生成的html报告

感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
 

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取 

 

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

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

相关文章

SUB-1G芯片--PAN3028 一款低功耗远距离无线收发芯片

PAN3028 是一款采用 ChirpIoT TM 调制解调技术的低功耗远距离无线收发芯片,支持半双工无线通信,工作频段为 370~590 MHz 和 740~1180MHz,该芯片具有高抗干扰性、高灵敏度、低功耗和超远传输距离等特性。最高具有-140dBm 的灵敏度,…

逐步学习 Swagger enum:从入门到精通

enum 是 Swagger 规范中用来定义枚举类型的一种方式。它允许开发者在 API 文档中明确列出该接口的参数、返回值或请求体中可接受的枚举值。通过使用 Swagger enum,开发者可以更清晰地描述 API 的输入和输出,提高 API 文档的可读性和可维护性。 enum 使用…

《QT从基础到进阶·十八》QT中的各种鼠标事件QEvent

1、界面标题栏事件: NonClientAreaMouseButtonPress 标题栏点击事件 NonClientAreaMouseButtonRelease 标题栏释放事件 bool CustomPopDialog::event(QEvent* event) {switch (event->type()){case QEvent::MouseButtonRelease://Event of mouse releasing wind…

基于 HarmonyOS 的 HTTPS 请求过程开发示例(ArkTS)

介绍 本篇 Codelab 基于网络模块以及 Webview 实现一次 HTTPS 请求,并对其过程进行抓包分析。效果如图所示: 相关概念 ● Webview:提供 Web 控制能力,Web 组件提供网页显示能力。 ● HTTP数据请求:网络管理模块&am…

6、规划绩效域

1、变更 (1)变更有哪几种原因(类型)? 纠正措施(比如进度落后了,我们会有赶工和快速跟进的措施) 缺陷补救 预防措施 更新措施 2、变更的目的和变更控制流程的意义 考点1&#…

Vue框架项目,给容器添加水印watermark

1、在/utils下新增一个名为waterMark.js的脚本 具体水印样式可以在代码里自行调节style 参数 - 水印内容, 加水印的容器, 是否显示时间 let watermark {};function getCurrentDateTime() {const now new Date();const year now.getFullYear();const month String(now.ge…

Vue入门教学——编写第一个页面

以Vue2.0为例子。 1、创建一个Vue项目 创建过程:Vue-cli(脚手架)的创建_vue脚手架创建项目命令-CSDN博客【注】项目名不能有大写字母。创建完毕后,使用VSCode打开项目文件夹(其他编辑器也行)。 2、运行项…

人声与背景音乐源分离

一.人声分离项目说明 人声分离是将音频录音分离为各个源的任务。该存储库是音乐源分离的 PyTorch 实现。用户可以通过安装此存储库将自己喜欢的歌曲分成不同的来源。用户还可以训练自己的源分离系统。该存储库还可用于训练语音增强、乐器分离和任何分离系统。 2.1 环境配置 …

嵌入式开发:ST-LINK V2.1仿真器,Type-C接口

标题ST-LINK V2.1仿真器,Type-C接口 之前做的版本虽然也是V2.1的,但使用的接口是USB的Micro形式,不支持正反插,也不兼容现在通用的手机数据线,出差的时候又要多带一条线。 现在终于把我的ST-LINK的接口改了一下 如下…

修改Android Studio默认的gradle目录

今天看了一下,gradle在C盘占用了40多G。我C盘是做GHOST的,放在这里不方便。所以就要修改。 新建目录名(似乎无必要) ANDROID_SDK_HOMEG:\SOFTWARES\android-sdk GRADLE_USER_HOMEG:\SOFTWARES\.gradle 修改目录 File->Setti…

“探秘!根据关键词搜索商品列表的虾皮API大揭露!“

要使用虾皮API根据关键词获取商品列表,您需要使用虾皮API的搜索功能。以下是使用Python和虾皮API根据关键词获取商品列表的基本步骤: 注册虾皮API账号并获取API凭证(访问虾皮开放平台并创建应用以获取API凭证)。安装必要的Python…

软件学习心得

标定表示:通过不断修改软件控制参数,使得系统得到最佳运行状态 通过xcp协议进行标定(XCP寻址的通讯方式) A2L文件是上位机解析ECU描述文件数据库:存放了变量名称、数据格式、转换规则,还存放了ECU的通讯信息…

python 把函数的值赋给变量

嗨喽~大家好呀,这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 一个是模块的调用和一个自定义函数返回值赋值给变量 编写一个简单的函数模块: def run(name): list1 hello namereturn list1编写一个调用的脚…

Avalonia播放视频(mp4)

1.Nuget添加类库Dove.Avalonia.Extensions.Media,项目路径https://github.com/michael-eddy/Avalonia.Extensions/ 2.Nuget添加VideoLAN.LibVLC.Windows PlatformLibVLC PackageMinimum OS VersionWindowsVideoLAN.LibVLC.WindowsWindows XPUWPVideoLAN.LibVLC.UW…

EtherCAT超高速实时运动控制卡XPCIE1032H上位机C#开发(一):驱动安装与建立连接

XPCIE1032H功能简介 XPCIE1032H是一款基于PCI Express的EtherCAT总线运动控制卡,可选6-64轴运动控制,支持多路高速数字输入输出,可轻松实现多轴同步控制和高速数据传输。 XPCIE1032H集成了强大的运动控制功能,结合MotionRT7运动…

Intel x86_64 LBR功能

文章目录 前言一、CPUID指令1.1 CPUID功能简介1.2 输入参数01H返回结果1.2.1 ECX返回结果1.2.2 EDX返回结果 1.3 Linux中CPUID指令1.3.1 应用层调用cpid指令1.3.2 linux内核中调用cpuid指令 二、MSR寄存器2.1 MSR 寄存器简介2.2 RDMSR,WRMSR指令介绍2.3 IA32_DEBUGCTL MSR 寄存…

净利暴跌9成,主力业务下滑,这家全球知名CIS供应商如何“翻身”?

消费电子寒冬对上游供应链的影响还在持续。 近日,全球知名的CMOS图像传感器(CIS)供应商格科微发布三季报显示,前三季度共实现营业收入32.45亿元,同比下降29.01%;实现净利润4972.57万元,同比下降…

开发中常用的SQL语句

开发中常用的SQL语句 1.update更新时不能引用本身表2.备份MySQL3.函数的使用1. case,when的使用2. IF3.其它4.拼接5. 处理时间 4.导出表结构注释等 1.update更新时不能引用本身表 UPDATE student SET valid_flag 0 WHERE id IN (SELECT idFROM (SELECT su.idFROM student su …

如何接入电商数据(淘宝/京东)API接口的对接获取(商品详情|价格|SKU)

双11是电商行业的两个重大节点,这两大节日吸引了大量消费者参与,同时也为电商企业带来了巨大的销售机会和业绩增长。 作为疫情放开之后的第一场“战役”,今年618显然被寄予了厚望。无论是大型电商品牌还是小型电商商家,都在积极探…

SQL练习---511.游戏玩法分析 I

题目描述 分析 题目描述很简单,找出用户第一次登陆的时期,很简单一个用户有多个记录,因此按用户分组即可,但是不知道日期能否求出最小值,事实证明还是可以的。 题解 select player_id,min(event_date) first_login f…