全网最牛,Python接口自动化测试实战干货-项目接口案例,看这篇足够...

news2024/11/17 3:37:48

目录:导读

    • 前言
    • 一、Python编程入门到精通
    • 二、接口自动化项目实战
    • 三、Web自动化项目实战
    • 四、App自动化项目实战
    • 五、一线大厂简历
    • 六、测试开发DevOps体系
    • 七、常用自动化测试工具
    • 八、JMeter性能测试
    • 九、总结(尾部小惊喜)


前言

1、单元测试主要做什么?

测试发现:从多个文件里面去找到我们的测试用例;
测试执行:按照一定的顺序和规则去执行,并生成结果;
测试判断:通过断言判断预期结果和实际结果的差异;
测试报告:统计测试进度,耗时,通过率,生成测试报告;

单元测试框架只是自动化测试框架中的组成部分之一。

自动化测试框架中还包括:设计模式、数据驱动、关键字驱动、全局配置文件的封装、日志监控、selenium和requests二次封装、断言、报告邮件…

2、pytest中的装饰器@pytest.mark.parametrize()的基础用法

所有的测试框架都离不开数据驱动,那数据驱动是什么?

数据驱动:其实就是把我们测试用例的数据放到excel、yaml、csv、mysql。然后通过去改变数据到改变测试用例的执行结果。

@pytest.mark.parametrize(args_name,args_value)

args_name:参数的名称
args_value:参数的值(支持格式:列表、元组,字典列表、字段元组,即:[]、()、[{},{},{}]、({},{},{})),值的注意的是,参数的值有多少个,这个方法就被执行多少次。

pytest默认的测试用例规则:(可以根据pytest.ini配置文件进行修改)

模块名必须以test_或者_test开头;
类名必须以Test开头;
方法名必须以test开头;

使用的方式:

方式1:最基本的用法

import pytest

class TestApi:

    @pytest.mark.parametrize('args', ['张三', '李四', '王五', '赵六'])
    def test_01_api(self, args):
        print(args)

if __name__ == '__main__':
    pytest.main(['-vs', 'test_api.py'])

执行以上代码,test_01_api用例会执行四次,分别将’张三’, ‘李四’, ‘王五’, '赵六’打印出来。-vs指令参数表示打印出较为详细的日志信息。test_api.py表示执行的文件。

执行结果:

在这里插入图片描述

方式2:解包的用法

若我们将传入参数的格式进行变化,如下图所示,参数的值写成两个list,测试用例就会执行两次,而这两次分别传入两个list。

在这里插入图片描述

现在我们传入两个参数名称,如下图所示,观察运行结果会发现,每一个list中的第一个元素会传给name,第二个元素会传给age,这就是解包的用法,此方法与unittest框架中实现数据驱动的装饰器ddt类似。

在这里插入图片描述

import pytest

class TestApi:

    @pytest.mark.parametrize('name,age', [['张三', 20], ['王五', 21]])
    def test_01_api(self, name, age):
        print(name, age)
        
if __name__ == '__main__':
    pytest.main(['-vs', 'test_api.py'])

3、Pytest结合yaml实现数据驱动

1)yaml简介

yaml它是一个数据文件保存的一个数据格式,支持注释、换行、裸字符串(最小单位的数据)

2)yaml用途

用于全局配置文件:环境、数据库信息、账号信息、日志格式、报告名称。
用于接口自动化里面多一些复杂的多接口串联。
用于编写接口测试用例。

3)yaml语法规则

区分大小写
和Python一样也是通过缩进的方式来表示层级关系
和缩进多少层无关,只和左边是否对齐有关系
#表示注释

4)yaml数据组成举例

map对象:键(空格)值

在这里插入图片描述

数组(列表):用一组横线开头

在这里插入图片描述

用来验证yaml文件格式或者json文件格式是否正确的网站:https://www.bejson.com/

数据驱动实战:

新建一个yaml文件data.yaml,编写代码如下:

在这里插入图片描述

-
  api_name: 获取网易新闻
  api_request:
    url: https://api.apiopen.top/getWangYiNews
    method: post
    headers:
      Content-Type: application/json
    params:
      page: 1
      count: 5
  api_validate:
    - eq: {code: 200}

新建一个Python文件yaml_util.py,封装读取yaml文件数据的函数。

在这里插入图片描述

import yaml

# 读取yaml文件内容的函数
def read_yaml():

    with open('data.yaml', encoding='utf_8', mode='r') as f:
        data = yaml.load(f, Loader=yaml.FullLoader)
        return data

新建一个Python文件test_api.py编写测试用例

import pytest
import requests
from pytest_yaml.yaml_util import read_yam

class TestApi:

    @pytest.mark.parametrize('args', read_yaml())
    def test_01_api(self, args):
        url = args['api_request']['url']
        method = args['api_request']['method']
        headers = args['api_request']['headers']
        params = args['api_request']['params']

        if method == 'get':
            requests.get(url)
        else:
            resp = requests.post(url, json=params, headers= headers)
            print(resp.json())

if __name__ == '__main__':
    pytest.main(['-vs', 'test_api.py'])

运行结果:

在这里插入图片描述

添加断言

在这里插入图片描述

如上图所示,获取yaml文件中断言的数据列表,所有多个断言,采用for循环遍历,使用assert方法进行断言,运行之后成功。

以上所实现的接口测试是最基础的,采用了一个接口,执行一个测试用例,只有一次断言。若在实际工作中使用,这远远是不够的。

4、接口实战

1)获取token鉴权码接口

使用微信开放文档中获取Access token接口进行练习,接口文档为:

在这里插入图片描述

由接口文档可知,方法为Get,接口地址为:api.weixin.qq.com/cgi-bin/tok… ,接口需要传入的参数为grant_type、appid、secret。

使用Python访问该接口,将响应的值打印到控制台,如下所示:

在这里插入图片描述

import unittest
import requests

class TestApi(unittest.TestCase):
    def test_01_get_token(self):
        url = " https://api.weixin.qq.com/cgi-bin/token"
        params = {
            "grant_type": "client_credential",
            "appid": "xxxxxxxxxxxxx",
            "secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
        }
        resp = requests.get(url, params=params)
        print(resp.json())

添加断言:

断言返回的状态码是否为200

self.assertEqual(resp.status_code, 200)

断言返回的结果中是否包含access_token

self.assertIn('access_token', resp.text)

断言返回的结果中expires_in的值是否等于7200

self.assertEqual(dict_result['expires_in'], 7200)

反序列化
把json格式的字符串转化为字典格式dict_result = json.loads(resp.text)
直接将响应的内容获取为字典格式dict_result = resp.json()

import json
import unittest
import requests


class TestApi(unittest.TestCase):
    def test_01_get_token(self):
        url = " https://api.weixin.qq.com/cgi-bin/token"
        params = {
            "grant_type": "client_credential",
            "appid": "xxxxxxxxxxxxx",
            "secret": "xxxxxxxxxxxxxxxxxxx"
        }
        resp = requests.get(url, params=params)
        print(resp.text, type(resp.text))

        # 方法一:反序列化,把json格式的字符串转化为字典格式
        dict_result = json.loads(resp.text)
        
        # 方法二:直接将响应的内容获取为字典格式
        # dict_result = resp.json()

        # 断言
        # 断言返回的状态码是否为200
        self.assertEqual(resp.status_code, 200)      # 状态断言
        # 断言返回的结果中是否包含access_token
        self.assertIn('access_token', resp.text)     # 业务断言1
        # 断言返回的结果中expires_in的值是否等于7200
        self.assertEqual(dict_result['expires_in'], 7200)    #  业务断言2

2)获取公众号已创建的标签

接口文档如下:

在这里插入图片描述

import unittest
import requests


class TestApi(unittest.TestCase):
    # 定义一个全局变量、类变量
    access_token = ""

    # 获取access_token
    def test_01_get_token(self):
        url = " https://api.weixin.qq.com/cgi-bin/token"
        params = {
            "grant_type": "client_credential",
            "appid": "wx5046a51617ff683a",
            "secret": "334c600a9fbbcadac918d5665d7b1d12"
        }
        resp = requests.get(url, params=params)
        print(resp.text, type(resp.text))

        # 反序列化,把json格式的字符串转化为字典格式
        dict_result = resp.json()
        # 获取鉴权码access_token并保存
        TestApi.access_token = dict_result['access_token']
        # 断言
        # 断言返回的状态码是否为200
        self.assertEqual(resp.status_code, 200)      # 状态断言
        # 断言返回的结果中是否包含access_token
        self.assertIn('access_token', resp.text)     # 业务断言1
        # 断言返回的结果中expires_in的值是否等于7200
        self.assertEqual(dict_result['expires_in'], 7200)    #  业务断言2

    # 获取公众号已创建的标签
    def test_02_select_flag(self):
        url = "  https://api.weixin.qq.com/cgi-bin/tags/get"
        params = {
            "access_token": TestApi.access_token
        }
        resp = requests.get(url, params=params)
        print(resp.json())

        # 断言返回的状态码是否为200
        self.assertEqual(resp.status_code, 200)  # 状态断言
        # 断言返回的结果中是否包含tags
        self.assertIn('tags', resp.text)  # 业务断言

3)接口关联

以上接口文档可知,接口2的执行需要传入接口1中返回的access_token,那么,如何实现access_token的关联呢?

定义一个全局变量access_token = “”;

在接口1响应内容中获取access_token的值并保存到全局变量中TestApi.access_token = dict_result[‘access_token’]

将全局变量access_token作为参数传入接口2中 “access_token”: TestApi.access_token

可将全局变量获取之后保存在yaml文件中。

5、Cookie、session、Token鉴权解决方案

什么是cookie?
cookie是在服务器产生的存储在客户端的一小段文本信息。格式是字典,键值对。

cookie的分类:
会话级:保存内存,当浏览器关闭就会消失。
持久化:保存硬盘,只有当失效时间到了才会被清除。

如何查看cookie?

在这里插入图片描述

cookie如何实现鉴权(原理)

当客户第一次访问服务器时,那么服务器就会产生cookie,然后通过响应头的方式在set-cookie里面传输到客户端,客户端从第2-N次请求都会自动的带上这些cookie。

致命的弱点:cookie保存在客户端,对于一些敏感的信息,比如用户名、密码、身份证号这些信息都不安全。

用python实现一个登录接口,并从响应中提取token。

接口为post请求,参数和响应结果如下所示:

在这里插入图片描述

在这里插入图片描述

用python发送请求,代码如下:

import requests
import unittest
import json

class TestApi(unittest.TestCase):

    def test_01_api(self):

        url = "http://api-store**************staff/login"

        jsontext = {
            "account": "188********",
            "password": "123456"
        }
        data = {
            "device_type": 30,
            "system": 2,
            "jsonText": json.dumps(jsontext)
        }

        headers = {
            "Content-Type": "application/x-www-form-urlencoded"
        }

        resp = requests.post(url, data=data, json=json,headers=headers)
        print(resp.text)


if __name__ == '__main__':
    unittest.main()

执行结果如下:

在这里插入图片描述

通过正则表达式取出token的值

# 通过正则表达式提取token的值
value = re.search('"token":"(.+?)"', resp.text)
print(value.group(1))

在这里插入图片描述

将获取的token保存到全局变量中

import re
import requests
import unittest
import json


class TestApi(unittest.TestCase):

    # 定义一个全局变量
    token = ""

    def test_01_api(self):

        url = "http://api***********/login"

        jsontext = {
            "account": "188******",
            "password": "123456"
        }
        data = {
            "device_type": 30,
            "system": 2,
            "jsonText": json.dumps(jsontext)
        }

        headers = {
            "Content-Type": "application/x-www-form-urlencoded"
        }

        resp = requests.post(url, data=data, json=json,headers=headers)
        print(resp.text)

        # 通过正则表达式提取token的值
        value = re.search('"token":"(.+?)"', resp.text)

        # 将提取的token值保存为一个全局变量
        TestApi.token = value.group(1)

        # 后面需要用到token的操作可以直接使用全局变量
        print(TestApi.token)


if __name__ == '__main__':
    unittest.main()

如果在下个接口测试的时候我们需要传入cookies,那么我们就可以定义一个保存cookies的全局变量test_cookies = “”。

通过test_cookies = resp.cookies提取cookies并保存到全局变量test_cookies中,在下面接口测试中将cookies传入,即:requests.post(url, data=data, json=json,
headers=headers, cookies=test_cookies),这样就实现了Cookie的鉴权。

session鉴权:

当用户第一次访问服务器的时候,然后在服务器端会保存一个sessionid,这个sessionid是经过加密的,然后通过cookie把这个sessionid保存到客户端,在请求服务器的时候只发送sessionid。

class TestApi(unittest.TestCase):

    # 定义一个全局变量
    session = ""

    def test_01_api(self):

        url = "http://**********"
        TestApi.session = requests.Session()
        # 请求的时候发送sessionid
        res = TestApi.session.get(url=url)
        print(TestApi.session)
        print(res.json())

        
if __name__ == '__main__':
    unittest.main()

session鉴权的致命弱点:

对于浏览器来说sessionid是非常好用的,只需要在cookie中存一个字符串就行了,但是服务器必须存储所有在线的用户sessionid,那么同时在线的人数越多开销越大,严重影响了服务器的性能。当用户量特别大的时候,会导致服务器崩溃。

token鉴权:

上述的解决方案都是围绕session,那么能不能不用sessionid来解决呢?

如果不适用sessionid,如何确保数据是服务器生成的呢?怎么去验证呢?用户信息存在哪?

于是有人想到了自己按照一定规则生成加密字符串,服务器只验证不存储,只要验证通过说明是自己生成的,用户信息存储在加密字符串中,这样性能、CORS(跨域资源共享)都能解决,而这个加密字符串就是token。

当一个用户登录之后,就给他发送一个token令牌,下一次用户再次请求的时候只需要带上这个令牌。

token的加密方式:
对称加密:DES AES
双钥加密:RSA
只加密不解密:MD5 SHA

token的分类:
access_token:有时间限制,限制在15分钟
refresh_token:一般15天

cookie,session,token的相同点和区别:

相同点:
都是用于做鉴权的,都是服务器产生的。

区别:
cookie存储在客户端,session存储在服务器,session的安全性比cookie高。所以一般情况下把重要的信息放到session,把不重要的放在cookie。

session存在服务器内存,token存在服务器的文件或者数据库中,token的好处是比session更节省服务器资源,token只需要在服务器解密即可。

在技术不断进步的过程中,以上逐渐无法满足用户的需求,出现了新的问题:第三方支付、银行、金融项目,对于安全性的要求更高,于是就出现了接口签名sign。

下面是我整理的2023年最全的软件测试工程师学习知识架构体系图

一、Python编程入门到精通

请添加图片描述

二、接口自动化项目实战

请添加图片描述

三、Web自动化项目实战

请添加图片描述

四、App自动化项目实战

请添加图片描述

五、一线大厂简历

请添加图片描述

六、测试开发DevOps体系

请添加图片描述

七、常用自动化测试工具

请添加图片描述

八、JMeter性能测试

请添加图片描述

九、总结(尾部小惊喜)

风雨兼程,唯有坚持不懈,方能登上成功之巅。披荆斩棘,勇往直前,梦想的光芒终将照亮前行的道路。相信自己,你必将创造奇迹。

只要心怀勇气,坚持不懈,你一定能够克服困难,实现自己的梦想。每一步努力都是通向成功的阶梯,坚信自己,勇往直前。

一路风雨,一路阳光,坚持不懈,勇往直前,你终将收获辉煌。每一份努力,都是未来成功的种子,在坚持中开花结果,相信自己,你能创造奇迹。

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

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

相关文章

pixhawk接深度计

环境 pixhawk 2.4.8 深度计MS5837 ardusub 4.1.1 mission planner 1.3.80 QGroundCpntrol 4.2.8 物理连接 pixhawk的IIC接口接个IIC扩展板,可扩展出4个接口,然后深度计的接头直接插入任意一个IIC扩展口即可 过程 在mission planner上往pixahwk中安装…

“舞”动金鸡 | 安全狗连续5年零失误守护金鸡奖颁奖典礼安全

11月4日,第36届中国电影金鸡奖颁奖典礼暨2023年中国金鸡百花电影节闭幕式在厦门圆满落幕。 作为国内云原生安全领导厂商,安全狗再一次收到客户委托,为其金鸡期间的相关宣传窗口、网页和系统的网络安全全程护航。 厦门服云信息科技有限公司&am…

threejs (二) 相机

正交相机 const camera new THREE.OrthographicCamera(-aspect,aspect,aspect,-aspect,0.1, //进平面1000 //远平面); // 透视相机创建相机辅助线 const cameraHelper new THREE.CameraHelper(this.camera);创建一个透视相机观察正交相机 // 创建透视相机const watchCamera …

什么是客户体验 (CX)?如何改善客户体验?

客户体验(CX)就是客户在与某个公司、产品或服务互动时所感受到的整体体验。这包括客户的感觉、情感和意见,无论是购物、与客服互动、使用产品还是与品牌互动。CX就像客户在与一家公司或产品互动时的"情感指南",可以是积…

使用c++解压rar文件,基于UnRAR64,非命令行

最近项目需要解压缩rar文件,我们都知道rar是闭源收费软件,如果直接采用命令行可能会有限制,或者盗版问题,使用正版的winrar命令行解压rar文件是否有限制,这个我没来得及测试,但是从交互体验上来说&#xff…

深兰科技科研团队6篇论文被国际医学信息科学顶尖学术会议收录

近日,深兰科技科学院智能科学首席科学家黄智生教授及其所带领的科研团队与同济大学团队,北京工业大学团队等合作,在国际医学信息科学顶尖学术会议“HIS 2023”上接连发表了六篇论文(其中有两篇论文的第一作者是黄教授本人)。 10月下旬&#x…

太坑了,降低 代码可读性的 12 个技巧

工作六七年以来,接手过无数个烂摊子,屎山雕花、开关编程已经成为常态。 下面细数一下 降低代码可读性,增加维护难度的 12 个编码“技巧”。 假设一个叫”二狗“ 的程序员,喜欢做以下事情。 1. 二狗积极拆分微服务,一个…

软文推广如何提高点击率,媒介盒子告诉你

随着软文推广的广泛应用,对于广告主来说,提高点击率已经成为一项关键任务,点击率直接影响广告主的投资回报率,今天媒介盒子将从两大方面给出软文推广如何提高点击率的建议: 一、 优化广告文案 广告文案是影响点击率的…

[动态规划] (十二) 简单多状态 LeetCode 213.打家劫舍II

[动态规划] (十二) 简单多状态: LeetCode 213.打家劫舍II 文章目录 [动态规划] (十二) 简单多状态: LeetCode 213.打家劫舍II题目解析解题思路状态表示状态转移方程初始化和填表顺序返回值提醒 代码实现总结 213. 打家劫舍 II 题目解析 本题是对打家劫舍和按摩师的升级题型&am…

ae如何保存为gif格式?三个方法轻松搞定!

GIF是动态图像,在聊天的时候发的动态表情包就是GIF,非常受大家欢迎。那么如何把视频变成GIF格式呢,下面是一些具体的操作步骤。 一、AE 1、依次点击AE菜单栏文件 — 导出 — 添加到渲染队列 — 导出MOV视频格式 2、依次点击导入MOV — 储存W…

jenkins原理篇——成员权限管理

大家好,我是蓝胖子,前面几节我讲述了jenkins的语法以及我是如何使用jenkins对测试和正式环境进行发布的。但正式环境使用jenkins还有一点很重要,那就是权限管理。正式环境的权限往往不能对所有人开放,以及要做到每次发布都是谁在操…

PMI-ACP(103:57- 103)

57/103 高绩效敏捷团队的特征 参与式指导有效的决策开放和清晰的沟通价值多样性相互信任管理冲突清楚目标明确定义角色 和 职责协调关系积极的氛围 58/103 创建授权团队 敏捷强调 具备授权和积极性 的自我管理团队,他们需要对项目成果充分负责,授权是…

0基础两小时建网站

​作者主页 📚lovewold少个r博客主页 ⚠️本文重点:0基础2小时搭建个人网站 👉【C-C入门系列专栏】:博客文章专栏传送门 😄每日一言:宁静是一片强大而治愈的神奇海洋! 目录 前言 第一步 环境…

Redis Desktop Manager安装和使用

Redis Desktop Manager(RDM)是一款用于管理和操作Redis数据库的图形化界面工具。提供了简单易用的界面,使用户能够方便地执行各种Redis数据库操作,并且支持多个Redis服务器的连接RDM功能介绍:1.连接管理:RD…

DC-DC降压芯片120V转12V5A大功率SL3038电源芯片

本文将介绍一款DC-DC降压芯片,将120V的电压转换为12V5A的大功率输出,使用SL3038电源芯片实现。在开始介绍之前,我们先来了解一下DC-DC降压芯片和SL3038电源芯片的基本原理和特点。 DC-DC降压芯片是一种常见的电源管理芯片,它可以将…

爱上联名的白酒,还是拿不下年轻人?

作者|Kyra 编辑|Ray “才喝完“酱香拿铁”,又吃了“浓香冰淇淋,古茗和天官赐福的联名刚也已经下单了,完美。”热衷于收集各种联名的Bella在办公室欢呼道。 现在品牌之间的联名意欲拿捏年轻人,特别是白酒…

maven中的install 和 clean命令,以及compile、、package、test等操作介绍

maven中的install命令 主要就是谁要被其他模块依赖就install谁 Maven工具可以进行clean、compile、install、package、test等操作,但是这些操作有什么用呢,以下面的p2p-exterface为例说明一下,pwp-exterface工程目录如下: com…