接口自动化测试如何实现?5个步骤轻松拿捏!

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

  1. 可以让用户写出更为紧凑的测试套件;
  2. 涉及到的样板代码并不多,因此用户能够容易地编写和理解各种测试;
  3. 测试夹具(fixture)函数常被用来向测试函数添加某个参数,并返回不同的值。在pytest中,可以通过使用一个fixture来模块化另外一个。同时也可以使用多个fixture,在无需重写测试用例的情况下,将测试覆盖到所有参数的组合;
  4. 可扩展性强,pytest有许多实用的插件。例如:pytest-xdist可以在不使用其他测试器的情况下,被用于执行并行测试;pytest-rerunfailures可以在测试失败后重新运行,而且运行次数和运行之间的延迟时间都是可以设置的;allure/pytest-html生成测试报告;

相比较其它的测试框架,比如Robot Framework(在创建自定义的HTML报告方面比较繁琐,顶多能用来生成xUnit格式的简短报告)、UniteTest/PyUnit(需要大量的样板代码),pytest更适合作为本次自动化测试的框架。下面为大家详细的介绍这种自动化测试的实现过程。

前期的准备工作

1、接口路径表

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

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的格式进行填写;

目录结构及运行流程

1、文件目录结构

  • testcase文件夹:存放测试用例表;
  • api文件夹:存放接口路径表;
  • common文件夹:common文件中存放通用的数据处理的脚本,如data.py和utlis.py(主要作用是将表中的数据进行处理,后面会进行详细的说明)、config.py(测试套件的基本配置);
  • report文件夹:用于存放测试完成后生成的测试报告;
  • conftest.py:属于pytest的一种全局公用的文件,一些通用的方法可以放在conftest.py中;
  • pytest.ini:pytest的配置文件;

2、测试的运行流程

触发自动化测试之后,测试数据的提取与处理并不会使用到pytest框架,当把数据处理为测试套件后,按模块分配给pytest进行执行,包括测试模块、http请求、断言。所有模块执行完之后将测试结果体现在生成的测试报告report.html中。测试结束之后可以通过邮件或者钉钉机器人的方式通知测试或开发本次自动化测试的测试结果。

测试用例的实现过程

现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036【暗号:csdn999】

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

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) 

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、生成可执行的测试套件

上一步已经将数据处理成[{‘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)

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

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_* 

6、结果展示

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

pytest-html生成的测试报告:

allure生成的测试报告:

总结

整个项目完成之后,对pytest测试框架有了更深的理解。同时,pytest也可以使用Jenkins将自动化测试加入到持续集成中,设置定时任务构建或者条件触发构建等,这样可以有效的提高测试效率,也节省了人力成本。当然,不仅仅只有这一种实现方式,目前的实现方式还是有很多不足的地方,后面会继续进行完善和改进。如果你有什么好的建议和方法,欢迎一起进行沟通和交流。

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走!

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
 

在这里插入图片描述

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

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

相关文章

python+requests接口自动化完整项目设计源码

前言 有很多小伙伴吵着要完整的项目源码&#xff0c;完整的项目属于公司内部的代码&#xff0c;这个是没法分享的&#xff0c;违反职业道德了&#xff0c;就算别人分享了&#xff0c;也只适用于本公司内部的业务。 所以用例的代码还是得自己去一个个写&#xff0c;我只能分享…

4.4.2.1 内部类

内部类 成员内部类 定义 调用内部类 访问修饰符的影响 外部类的成员变量及成员方法在内部类的使用 内部类在外部类的使用 静态内部类 静态内部类调用非静态外部类 1

乡村电商人才齐聚浙江建德,这场农播氛围值已拉满!

“3、2、1&#xff0c;上链接!” “现场营造了很好的交流氛围&#xff0c;碰撞出了不少合作机会。” “农播让我们有机会为家乡农产品代言&#xff0c;并且通过电商平台&#xff0c;把优质农特产品卖到全国各地。” “就像是一个演员需要一个舞台&#xff0c;一个好产品也需…

企业邮箱认证指南:安全与高效的邮箱认证方法

企业邮箱是专门为企业提供的电子邮件服务&#xff0c;安全性和专业性更高。在开始使用企业邮箱之前&#xff0c;很多人会有一些问题&#xff0c;比如企业邮箱需要认证吗、如何开通企业邮箱&#xff0c;以及哪款企业邮箱好。 1、企业邮箱在使用前需要认证吗&#xff1f; 答案是肯…

数据结构(c语言版本) 二叉树的遍历

要求 实现二叉树的创建&#xff0c;并输入二叉树数据 然后先序遍历输出二叉树、中序遍历输出二叉树、后序输出二叉树 例如二叉树为&#xff1a; 该二叉树的先序遍历结果为&#xff1a; A B D C E F 该二叉树的中序遍历结果为&#xff1a; B D A E C F 该二叉树的后序遍历结果…

互联网上门预约洗衣洗鞋店小程序;

拽牛科技干洗店洗鞋店软件&#xff0c;方便快捷&#xff0c;让你轻松洗衣。只需在线预约洗衣洗鞋服务&#xff0c;附近的门店立即上门取送&#xff0c;省心省力。轻松了解品牌线下门店&#xff0c;通过列表形式展示周围门店信息&#xff0c;自动选择最近门店为你服务。简单填写…

分布式下多节点WebSocket消息收发

1、使用场景 2、疑问 第一次发送请求后&#xff0c;通过N1&#xff0c;W2&#xff0c;到达service2&#xff0c;建立websocket连接。 1、接下来发送的消息&#xff0c;通过Ngixn后和网关gateway后还能落在service2上面吗&#xff1f; 如果不能落在service2上&#xff0c;需要怎…

【C语法学习】25 - strncpy()函数

文章目录 1 函数原型2 参数3 返回值4 使用说明5 示例5.1 示例15.2 示例2 1 函数原型 strncpy()&#xff1a;将str指向的字符串的前n个字符拷贝至dest&#xff0c;函数原型如下&#xff1a; char *strncpy(char *dest, const char *src, size_t n);2 参数 strncpy()函数有三个…

【服务端性能测试】性能测试指标!

接触过性能测试的小伙伴一定都听过响应时间&#xff08;Response Time&#xff09;、TPS、CPU资源利用率等术语&#xff0c;它们都属于性能测试的指标。本文对性能测试中涉及到的指标做了较为详细的整理。 性能测试指标一般可以分为系统性能指标、资源指标、应用指标&#xff…

【路径穿越】vulfocus/apache-cve_2021_41773

1.1漏洞描述 漏洞编号cve_2021_41773漏洞类型路径穿越漏洞等级高危漏洞环境vulfocus攻击方式 1.2漏洞等级 高危 1.3影响版本 Apache HTTP Server 2.4.49、2.4.50 1.4漏洞复现 1.4.1.基础环境 靶场VULFOCUS工具BurpSuite 1.4.2.前提 1.5深度利用 1.5.1漏洞点 利用网上爆出…

Nginx 可视化管理平台:nginx-proxy-manager

本心、输入输出、结果 文章目录 Nginx 可视化管理平台:nginx-proxy-manager前言nginx-proxy-managernginx-proxy-manager 特性快速开始使用 Docker 网络开启 Docker 健康检查相关可视化页面相关链接弘扬爱国精神Nginx 可视化管理平台:nginx-proxy-manager 编辑:简简单单 Onl…

打开文件 和 文件系统的文件产生关联

补充1&#xff1a;硬件级别磁盘和内存之间数据交互的基本单位 OS的内存管理 内存的本质是对数据临时存/取&#xff0c;把内存看成很大的缓冲区 物理内存和磁盘交互的单位是4KB&#xff0c;磁盘中未被打开的文件数据块也是4KB&#xff0c;所以磁盘中页帧也是4KB&#xff0c;内存…

【AI视野·今日CV 计算机视觉论文速览 第277期】Fri, 27 Oct 2023

AI视野今日CS.CV 计算机视觉论文速览 Fri, 27 Oct 2023 Totally 93 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers A Coarse-to-Fine Pseudo-Labeling (C2FPL) Framework for Unsupervised Video Anomaly Detection Authors Anas Al lahham…

Xrdp+Cpolar实现远程访问Linux Kali桌面

XrdpCpolar实现远程访问Linux Kali桌面 文章目录 XrdpCpolar实现远程访问Linux Kali桌面前言1. Kali 安装Xrdp2. 本地远程Kali桌面3. Kali 安装Cpolar 内网穿透4. 配置公网远程地址5. 公网远程Kali桌面连接6. 固定连接公网地址7. 固定地址连接测试 前言 Kali远程桌面的好处在于…

【Spring Cloud】黑马头条 用户服务创建、登录功能实现

点击去看上一篇 一、创建用户 model 1.创建用户数据库库 leadnews_user 核心表 ap_user 建库建表语句 这里一定要使用 navicat&#xff0c;执行SQL 文件&#xff0c;以防止 cmd 中的编码问题 先将 SQL 语句&#xff0c;保存在电脑中&#xff0c;再使用 navicat 打开 CREATE…

代码静态测试工具之cppcheck

cppcheck简介 Cppcheck is an analysis tool for C/C code. It provides unique code analysis to detect bugs and focuses on detecting undefined behaviour and dangerous coding constructs. The goal is to detect only real errors in the code, and generate as few f…

数据库期末考前复习题(单选+多选+判断+解答)

文章目录 #数据库考前复习题一、 选择1.单选题2.多选题 二、判断题三、解答请描述数据库中的三大范式关系型数据库ACID特性 #数据库考前复习题 一、 选择 1.单选题 1.使用limit进行分页查询&#xff0c;其中每页10条数据&#xff0c;查询第5页应该写为&#xff1f; SELECT *…

java: 程序包XXX.XXX.XXX不存在解决方法

背景介绍&#xff1a; com.DXG.bean 来源于同一个项目底下的另一个包 问题所在&#xff1a; 明明已经引入了相关包 但是编译的时候报错&#xff1a;java: 程序包com.DXG.bean不存在 问题分析&#xff1a; 怀疑是拆模块以后引入相关包没有将相关包下载到本地maven仓库中 所以…

Qt QLable 字符过长省略

前言&#xff1a; 项目中常用到字符过长问题&#xff0c;Qt默认的省略并不好用&#xff0c;不是自己想要的&#xff1b; QFontMetri 可使用 QFontMetri 当text的像素宽度超过width&#xff0c;将返回字符串的一个省略版本取决于mode。否则将返回原字符串&#xff1b; mode…

C++面向对象编程(3)——常用关键字介绍(TODO)

本篇会逐步添加一些C的关键字&#xff0c;持续更新... 一. default 1.1 场景 如果对构造函数进行了重载&#xff0c;则编译器不会隐式的生成一个默认的构造函数&#xff0c;此时如果调用了默认构造函数会在编译时报错&#xff0c;但是很多时候我们是需要默认构造函数的。如何…
最新文章