实现接口自动化测试

最近接到一个接口自动化测试的case,并展开了一些调研工作,最后发现,使用pytest测试框架并以数据驱动的方式执行测试用例,可以很好的实现自动化测试。这种方式最大的优点在于后续进行用例维护的时候对已有的测试脚本影响很小。当然,pytest还有以下其他优点:

可以让用户写出更为紧凑的测试套件;
涉及到的样板代码并不多,因此用户能够容易地编写和理解各种测试;
测试夹具(fixture)函数常被用来向测试函数添加某个参数,并返回不同的值。在pytest中,可以通过使用一个fixture来模块化另外一个。同时也可以使用多个fixture,在无需重写测试用例的情况下,将测试覆盖到所有参数的组合;
可扩展性强,pytest有许多实用的插件。例如:pytest-xdist可以在不使用其他测试器的情况下,被用于执行并行测试;pytest-rerunfailures可以在测试失败后重新运行,而且运行次数和运行之间的延迟时间都是可以设置的;allure/pytest-html生成测试报告;
相比较其它的测试框架,比如Robot Framework(在创建自定义的HTML报告方面比较繁琐,顶多能用来生成xUnit格式的简短报告)、UniteTest/PyUnit(需要大量的样板代码),pytest更适合作为本次自动化测试的框架。

下面为大家详细的介绍这种自动化测试的实现过程。

1 前期的准备工作
1.1 接口路径表
根据接口文档,将接口的地址和路径以及请求方式记录在excel表中,key:接口名称,type:请求方式,value:接口路径,第一行baseurl为基本路径,type不填。接口名称建议与接口文档中的接口名称一致,这样方便检查。如果同一个接口有多种请求方式,需要重新填写一行,type为相对应的请求方式。这样记录接口路径和请求方式是为了方便后面的数据提取和处理。

1.2 测试用例表
测试用例表中主要记录9列类型的数据,测试模块:将接口按照模块进行划分有利于问题的定位和数据的分类;

测试模块:将被测接口按照功能进行模块划分;
用例编号:主要用于记录用例的条数,建议按照模块名称进行命名,如:登录模块,用例编号为login_001,login_002;
用例标题:记录测试的内容;
前置条件:当被测接口需要其他接口的数据支撑时,在前置条件栏中填入需要的接口数据:如:login_001:token(login_001指用例编号,token指该用例执行后返回的响应参数中token字段的值),前提条件是该接口用例在本条用例之前;
测试步骤:方便于模块用例的执行;
请求接口:按照接口路径表中key的命名填写,需要请求登录接口时,就填写上图中表中key命名的登录接口。请求头部:当请求头部中有特殊的参数时,比如该接口需要身份验证authorization字段,而该字段的数据来源于登录接口返回的token,这种用例的请求头部应该这样填写: Content-Type=application/json,Authorization=<token>;
请求数据:填写测试用例的请求数据,按照key=value的格式记录,如果需要其他接口的返回数据,在前置条件中加入之后,再填写请求数据中需要的返回数据即可,如:username =admin,password=zxcvbnm,token=<token>;
断言:根据接口返回的数据进行断言,主要是验证返回数据中的某个字段是否正确,也是按照key=value的格式进行填写;

2 目录结构及运行流程
2.1 文件目录结构

testcase文件夹:存放测试用例表;
api文件夹:存放接口路径表;
common文件夹:common文件中存放通用的数据处理的脚本,如data.py和utlis.py(主要作用是将表中的数据进行处理,后面会进行详细的说明)、config.py(测试套件的基本配置);
report文件夹:用于存放测试完成后生成的测试报告;
conftest.py:属于pytest的一种全局公用的文件,一些通用的方法可以放在conftest.py中;
pytest.ini:pytest的配置文件;
2.2 测试的运行流程
触发自动化测试之后,测试数据的提取与处理并不会使用到pytest框架,当把数据处理为测试套件后,按模块分配给pytest进行执行,包括测试模块、http请求、断言。所有模块执行完之后将测试结果体现在生成的测试报告report.html中。测试结束之后可以通过邮件或者钉钉机器人的方式通知测试或开发本次自动化测试的测试结果。

3 测试用例的实现过程
下面简单介绍一下测试用例实现过程中部分脚本的作用。

3.1 读取excel表
使用xlrd库读取excel表中的内容,python中还有很多可以对excel的数据进行操作的库,如:openpyxl、xlsxwriter;循环遍历每一行的数据,保存为列表并赋值给self.list_data。

# -*- coding: utf-8 -*-
import xlrd
class Excel(object):
    def __init__(self, file_name):
        # 读取excel
        self.wb = xlrd.open_workbook(file_name)
        self.sh = self.wb.sheet_names()
        self.list_data = []
 
    def read(self):
        for sheet_name in self.sh:
            sheet = self.wb.sheet_by_name(sheet_name)
            rows = sheet.nrows
            for i in range(0, rows):
                rowvalues = sheet.row_values(i)
                self.list_data.append(rowvalues)

3.2 将数据格式化成测试套件
第一步将表格数据保存为列表后,还不是我们需要的数据格式,这样的数据列表不能直接使用,这里进行了一次数据的格式化。这里需要用到config.py中的case_header的配置,将中文的标题换成英文,并作为字典的key值。之后从第1个元素开始循环遍历data,将data中每个元素都以 [{'key1': 'value1', 'key2': 'value2'}, {}, {}, ...]的形式保存为list_dict_data并返回。
 

def data_to_dict(data):
    """
    :param data: data_list
    :return:
    """
    head = []
    list_dict_data = []
    for d in data[0]:
        d = case_header.get(d, d)
        head.append(d)
    for b in data[1:]:
        dict_data = {}
        for i in range(len(head)):
            if isinstance(b[i], str):
                dict_data[head[i]] = b[i].strip()
            else:
                dict_data[head[i]] = b[i]
        list_dict_data.append(dict_data)
    return list_dict_data
case_header = { 
	'测试模块': 'module', 
	'用例编号': 'id', 
	'用例标题': 'title', 
	'前置条件': 'condition', 
	'测试步骤': 'step', 
	'请求接口': 'api', 
	'请求方式': 'method', 
	'请求头部': 'headers', 
	'请求数据': 'data', 
	'断言': 'assert', 
	'步骤结果': 'score' }

3.3 生成可执行的测试套件
上一步已经将数据处理成了[{'key1': 'value1', 'key2': 'value2'}, {}, {}, ...]这样的格式,但是发现这样的格式没有将模块中的用例整合到一起,列表中每一个元素都是单独的一条用例,这样的话不利于用例的执行,所以,对上一步返回的数据再进行一次处理。因为测试用例和接口路径是保存在两个excel表中的,所以需要将两个表的数据进行合并。首先将接口路径表中的数据读取出来并处理成需要的格式 {'key': {'type': 'value', 'url': 'value'}},之后按照测试步骤中的顺序把测试用例保存在steps字典中。由于代码过长,下面只展示核心部分。
 

for d in data:
    # 将请求数据和断言数据格式化
    for key in ('data', 'assert', 'headers'):
        if d[key].strip():
            test_data = dict()
            for i in d[key].split(','):
                i = i.split('=')
                test_data[i[0]] = i[1]
            d[key] = test_data
    if d['module'].strip():
        if testcase:
            testsuite.append(testcase)
            testcase = {}
        testcase['module'] = d['module']
        testcase['steps'] = []
    no = str(d['step']).strip()
    if no:
        step = {'no': str(int(d['step']))}
        for key in ('id', 'title', 'condition', 'api', 'headers', 'data', 'assert'):
            if key == 'api':
                step[key] = {'type': apis[d.get(key, '')]['type'],
                             'url': apis['baseurl']['url'] + apis[d.get(key, '')]['url']}
            else:
                step[key] = d.get(key, '')
        testcase['steps'].append(step)
if testcase:
    testsuite.append(testcase)

3.4 pytest执行测试套件
将http请求封装在了conftest.py中,使用pytest数据驱动的特点,在执行测试文件test_login。py中不需要import就可以直接调用。这里只展示了发起post请求的代码,其它类型的请求类似,pytest.fixture通过固定参数request传递数据。然后使用'标记'中的pytest.mark.parametrize进行参数化和数据驱动更灵活。在fixture中的方法里面准备测试数据和前置依赖方法,在测试方法中参数化,测试方法调用准备数据和前置方法。pytest.mark.parametrize('post_request', data, indirect=True),indirect=True是把post_request当作函数去执行,data则是前面生成的模块的测试用例,其中包括了发起\http请求所需要的所有参数。

@pytest.fixture()
def post_request(request):
    data = request.param['data']
    header = request.param['headers']
    url = request.param['api']['url']
    no = request.param['no']
    logger.info(f'request: {data}')
    response = requests.request('POST', url=url, headers=header, data=json.dumps(data))
    logger.info(f'response: {response.json()}')
    return response, no
# -*- coding: UTF-8 -*-
import pytest
import allure
from common.data import module_data
 
 
class TestCase(object):
 
    @allure.feature('登录')
    @pytest.mark.parametrize('post_request', module_data(module='登录'), indirect=True)
    def test_login(self, post_request):
        response = post_request[0].json()
        no = int(post_request[1])
        assert response['msg'] == module_data(module='登录')[no - 1]['assert']['msg']
def module_data(module):
 
    excel = Excel(file_path.parent / 'testcase/testcase.xlsx')
    excel.read()
    cases = excel.list_data
    test_suit = suite_cases(data_to_dict(cases))
    for _ in test_suit:
        if _['module'] == module:
            data = _['steps']
            return data

3.5 运行测试用例
可以在pytest.ini中配置执行测试时的一些文件、类、方法的匹配规则和常用的命令参数,执行时只需要命令行输入D:\py_test>pytest就可以开始执行自动化测试。也可以不用pytest.ini配置,命令行执行D:\py_test>pytest -s test_login.py --html=report/report.html,-s参数:输出所有测试用例的print信息,安装了pytest-html插件后,在执行命令中加入--html=测试报告保存路径。

pytest.ini文件配置如下:

[pytest] 
# 打印print,生成保存报告 
addopts = -s --html=report/report.html 
# 匹配执行文件 
python_files = test_*.py 
# 匹配执行类 
python_classes = Test* 
# 匹配执行方法 
python_functions = test_*

3.6 结果展示
可以在ide中执行测试用例,也可以使用命令行执行,执行完测试用例后,会生成一个html格式的测试报告,在浏览器中打开就可以查看本次自动化测试的测试结果。pytest不仅支持pytest-html插件,还可以使用allure生成更加美观的测试报告。下面分别展示使用pytest-html和allure生成的html测试报告,pytest-html报告中记录的内容比较详尽,包括了用例运行日志、通过\失败\跳过用例条数、用例运行时间等等。allure生成的报告可读性比较强,可以很直观的看到测试结果。

pytest-html生成的测试报告:

allure生成的测试报告:

 

 

4 总结
整个项目完成之后,对pytest测试框架有了更深的理解。同时,pytest也可以使用Jenkins将自动化测试加入到持续集成中,设置定时任务构建或者条件触发构建等,这样可以有效的提高测试效率,也节省了人力成本。当然,不仅仅只有这一种实现方式,目前的实现方式还是有很多不足的地方,后面会继续进行完善和改进。如果你有什么好的建议和方法,欢迎一起进行沟通和交流。
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

文档获取方式:点击右边链接领取:软件测试全套资料分享     

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CAN201 计网概念收集

Lecture 1 the theoretical basis for networking Network edge and core 地理覆盖范围&#xff1a;广WAN&#xff0c;城MAN&#xff0c;局LAN&#xff0c;个PAN 交换方式&#xff0c;电路&#xff0c;报文&#xff0c;分组 电路交换vs报文vs分组 Network performance pr…

[AutoSar]基础部分 RTE 07 VFB虚拟功能总线

目录 关键词平台说明一、VFB1.1VFB是什么1.1VFB的好处1.2VFB的坏处 二、VFB在ECU内部的描述2.1Components2.2 Port-Interfaces2.3 Port2.4 Compositions 关键词 嵌入式、C语言、autosar、VFB 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语言C&#xff0…

浅析NVMe key per IO加密技术-3

三、Key per IO行业规范支持情况 Key Per I/O功能在行业规范中的支持情况&#xff1a; NVMe标准已经批准并采纳了NVMe TP4055提案&#xff0c;明确支持并定义了如何使用每个I/O操作独立的加密密钥技术。这意味着NVMe设备可以实现对每一个数据传输请求进行单独加密&#xff0c;…

降压恒压 耐压DC60V芯片,SL3037B替代HT7463A、兼容替代HT7463B

在当今的电子设备中&#xff0c;电源管理芯片扮演着至关重要的角色。它们负责为设备提供稳定的电压&#xff0c;确保设备的正常运行。然而&#xff0c;随着技术的不断发展&#xff0c;一些传统的电源管理芯片已经无法满足现代设备的需要。此时&#xff0c;寻找一种能够替代传统…

0111qt

实现闹钟&#xff0c;并播报懒虫...~ daytest.pro: QT core gui texttospeechgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (th…

nginx和CDN应用

一、代理的工作机制 1&#xff0e;代替客户机向网站请求数据&#xff0c;从而可以隐藏用户的真实IP地址。 2&#xff0e;将获得的网页数据&#xff08;静态 Web 元素&#xff09;保存到缓存中并发送给客户机&#xff0c;以便下次请求相同的数据时快速响应。 二、代理服务器的…

Windows7共享文档—开启方法及用户权限设置

使用计算机的朋友&#xff0c;在工作中经常需要在局域网中将文件共享给其他用户&#xff0c;这样其他人可以方便的通过局域网查看&#xff0c;甚至修改这些共享文件。当然&#xff0c;根据文件的重要程度&#xff0c;使用等级不同&#xff0c;不同的用户会赋予不同的权限&#…

进行商城的测试用例设计思路是什么?

进行商城的测试用例设计时&#xff0c;可以考虑以下思路&#xff1a; 1. 功能测试&#xff1a;测试商城的基本功能是否正常工作&#xff0c;包括用户注册、登录、浏览商品、搜索商品、添加商品到购物车、下单、支付等。 2. 数据验证测试&#xff1a;验证商城中的数据是否正确…

Linux 配置FTP服务器 + vsftpd服务安装配置 (Good篇)

CSDN 成就一亿技术人&#xff01; VSFTPD 实现客户端和服务器之间传输文件 CSDN 成就一亿技术人&#xff01; 目录 什么是VSFTPD&#xff1f; VSFTPD 的特点和功能 1. 设置和使用FTP服务器的步骤 1. 下载vsftpd包 2. 启动服务 开机自启 3. 关闭防火墙 4. 配置vsftpd服…

Base64编码:数据传输的安全使者

Base64编码是一种将二进制数据转换为可传输的文本表示形式的方法&#xff0c;它在全球范围内被广泛应用于网络通信、数据存储和传输等领域。本文将从多个方面介绍Base64编码的原理、应用及其在现实场景中的优势&#xff0c;帮助您深入了解这一重要的编码技术。 Base64编码解码…

MySql workBench客户端菜单汉化最新版

找到Mysql Workbench安装目录 如&#xff1a;D:\soft\MySQL\MySQL Workbench 8.0 CE\ 进入data目录&#xff1a;D:\soft\MySQL\MySQL Workbench 8.0 CE\data 里面有main_menu.xml文件&#xff0c;将汉化文件覆盖即可 main_menu.xml汉化内容 注意篇幅限制请移步下载完整版完…

Window平台安装MongoDB

在部署前需要在官网先确定系统对应的Mongo DB版本。 本机电脑为Window10&#xff0c;所以这里以MongoDB 6.0版本。 1 在官网下载安装包 2 安装MongoDB MongoDB Compass 是一个图形界面管理工具&#xff0c;如果勾选了安装会花费长一点时间&#xff0c;可以取消掉勾选&#xff…

C++ Primer 6.2参数传递 知识点+练习题

C Primer 6.2参数传递 知识点练习题 指针形参使用引用拷贝Const 形参实参尽量使用常量引用数组形参数组引用形参传递多维数组向main函数传参数含有可变形参的函数练习题待更新 指针形参 void reset(int *p) {*p0;//p指向的整型对象变为0p0;//只是对形参改变p&#xff0c;使其为…

NPN PNP SS8050 SS8550 S8050

SS8050的使用及引脚判断方法 今天讲的是NPN型三极管SS8050&#xff0c;主要分为以下几个方面&#xff1a; 一、前言 二、SS8050简介 三、NPN三极管与PNP三极管 四、三极管管脚识别方法 五、不拆卸三极管判断其好坏 六、S8050和SS8050的区别 七、三极管与MOS管的区别 八…

Modern C++ std::mutex底层原理

前言 我时常有这样的疑问&#xff1a; std::mutex怎么就能保证后面的语句100%安全哪&#xff1f;CPU reordering就不会把这些语句重排到mutex前面执行&#xff1f;而且各个CPU都是有L1、L2缓存的&#xff0c;如果mutex后面要访问的的变量在这些缓存中怎么办&#xff1f; 带着…

开启鸿蒙开发探索之旅ArkTS基本语法介绍(3)

上一章简单的介绍了鸿蒙HUAWEI DevEco Studio框架的搭建&#xff0c;这一章讲一下鸿蒙的主要开发一眼ArkTS的基本语法结构 1.ArkTS语法解释 ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript&#xff08;简称TS&#xff09;生态基础上做了进一步扩展&…

信道编码理论【信息论安全】

目录 一. 信道编码模型 二. 信道编码速率与错误译码率 2.1 信道编码速率 2.2 平均错误率 三. 信道容量 四. 小结 一. 信道编码模型 &#xff08;1&#xff09;消息 假定消息集合为M&#xff0c;如下&#xff1a; &#xff08;2&#xff09;编码 将消息m映射成码字&…

怎么在PDF添加文本框?6种快速向PDF添加文字教程

有时您可能希望填写表格或在 PDF 文件中留下评论。这需要您将文本框和文本添加到 PDF。文本框是一个文本字段&#xff0c;您可以在其中键入文本。但是&#xff0c;除非您使用专用的 PDF 编辑器&#xff0c;否则编辑 PDF 文件具有挑战性。了解正确的 PDF 工具和将文本框添加到 P…

松木和桉木建筑模板:它们的性能和用途有何区别?

在建筑行业中&#xff0c;选择合适的模板材料对于保证施工质量和效率至关重要。松木和桉木是两种常用的建筑模板材料&#xff0c;它们各有特点和优势。特别是桉木&#xff0c;在某些方面相比松木有显著的优势。 松木建筑模板的特点 松木因其广泛的可用性和经济性而被广泛应用…

软件工程各种图

参考视频&#xff1a; 6 分钟学会 UML 类图_哔哩哔哩_bilibili 5 分钟学会 UML 时序图&#xff08;顺序图、序列图&#xff09;_哔哩哔哩_bilibili 3 分钟学会 UML 活动图_哔哩哔哩_bilibili 6 分钟学会 UML 用例图_哔哩哔哩_bilibili 是真的讲的非常好&#xff01;&#…