接口自动化框架(Pytest+request+Allure)

前言:

接口自动化是指模拟程序接口层面的自动化,由于接口不易变更,维护成本更小,所以深受各大公司的喜爱。
接口自动化包含2个部分,功能性的接口自动化测试和并发接口自动化测试。
本次文章着重介绍第一种,功能性的接口自动化框架。

一、简单介绍

环境:Mac、Python 3,Pytest,Allure,Request
流程:读取Yaml测试数据-生成测试用例-执行测试用例-生成Allure报告
模块类的设计说明:

Request.py 封装request方法,可以支持多协议扩展(get\post\put)
Config.py读取配置文件,包括:不同环境的配置,email相关配置
Log.py 封装记录log方法,分为:debug、info、warning、error、critical
Email.py 封装smtplib方法,运行结果发送邮件通知
Assert.py 封装assert方法
run.py 核心代码。定义并执行用例集,生成报告

Yaml测试数据格式如下:

---
Basic:
  dec: "基础设置"
  parameters:
    -
      url: /settings/basic.json
      data: slug=da1677475c27
      header: {
                 "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko)\
                  Chrome/67.0.3396.99 Safari/537.36",
                 "Content-Type": "keep-alive"
              }

二、代码结构与框架流程

1、代码结构见下图:

2、框架流程见下图:


三、详细功能和使用说明

1、定义配置文件config.ini

该文件中区分测试环境[private_debug]和正式环境[online_release]分别定义相关配置项,[mail]部分为邮件相关配置项

# http接口测试框架配置信息
 
[private_debug]
# debug测试服务
tester = your name
environment = debug
versionCode = your version
host = www.jianshu.com
loginHost = /Login
loginInfo = email=wang@user.com&password=123456
 
[online_release]
# release正式服务
tester = your name
environment = release
versionCode = v1.0
host = www.jianshu.com
loginHost = /Login
loginInfo = email=wang@user.com&password=123456
 
[mail]
#发送邮件信息
smtpserver = smtp.163.com
sender = test1@163.com
receiver = wang@user.com
username = wang@user.com
password = 123456

2、读取yaml测试数据后封装

yaml测试数据例子见第一节,一条接口可定义多条case数据,get_parameter为已封装好的读取yaml数据方法,循环读取后将多条case数据存在list中。

class Basic:
    params = get_parameter('Basic')
    url = []
    data = []
    header = []
    for i in range(0, len(params)):
        url.append(params[i]['url'])
        data.append(params[i]['data'])
        header.append(params[i]['header'])

 3、编写用例

class TestBasic:
    @pytest.allure.feature('Home')
    @allure.severity('blocker')
    @allure.story('Basic')
    def test_basic_01(self, action):
        """
            用例描述:未登陆状态下查看基础设置
        """
        conf = Config()
        data = Basic()
        test = Assert.Assertions()
        request = Request.Request(action)
 
        host = conf.host_debug
        req_url = 'http://' + host
        urls = data.url
        params = data.data
        headers = data.header
 
        api_url = req_url + urls[0]
        response = request.get_request(api_url, params[0], headers[0])
 
        assert test.assert_code(response['code'], 401)
        assert test.assert_body(response['body'], 'error', u'继续操作前请注册或者登录.')
        assert test.assert_time(response['time_consuming'], 400)
        Consts.RESULT_LIST.append('True')

4、运行整个框架run.py

if __name__ == '__main__':
    # 定义测试集
    allure_list = '--allure_features=Home,Personal'
    args = ['-s', '-q', '--alluredir', xml_report_path, allure_list]
    log.info('执行用例集为:%s' % allure_list)
    self_args = sys.argv[1:]
    pytest.main(args)
    cmd = 'allure generate %s -o %s' % (xml_report_path, html_report_path)
 
    try:
        shell.invoke(cmd)
    except:
        log.error('执行用例失败,请检查环境配置')
        raise
 
    try:
        mail = Email.SendMail()
        mail.sendMail()
    except:
        log.error('发送邮件失败,请检查邮件配置')
        raise

5、err.log实例

[ERROR 2018-08-24 09:55:37]Response body != expected_msg, expected_msg is {"error":"继续操作前请注册或者登录9."}, body is {"error":"继续操作前请注册或者登录."}
[ERROR 2018-08-24 10:00:11]Response time > expected_time, expected_time is 400, time is 482.745
[ERROR 2018-08-25 21:49:41]statusCode error, expected_code is 208, statusCode is 200 

6、Assert部分代码

    def assert_body(self, body, body_msg, expected_msg):
        """
        验证response body中任意属性的值
        :param body:
        :param body_msg:
        :param expected_msg:
        :return:
        """
        try:
            msg = body[body_msg]
            assert msg == expected_msg
            return True
 
        except:
            self.log.error("Response body msg != expected_msg, expected_msg is %s, body_msg is %s" % (expected_msg, body_msg))
            Consts.RESULT_LIST.append('fail')
 
            raise
 
    def assert_in_text(self, body, expected_msg):
        """
        验证response body中是否包含预期字符串
        :param body:
        :param expected_msg:
        :return:
        """
        try:
            text = json.dumps(body, ensure_ascii=False)
            # print(text)
            assert expected_msg in text
            return True
 
        except:
            self.log.error("Response body Does not contain expected_msg, expected_msg is %s" % expected_msg)
            Consts.RESULT_LIST.append('fail')
 
            raise

7、Request部分代码

    def post_request(self, url, data, header):
        """
        Post请求
        :param url:
        :param data:
        :param header:
        :return:
        """
        if not url.startswith('http://'):
            url = '%s%s' % ('http://', url)
            print(url)
        try:
            if data is None:
                response = self.get_session.post(url=url, headers=header)
            else:
                response = self.get_session.post(url=url, params=data, headers=header)
 
        except requests.RequestException as e:
            print('%s%s' % ('RequestException url: ', url))
            print(e)
            return ()
 
        except Exception as e:
            print('%s%s' % ('Exception url: ', url))
            print(e)
            return ()
 
        # time_consuming为响应时间,单位为毫秒
        time_consuming = response.elapsed.microseconds/1000
        # time_total为响应时间,单位为秒
        time_total = response.elapsed.total_seconds()
 
        Common.Consts.STRESS_LIST.append(time_consuming)
 
        response_dicts = dict()
        response_dicts['code'] = response.status_code
        try:
            response_dicts['body'] = response.json()
        except Exception as e:
            print(e)
            response_dicts['body'] = ''
 
        response_dicts['text'] = response.text
        response_dicts['time_consuming'] = time_consuming
        response_dicts['time_total'] = time_total
 
        return response_dicts

四、Allure报告及Email

1、Allure报告总览,见下图:

2、Email见下图:


五、后续优化

1、集成Jenkins,使用Jenkins插件生成Allure报告
2、多线程并发接口自动化测试
3、接口加密,参数加密

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

在这里插入图片描述

软件测试面试小程序

被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!

涵盖以下这些面试题板块:

1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux

6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!   

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

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

相关文章

Python Opencv实践 - 直方图显示

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_COLOR) print(img.shape)#图像直方图计算 #cv.calcHist(images, channels, mask, histSize, ranges, hist, accumulate) #images&…

爱校对发布全新PDF校对工具,为用户带来更为便捷的校正体验

随着数字化文档使用的普及,PDF格式已经成为最为广泛使用的文件格式之一。为满足广大用户对于高效、准确PDF文档校对的需求,爱校对团队经过深入研发,正式推出全新的PDF校对工具! 这一全新工具针对PDF文件格式进行了深度优化&#…

TRON归集回调

简介 设计一个通过调用api创建对应的tron地址,当地址收到token的时候,进行归集&回调通知的。包括的功能有: 根据UID创建地址归集(TRX归集 TRC10归集 TRC20归集)回调通知(转出回调通知&接收回调通知)发起转出…

vue组件的scope 以及 如何样式穿透

个人复习!!! 有什么用 让当前组件的样式不会修改到其它地方的样式,使用了data-v-hash的方式来使css有了它对应模块的标识 实现原理 1、给HTML的dom节点添加一个不重复的data属性(例如: data-v-5558831a)来唯一标识这个dom 元素…

Four Operations

一、题目 Little Ruins is a studious boy, recently he learned the four operations! Now he want to use four operations to generate a number, he takes a string which only contains digits ‘1’ - ‘9’, and split it into 5 5 intervals and add the four operat…

LRU淘汰策略执行过程

1 介绍 Redis无论是惰性删除还是定期删除,都可能存在删除不尽的情况,无法删除完全,比如每次删除完过期的 key 还是超过 25%,且这些 key 再也不会被客户端访问。 这样的话,定期删除和堕性删除可能都彻底的清理掉。如果…

设计模式——接口隔离原则

文章目录 基本介绍应用实例应传统方法的问题和使用接口隔离原则改进 基本介绍 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上先看一张图: 类 A 通过接口 Interface1 依赖类 B,类 C 通过接口 Interface1 依赖类 D&…

A 题国际旅游网络的大数据分析-详细解析与代码答案(2023 年全国高校数据统计与调查分析挑战赛

请你们进行数据统计与调查分析,使用附件中的数据,回答下列问题: ⚫ 问题 1: 请进行分类汇总统计,计算不同国家 1995 年至 2020 年累计旅游总人数,从哪个国家旅游出发的人数最多,哪个国家旅游到达的人数最多…

19.图,图的两种存储结构

目录 一. 一些基本概念 二. 图的抽象数据类型定义 三. 图的存储结构 (1)数组表示法(邻接矩阵表示法) (a)邻接矩阵 (b)存储表示 (c)优缺点分析 &#x…

前端工程化概述

软件工程定义:将工程方法系统化地应用到软件开发中 前端发展历史 前端工程化的发展历史可以追溯到互联网的早期阶段,随着前端技术的不断演进和互联网应用的复杂化,前端工程化也逐渐成为了前端开发的重要领域。以下是前端工程化的主要发展里程…

【了解一下常见的设计模式】

文章目录 了解一下常用的设计模式(工厂、包装、关系)导语设计模式辨析系列 工厂篇工厂什么是工厂简单工厂「模式」(Simple Factory「Pattern」)简单工厂代码示例:简单计算器优点:缺点: 静态工厂模式特点: 工…

手搭手入门MyBatis-Plus

MyBatis-Plus Mybatis-Plus介绍 为简化开发而生 MyBatis-Plus(opens new window)(简称 MP)是一个 MyBatis(opens new window) 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 特性 无侵入&#…

protobuf+netty自定义编码解码

protobufnetty自定义编 项目背景 protobufnetty自定义编码解码 比如心跳协议,客户端请求的协议是10001,在java端如何解码,心跳返回协议如何编码,将协议号带过去 // 心跳包 //10001 message c2s_heartbeat { }//10002 message …

LeetCode--HOT100题(38)

目录 题目描述:226. 翻转二叉树(简单)题目接口解题思路代码 PS: 题目描述:226. 翻转二叉树(简单) 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 LeetCode做题链…

lvs-DR模式:

lvs-DR数据包流向分析 客户端发送请求到 Director Server(负载均衡器),请求的数据报文(源 IP 是 CIP,目标 IP 是 VIP)到达内核空间。 Director Server 和 Real Server 在同一个网络中,数据通过二层数据链路…

7-42 整型关键字的散列映射

题目链接:这里 题目大意:就是写一个线性探测的散列 然鹅,我不会写(?)我一共错了两个地方 有冲突的情况下,就是线性探查然后往后找,但是我之前写的是t,应该是t (t1)%p;…在有重复关键字的时候&#xff0c…

大学生创业出路【第二弹】科创训练营

目录 🚀一、我从哪里了解到的训练营 🚀二、训练营里学习和日常 🔎学习 🔎环境和设备 🔎遇到的人 🔎团队记录视频 🚀三、感悟 ​​​​个人主页:一天三顿-不喝奶茶&#x1f39…

UE4/5Niagara粒子特效之Niagara_Particles官方案例:1.5->2.3

目录 之前的文章: 1.5 Blend Attributes by Value 发射器更新 粒子生成 粒子更新 2.1 Static Beams ​编辑 发射器更新: 粒子生成 粒子更新 2.2 Dynamic Beams 没有开始模拟前的效果是: 开始模拟后的效果是: 发射器更新 …

数据结构入门 — 顺序表详解

前言 数据结构入门 — 顺序表详解 博客主页链接:https://blog.csdn.net/m0_74014525 关注博主,后期持续更新系列文章 文章末尾有源码 *****感谢观看,希望对你有所帮助***** 文章目录 前言一、顺序表1. 顺序表是什么2. 优缺点 二、概念及结构…

java-IONIO

一、JAVA IO 1.1. 阻塞 IO 模型 最传统的一种 IO 模型,即在读写数据过程中会发生阻塞现象。当用户线程发出 IO 请求之后,内 核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线…