二、接口自动化测试(1)

一、什么是接口测试

先回顾一下原理:参考网站:https://blog.csdn.net/HUA1211/article/details/131959650

接口测试的原理就是模拟客户端向服务器发送请求,服务器接收请求报文后对相应的报文做处理并向客户端返回应答,客户端接收应答的过程。接口测试采用的方法其实与黑盒测试一致的,甚至可以把接口测试理解为没有界面的功能测试。只不过接口测试的关注点主要在请求和响应上。另外,还包括接口的安全,接口的性能等。常用的用例设计有等价类,边界值法等。一般测试用例的设计要从单接口参数的校验到整个业务功能点的验证,还可以验证一些安全性和异常情况。

二、为啥做接口自动化

复制代码
**实现方式**
- 工具(jmeter, postman, ...)
- 编码(python, java, ...)

**比较**
- 工具:
  - 优点: 1.不需要编程基础 2.功能都是封装好的, 直接调用
  - 缺点: 不灵活
- 编码:
  - 优点: 灵活
  - 缺点: 1.需要编程基础 2.功能需要自实现, 效率偏低
复制代码
JMeter接口测试的不足:
  1. 脚本的灵活性。虽然JMeter提供了一定的BeanShell编程能力和自定义协议的扩展能力,可以让脚本开发人员有一定的灵活性,受制于JMeter本身的限制,与开发人员直接使用语言进行接口测试相比,灵活性还是相对不足。

  2. 报告的能力。JMeter提供了HTML报告,但是JMeter本身的测试报告主要用于性能测试,反映的更多是性能测试层面的结果。而且配置过程比较复杂,在团队成员分享报告等方面比较麻烦。

  3. 持续集成。利用第三方的Jenkins插件、Ant和Maven等,能与JMeter进行一些基本的持续测试集成,但是对于完全自动化所需的测试环境的管理等功能支持不足,配置过程略嫌麻烦。

  4. 测试脚本和测试结果的管理:脚本和结果基本都是本地管理,无法做到在线管理。

  5. 不支持前端测试, 使用Jmeter无法验证JS程序,也无法验证页面,所以需要手工去验证。

  6. Jmeter的断言功能不是很强大

  7. 就算是jmeter脚本顺利执行,依旧无法确定程序是否正确执行,有时候需要进入程序查看,或者查看Jmeter的响应数据。

  8. Jmeter脚本的维护需要保存为本地文件,而每个脚本文件只能保存一个测试用例,不利于脚本的维护。

  9. 调试不方便,不容易从结果提示错误中快速定位到错误点具体位置,例如一次测试几百个接口,如果有几个接口出现了问题,还得一个一个去翻查找

  10. 在接口自动化测试中,较难给测试接口快速提供可测试环境,或者说较难提供自己想要的测试环境

  11. 使用过程中单位不规范(有时候单位秒、分)

Python接口自动化特点:

  1. Python 做接口自动化有自带的框架,如 Pytest、Unittest 等;
  2. 学会了 Python 接口自动化,再学 UI 自动化就很容易上手,原理相同;
  3. Python 接口自动化难点在于测试框架,需要自己封装,否则没有创新点;
  4. Python 的框架可以自由设计,函数可以自己封装,相对灵活,可扩展性较强;
  5. Python 写接口自动化脚本需要时间,不适合紧急迭代的项目。

三、接口自动化框架的实现

一、流程

  1. 需求分析

  2. 挑选需要做自动化测试的功能接口(相当于测试计划)

  3. 设计测试用例

  4. 搭建自动化测试环境[可选]

  5. 设计自动化测试项目的架构[可选]

  6. 编写代码

  7. 执行测试用例

  8. 生成测试报告并分析结果

二、pymysql+requests+pytest

https://blog.csdn.net/weixin_74783615/article/details/135184310

复制代码
1、pymysql:
功能:pymysql 是 Python 语言操作 MySQL 数据库的一个库,提供了对 MySQL 数据库的连接、查询、数据操作等功能。
使用场景:当你需要在 Python 中连接 MySQL 数据库,并执行数据库操作时,可以使用 pymysql。

2、requests:
功能:requests 是一个简洁且功能强大的 HTTP 请求库,用于发送 HTTP 请求和处理响应。
使用场景:当你需要在 Python 中进行 HTTP 请求,例如与 Web 服务进行通信、调用 API 接口等时,可以使用 requests。

3、pytest:
功能:pytest 是 Python 中的一个单元测试框架,用于编写和执行测试用例,并生成测试报告。
使用场景:当你需要对 Python 代码进行单元测试,验证代码的正确性和健壮性时,可以使用 pytest。
pytest 是 python 的一种第三方的单元测试框架, 同自带的 unittest 测试框架类似, 相比于 unittest 框架使用起来更简洁, 更高效
复制代码

(一)、pymysql

  1. 创建了一个连接 connection

  2. 获取游标 cursor

  3. 执行sql语句

  4. 关闭游标 cursor

  5. 关闭连接 connection

查:

 

复制代码
"""
    使用 pymysql 连接数据库, 无论增删改查哪种操作, 操作流程基本一致
    1.导包
    2.创建连接(桥)
    3.创建游标(驴)
    4.核心操作: 发送 sql 语句
    5.释放资源(先驴后桥)
"""
# 1.导包
import pymysql
# 2.创建连接(桥)
myConn = pymysql.Connect(host="127.0.0.1", port=3306, database="test", user="root", password="123456", charset="utf8")
# 3.创建游标(驴)
lv = myConn.cursor()
# 4.核心操作: 发送sql语句(查询)
# 4.1 编写sql语句
sql = "SELECT * FROM t_area"
# 4.2 执行sql
lv.execute(sql)
# 4.3 获取响应结果
# 4.3.1 获取相应结果行数
print("响应结果行数:", lv.rowcount)
# 4.3.2 逐行获取数据
# row1 = lv.fetchone()
# row2 = lv.fetchone()
# row3 = lv.fetchone()
# row4 = lv.fetchone()
# row5 = lv.fetchone()
# print("第1行数据:", row1)
# print("第2行数据:", row2)
# print("第3行数据:", row3)
# print("第4行数据:", row4)
# print("第5行数据:", row5)
# 4.3.3 获取所有数据
rows = lv.fetchall()
print("所有数据:", rows)
for row in rows:
print("每一条:", row)
print("id", row[0])
print("区域名称", row[1])
print("优先级", row[2])
print("创建时间", row[3])
print("更新时间", row[4])

# 5.释放资源(先驴后桥)
lv.close()
myConn.close()
复制代码

增:

复制代码
# 1.导包
import pymysql
# 2.创建连接(桥)
myConn = pymysql.Connect(host="127.0.0.1", port=3306, database="test", user="root", password="123456", charset="utf8")
# 3.创建游标(驴)
lv = myConn.cursor()

# 4.核心操作: 发送sql语句(增------------------------------)
# 4.1 编写sql语句
sql = "insert into t_area(area_name, priority) values('咚咚咚', '123')"
# 4.2 执行sql
lv.execute(sql)
myConn.commit()
# 4.3 获取响应结果
print("响应结果行数:", lv.rowcount)

# 5.释放资源(先驴后桥)
lv.close()
myConn.close()
复制代码

改:

复制代码
# 1.导包
import pymysql
# 2.创建连接(桥)
myConn = pymysql.Connect(host="127.0.0.1", port=3306, database="test", user="root", password="123456", charset="utf8")
# 3.创建游标(驴)
lv = myConn.cursor()

# 4.核心操作: 发送sql语句(改------------------------------)
# 4.1 编写sql语句
sql = "update t_area set area_name='嘻嘻嘻' where area_id=28"
# 4.2 执行sql
lv.execute(sql)
myConn.commit()
# 4.3 获取响应结果
print("响应结果行数:", lv.rowcount)

# 5.释放资源(先驴后桥)
lv.close()
myConn.close()
复制代码

删:

复制代码
# 1.导包
import pymysql
# 2.创建连接(桥)
myConn = pymysql.Connect(host="127.0.0.1", port=3306, database="test", user="root", password="123456", charset="utf8")
# 3.创建游标(驴)
lv = myConn.cursor()

# 4.核心操作: 发送sql语句(删------------------------------)
# 4.1 编写sql语句
sql = "delete from t_area where area_id=28"
# 4.2 执行sql
lv.execute(sql)
myConn.commit()
# 4.3 获取响应结果
print("响应结果行数:", lv.rowcount)

# 5.释放资源(先驴后桥)
lv.close()
myConn.close()
复制代码

事务操作:

复制代码
# 1.导包
import pymysql
# 2.创建连接(桥)
myConn = pymysql.Connect(host="127.0.0.1", port=3306, database="test", user="root", password="123456", charset="utf8")
# 3.创建游标(驴)
lv = myConn.cursor()

# 4.核心操作: 发送sql语句(事务------------------------------)
try:
    sql1 = "insert into t_area(area_name, priority) values('咚咚咚', '111')"
    sql2 = "insert into t_area(area_name, priority) values('嘻嘻嘻', '222')"
    # 执行sql1(插入数据A)
    lv.execute(sql1)
    # 执行sql2(插入数据B)
    lv.execute(sql2)
    # 提交(写入数据库)
    myConn.commit()
except Exception as e:
    print("error:", e)
    # 回滚(拒绝写入数据库)
    myConn.rollback()

# 5.释放资源(先驴后桥)
lv.close()
myConn.close()
复制代码

封装:

复制代码
"""
实现封装:
    将 pymysql 的常见用法实现封装进一个专门工具类
    封装的功能: 1.获取连接 2.获取游标 3.释放资源
"""
import pymysql

class DBUtils:
    # 工具函数 1.获取连接
    @classmethod
    def get_conn(cls):
        return pymysql.Connect(host="127.0.0.1", port=3306, database="test", user="root", password="123456", charset="utf8")

    # 工具函数 2.获取游标
    @classmethod
    def get_cursor(cls, conn):
        return conn.cursor()

    # 工具函数 3.释放资源
    @classmethod
    def close_res(cls, cursor, conn):
        if cursor:
            cursor.close()
        if conn:
            conn.close()
复制代码

调用:

复制代码
"""
实现调用:
    以查询数据库为例, 调用工具类中封装的功能
"""

# 导包
from pymysql_19 import DBUtils

# 调用获取连接的工具函数
conn = DBUtils.get_conn()

# 调用获取游标的工具函数
lv = DBUtils.get_cursor(conn)

# 核心: 查询为例
sql = "select * from t_area"
lv.execute(sql)
print(lv.fetchall())

# 调用释放资源的工具函数
DBUtils.close_res(lv, conn)
复制代码

(二)、requests

复制代码
"""
    需求: 编写 python 代码, 访问案例的查询接口 (/sa/listarea)

    流程: 三要素
        1.根据 url 定位接口资源
        2.提交测试数据
        3.发送请求, 接收并处理响应结果
"""
# -----------------------get请求----------------------
# 导包
import requests
# 一行代码搞定
response = requests.get("http://localhost:8081/sa/listarea")
# 打印结果
print("状态码:", response.status_code)
print("响应体:", response.text)
# -----------------------post请求---------------------
# 导包
import requests
# 三要素
data = {"areaName": "中发白", "priority": "123"}
response = requests.post("http://localhost:8081/sa/addarea", data=data)
print("状态码:", response.status_code)
print("响应体:", response.text)
# -----------------------put请求---------------------
# 导包
import requests
# 三要素
myJson = {
    "areaId": "40",
    "areaName": "东南西北中发白",
    "priority": "888"
}
response = requests.put("http://localhost:8081/sa/modifyarea", json=myJson)
print("状态码:", response.status_code)
print("响应体:", response.text)
# -----------------------delete请求-------------------
# 导包
import requests
# 三要素
response = requests.delete("http://localhost:8081/sa/removearea", params={"areaId": "40"})
print("状态码:", response.status_code)
print("响应体:", response.text)
复制代码
复制代码
"""
    需求: 响应由行头体三部分组成, 需要用requests 相关实现解析响应中的行头体
"""

import requests

response = requests.get("http://www.baidu.com")

# 行解析
print("URL:", response.url)
print("状态码:", response.status_code)
print("-"*80)

# 头获取
print("获取所有响应头:", response.headers)
print("获取所有cookie:", response.cookies)
print("获取所有编码集:", response.encoding)
print("-"*80)

# 体获取
print("以文本的方式获取响应体:", response.text)    # 服务器传过来的是文本信息, 如 html 文档
# print("以二进制的方式获取响应体:", response.content)    # 服务器传过来的是图片/视频/音频等非文本数据
# print("以JSON的方式获取响应体:", response.json())    # 服务器传过来的是json格式数据, 调用该方法以json语法解析数据
复制代码
复制代码
'''
requests登录实现cookie
'''
import requests

# 1.获取验证码, 并获得 cookie  中的 PHPSESSID
response1 = requests.get("http://localhost/index.php?m=Home&c=User&a=verify")
print(response1.status_code)
print(response1.cookies)
id = response1.cookies.get("PHPSESSID")
print(id)
print("-"*80)

# 2.登录, 并提交cookie
data = {"username": "17150312012", "password": "123456", "verify_code": "8888"}
cookie = {"PHPSESSID": id}
response2 = requests.post("http://localhost/index.php?m=Home&c=User&a=do_login", data=data, cookies=cookie)
print(response2.status_code)
print(response2.text)
print("-"*80)

# 3.获取订单, 需要再次提交 cookie
response3 = requests.get("http://localhost/Home/Order/order_list.html", cookies=cookie)
print(response3.status_code)
print(response3.text)
复制代码
复制代码
'''
    requests登录实现session
'''
import requests

# 创建 session 对象
session = requests.Session()

# 1.获取验证码(隐式获取cookie)
response1 = session.get("http://localhost/index.php?m=Home&c=User&a=verify")
print(response1.status_code)
print("-"*80)

# 2.登录
data = {"username": "17150312012", "password": "123456", "verify_code": "8888"}
response2 = session.post("http://localhost/index.php?m=Home&c=User&a=do_login", data=data)
print(response2.status_code)
print(response2.text)
print("-"*80)

# 3.获取订单
response3 = session.get("http://localhost/Home/Order/order_list.html")
print(response3.status_code)
print(response3.text)
复制代码
posted @   Mei_first  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
点击右上角即可分享
微信分享提示