接口自动化框架入门(requests+pytest)

news2024/11/15 19:57:50

一、接口自动化概述

二、数据库概述

2.1 概念

  • 存储数据的仓库,程序中数据的载体

2.2 分类

  • 关系型数据库:安全

    • 如mysql,oracle,SQLLite

    • database tables 行+列

  • 非关系型数据库:高效

    • 如redis,mongoDB

    • 数据存储结构多样

      • 键值对,列表,字符串

2.3 数据库和变量都可以存储数据,二者的区别

  • 数据库可以持久性存储数据(存到硬盘上)

  • 变量不能持久性存储数据,而是运行在内存中

三、Python操作数据库的相关实现

3.1 背景

  • 各种编程语言本身不具备直连数据库的功能,必须导入第三方包

3.2 相关实现

  • 驱动

    • mysqldb

    • mysqlclient

    • pymysql(重点)

四、pymysql实现操作数据库增删改查

 4.1 总体介绍

安装:pip install pymysql

校验:pip list        (显示安装的包及版本号)

流程:

1、创建一个连接connection,填入数据库配置信息

2、创建一个游标cursor

3、执行sql语句

  • cur.execute("sql语句")
  • 执行查询语句-fetchall()
  • 执行增删改语句-判断是否有异常

有异常:回滚事务(conn.rollback)

无异常:提交事务(conn.commit())

4、关闭游标cursor

5、关闭连接connection

基本框架:

# 导包
import pymysql
# 创建连接
conn = pymysql.connect(host='localhost',port=3306,database='api_test',user='root',password='123456',charset='utf8')
# 创建游标
cur = conn.cursor()
# 发送sql语句(核心操作)

# 释放资源
cur.close()
conn.close()

4.2 pymysql操作_查询 

import pymysql
conn = pymysql.connect(host='localhost',port=3306,user='root',passwd='123456',db='api_test',charset='utf8')
cur = conn.cursor()
cur.execute('select * from t_area')
# fetchall()是输出所有查询信息
fetch = cur.fetchall()
# for i in fetch:
#     print(i)
print("所有数据:",fetch)
for row in fetch:
    print("每一条数据:",row)
    print("id",row[0])
    print("区域名称",row[1])
    print("优先级",row[2])
    print("创建时间",row[3])
    print("更新时间",row[4])

# fetchmany(n)是输出n条信息
fetchm = cur.fetchmany(2)
print(fetchm)
# # fetchchone()是逐行输出信息
fetch1 = cur.fetchone()
fetch2 = cur.fetchone()
fetch3 = cur.fetchone()
fetch4 = cur.fetchone()
fetch5 = cur.fetchone()
fetch6 = cur.fetchone()
print("总共多少行信息:",cur.rowcount)
print("第一行信息",fetch1)
print("第二行信息",fetch2)
print("第三行信息",fetch3)
print("第四行信息",fetch4)
print("第五行信息",fetch5)
print("第六行信息",fetch6)

cur.close()
conn.close()

4.3 pymysql操作_增删改 

import pymysql
conn = pymysql.connect(host='localhost',port=3306,user='root',passwd='123456',db='api_test',charset='utf8')
cur = conn.cursor()
# 增——操作
sql_add = "insert into t_area(area_name,priority) values('四川','1234')"
cur.execute(sql_add)
print("受影响的行数:",cur.rowcount)
# 删——操作
sql_delete = "delete from t_area where area_name = '四川'"
cur.execute(sql_delete)
print("受影响的行数:",cur.rowcount)
# 改——操作
sql_update = "update t_area set area_name = '北京' where priority = '11'"
cur.execute(sql_update)
print("受影响的行数:",cur.rowcount)
# 这里一定要确认,保证安全性
conn.commit()
cur.close()
conn.close()

4.4 pymysql操作_事务

  • 4.4.1 事务概念

一套完整的业务逻辑,在这套业务中可能包含多条sql语句,这些sql语句,要么都成功,要么都失败

4.4.2 事务四大特性

  • 原子性

事务中包含的操作被看作一个逻辑单元,这个单元的操作要么都成功,要么都失败

  • 一致性

逻辑单元中的操作不应该一部分失败,一部分失败

  • 隔离性

事务的中间状态对其他事务是不可见的

  • 持久性

指一个事务一旦提交成功,它对数据库中数据的改变应该是永久性的

4.4.3 事务提交机制

  • 提交:commit,将修改写入数据库

  • 回滚:rollback,拒绝将修改写入数据库

  • 方式

    • 手动提交

      • 连接对象.commit()

    • 自动提交

      • 创建连接时设置 autocommit=True

 代码: 

import pymysql
conn = pymysql.connect(host='localhost',port=3306,user='root',passwd='123456',db='api_test',charset='utf8')
cur = conn.cursor()
# 增——操作
try:
    sql_add1 = "insert into t_area(area_name,priority) values('咚咚咚','222')"
    sql_add2 = "insert into t_area(area_name,priority) values('嘻嘻嘻','333')"

    cur.execute(sql_add1)
    cur.execute(sql_add2)
    print("受影响的行数:",cur.rowcount)
    conn.commit()
except Exception as e:
    print("error",e)
    # 回滚,拒绝将数据写入
    conn.rollback()


cur.close()
conn.close()

4.5 pymysql方法封装 

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

class DBUtils:
    @classmethod
    def create_conn(cls):
        return pymysql.connect(host='localhost',port=3306,user='root',passwd='123456',db='api_test',charset='utf8')

    @classmethod
    def create_cur(cls,conn):
        return conn.cursor()

    @classmethod
    def close_res(cls,conn,cur):
        if cur:
            cur.close()
        if conn:
            conn.close()

    @classmethod
    def conn_commit(cls,conn):
        conn.commit()

封装方法执行查询:

from Demo.pymysql_05 import DBUtils

conn = DBUtils.create_conn()
cur  = conn.cursor()
sql = "select * from t_area"
cur.execute(sql)
fetch = cur.fetchall()
for row in fetch:
    print(row)
DBUtils.close_res(conn,cur)

封装方法执行增删改: 

from Demo.pymysql_05 import DBUtils

conn = DBUtils.create_conn()
cur = DBUtils.create_cur(conn)

# 增——操作
sql_add = "insert into t_area(area_name,priority) values('四川','1234')"
cur.execute(sql_add)
print("受影响的行数:",cur.rowcount)
# 删——操作
sql_delete = "delete from t_area where area_name = '四川'"
cur.execute(sql_delete)
print("受影响的行数:",cur.rowcount)
# 改——操作
sql_update = "update t_area set area_name = '北京' where priority = '11'"
cur.execute(sql_update)
print("受影响的行数:",cur.rowcount)

DBUtils.conn_commit(conn)

DBUtils.close_res(conn,cur)

五、requests库-模拟接口请求

 5.1 概述

 

概念

  • requests库是使用python编写的,可以调用该库的函数直接向服务器发送HTTP请求,并接收响应

角色定位

  • 相当于jmeter中的http请求

安装

  • pip install requests

校验

  • pip list找到对应库及版本号

5.2 基本实现请求 

  • GET

  • POST

  • PUT

  • DELETE

四种请求代码实现方式基本一致:

import requests
"""
需求:编写Python代码,访问案例,查询area
流程:三要素
1、首先,根据URL定位接口资源
2、然后,提交测试数据
3、最后,发送请求,接收并处理响应结果
"""


# 1、get请求
response_get = requests.get("http://localhost:1234/area/listarea")

# 打印结果
print("状态码:",response_get.status_code)
print("响应体:",response_get.text)

# 2、post请求
data = {"areaName":"加利福尼亚","priority":"222"}
# 传递参数:data是键值对,json是josn字符串
response_post = requests.post("http://localhost:1234/area/addarea",data=data)

# 打印结果
print("状态码:",response_post.status_code)
print("响应体:",response_post.text)

# 3、put请求
JSON = {
    "areaId":"1",
    "areaName":"华盛顿",
    "priority":"666"
}
# 传递参数:data是键值对,json是josn字符串
response = requests.put("http://localhost:1234/area/modifyarea",json=JSON)

# 打印结果
print("状态码:",response.status_code)
print("响应体:",response.text)

# 4、delete请求
# 传递参数:data是键值对,json是josn字符串
response = requests.delete("http://localhost:1234/area/removearea",params={'areaId':'9'})

# 打印结果
print("状态码:",response.status_code)
print("响应体:",response.text)

5.3 实现请求发出与响应

import requests


# 传递参数:data是键值对,json是josn字符串
response = requests.get('https://www.baidu.com')


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

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

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

 5.4 实现登录接口请求(cookie和session)

需求案例:

  • 先登录,登录成功后获取‘我的订单’页面

    • login接口(post)

      • 键值对提交数据username和password

    • order_list接口(get)

 

cookie版登录:

import requests

# 1、获取验证码,并获得cookie中的PHPSESSID
response1 = requests.get('验证码接口')
print(response1.status_code)
print(response1.cookies)
id= response1.cookies.get("PHPSEESSID")
print(id)
print("-"*80)
# 2、登录,并提交cookie
data = {"username":"","password":"","verify_code":""}
cookie = {"PHPSEESSID":id}
response2  = requests.post("登录接口",data=data,cookies=cookie)
print(response2.status_code)
print(response2.text)
print("-"*80)
# 3、获取订单,需要再次提交cookie
response3 = requests.get("获取订单接口",cookies=cookie)
print(response3.status_code)
print(response3.text)

session版登录:

import requests

# 创建session对象
session = requests.Session()
# 1、获取验证码(隐式获取cookie)
response1 = session.get('验证码接口')
print(response1.status_code)
print("-"*80)
# 2、登录
data = {"username":"","password":"","verify_code":""}
response2  = session.post("登录接口",data=data)
print(response2.status_code)
print(response2.text)
print("-"*80)
# 3、获取订单
response3 = session.get("获取订单接口")
print(response3.status_code)
print(response3.text)

 六、pytest单元测试框架

6.1 概述

概念:pytest是python的一种第三方单元测试框架

特点:同自带的unittst单元测试框架相比,使用起来更加简洁、高效

6.2 运行

命名规则:文件名和方法名一定要以"test_"开头,类名以Test开头,使pytest能够识别到 

代码准备:

test_login.py:

class TestDemo1:
    def test_1(self):
        print("断言成功")
        assert True

    def test_2(self):
        print("断言失败")
        assert False


运行方式:

主函数运行:

# 运行文件:all.py
import pytest
if __name__ == '__main__':
    pytest.main()

命令行运行: 

直接输入pytest即可

6.3 setup和teardown

概念
函数级别:运行于测试方法的始末,运行一次测试函数会执行一次 setup 和 teardown。
示例代码:

class TestLogin:
    # 函数级初始化方法
    def setup_method(self, method):
        print("---setup---")

    # 函数级结束
    def teardown_method(self, method):
        print("---teardown---")

    def test_a(self):
        print("test_a")
        assert 1

    def test_b(self):
        print("test_b")
        assert 0

执行结果:

 

6.4 pytest配置文件 

6.4.1 概述 

应用场景
使用配置文件,可以通过配置项来选择执行哪些目录下的哪些测试模块。
使用方式
1.项目下新建 scripts 模块
2.将测试脚本文件放到 scripts 中3.pytest 的配置文件放在自动化项目目录下
4.名称为 pytest.ini
5.第一行内容为 [pytest],后面写具体的配置参数6.命令行运行时会使用该配置文件中的配置

 6.4.2 配置实现

[pytest]
addopts = -s --html=report/report_demo.html
testpaths = ./scripts
python_files = test_*.py
python_classes = Test*
python_functions = test_*

addopts=-s        表示命令行参数
testpaths,python_files,python_classes, python_functions表示执行 scripts 文件夹下的 test_开头 .py 结尾的文件下的 Test 开头的类下的 test _开头的函数 

 注意点

1.配置文件是否已经正确的加载?

  • 通过控制台的 inifile 进行查看

2.windows中可能出现“gbk"错误?

  • 删除 ini 文件中的所有中文

3.在工作中这个文件也需要复制粘贴?

  • 是的,一个项目只会用一次,只需理解,会修改即可

 6.5 数据参数化

应用场景:
登录功能都是输入用户名,输入密码,点击登录。但登录的用户名和密码如果想测试多个值时,数据参数化可以使代码更整洁,可读性更好。 

方法: 

数据参数化
# 参数:
argnames:参数名
井argva1ues:参数对应值,类型必须为可迭代类型,一般使用1ist@pytest.mark.parametrize("argnames",argvalues)

示例和结果: 参数化运行两条用例

import pytest
class TestLogin:
    @pytest.mark.parametrize("params",[
        {"username": "zhangsan", "password": "1234"}, 
        {"username": "lisi", "password": "6666"}
    ])
    def test_a(self,params):   #以test开头的测试函数
        print(params)
        print(params["username"])
        print(params["password"])

        assert 1        #断言成功

6.6 测试报告插件 

应用场景
自动化测试脚本最终执行是通过还是不通过需要通过测试报告进行体现。
安装
使用命令 pip install pytest-html进行安装pip install pytest-html==1.21.1 在最新的2.0上有错误
使用
在配置文件中的命令行参数中增加 --htmi-用户路径/report.html
示例
pytest.ini中addopts =-s --html=report/report.html
结果
在项目目录下会对一个 report 文件夹,里面有个report.html 即为测试报告 

 

 

 

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

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

相关文章

C++笔记之子类初始化时父类带参构造函数的处理、父子类中模板参数的传递

C++笔记之子类初始化时父类带参构造函数的处理、父子类中模板参数的传递 code review! 文章目录 C++笔记之子类初始化时父类带参构造函数的处理、父子类中模板参数的传递一.子类初始化时父类带参构造函数的处理1.1.若父类只有带参数的构造函数,子类初始化时必须在初始化列表…

C++ 面试必备知识大全:从基础到高级特性全面解析

创作不易,您的打赏、关注、点赞、收藏和转发是我坚持下去的动力! C 面试中常见的问题涵盖了语言基础、面向对象编程、内存管理、STL(标准模板库)、并发编程、设计模式等。以下是一些常见的 C 面试问题及其详细答案总结&#xff1…

protobuf中c、c++、python使用

文章目录 protobuf实例:例题1:[CISCN 2023 初赛]StrangeTalkBot分析:思路:利用: 例题2:[CISCN 2024]protoverflow分析: protobuf Protocol Buffers,是Google公司开发的一种数据描述语…

Tcl lnit error: Can’t find a usable init.tcl in the following directories 问题解决

这个问题出现在我用py2exe打包了一个包含tkinter的图形化界面,在当前电脑上运行无问题,在移动到新电脑上后提示报错、 这里吐槽一下,新电脑上报错信息一闪而过,我用的土法子解决的,就是录视频然后0.25倍速度暂定找到报…

删除Cookie原理

WebServlet("/deletecookie") // 这个注解指定了Servlet的URL映射路径 public class DeleteCookieServlet extends HttpServlet { // 定义一个继承自HttpServlet的类Override // 重写父类的方法protected void doGet(HttpServletRequest request, HttpServletResp…

ORM框架详解:为什么不直接写SQL?

想象一下,你正在开发一个小型的在线书店应用。你需要存储书籍信息、用户数据和订单记录。作为一个初学者,你可能会想:“我已经学会了SQL,为什么还要使用ORM框架呢?直接写SQL语句不是更简单、更直接吗?” 如…

【CS110L】Rust语言 Lecture3-4 笔记

文章目录 第三讲 所有权:移动与借用&例1例2例3 错误处理(开头)为什么空指针如此危险,我们能做什么以应对?— 引出Optionis_none()函数unwrap_or()函数常见用法 第四讲 代码实践:链表Box节点和链表的定义节点和链表的构造函数判…

基于Sobel算法的边缘检测设计与实现

1、边缘检测 针对的时灰度图像,顾名思义,检测图像的边缘,是针对图像像素点的一种计算,目的时标识数字图像中灰度变化明显的点,图像的边缘检测,在保留了图像的重要结构信息的同时,剔除了可以认为…

【WPF】桌面程序开发之xaml页面绑定数据模型详解

使用Visual Studio开发工具,我们可以编写在Windows系统上运行的桌面应用程序。其中,WPF(Windows Presentation Foundation)项目是一种常见的选择。然而,对于初学者来说,WPF项目中xaml页面的布局设计可能是一…

unity3d入门教程七

unity3d入门教程七 17.1物理系统17.2静态刚体17.3刚体的碰撞17.4刚体的反弹18.1运动学刚体18.2碰撞检测18.3碰撞事件回调18.4目标的识别18.5碰撞的规避 17.1物理系统 在物理系统中的物体具有质量和速度的是刚体 不用写代码就会自由落体运动了 17.2静态刚体 给 ‘地面’ 添…

conda安装qgis(亲测没问题)

conda安装qgis(亲测没问题,目前测试win10,linux其实也是可以的) 目录 1.前提 2.准备条件 3.实战 4.扩展 1.前提 意外发现conda可以安装qgis,即使不是完全版,但是矢量空间分析都可以用,那么…

影刀RPA实战:网页爬虫之CSDN博文作品数据

今天我们使用影刀来采集网页数据,影刀RPA是一款功能强大的自动化办公软件,它可以模拟人工的各种操作,帮助企业自动处理大量重复性、有逻辑规则的工作。影刀RPA在网页数据采集方面表现出色,能够实现对任何桌面软件、Web程序的自动化…

危机中的机遇:客户服务在品牌危机管理中的角色与价值

在瞬息万变的商业环境中,品牌危机如同暗流涌动的漩涡,随时可能将企业卷入深渊。然而,正如古语所云:“祸兮福之所倚”,危机之中往往也蕴藏着转机与机遇。在这一过程中,客户服务作为企业与消费者之间的桥梁&a…

物品识别——基于python语言

目录 1.物品识别 2.模型介绍 3.文件框架 4.代码示例 4.1 camera.py 4.2 interaction.py 4.3 object_detection.py 4.4 main.py 4.5 运行结果 5.总结 1.物品识别 该项目使用Python,OpenCV进行图像捕捉,进行物品识别。我们将使用YOLO&#xff08…

Dating App约会软件都有哪些商业化策略

在设计一个成功的Dating App时,吸引并留住用户(特别是女用户)和实现商业化是两个核心任务。比如探探、陌陌等,以下是可行的产品流程思路,以及商业化的功能设计策略,借鉴了成熟的约会平台的经验。 吸引并留住…

2000-2021年3月海关数据库

2000-2021年3月海关数据库 1、时间:2000-2021年3月 2、指标:2000-2015数据变量包括:年份、截止日期、进出口分类代码、进出口分类名称、HS商品编码、HS商品名称、金额_美元、数量、价格、经营单位代码、经营单位名称、经营单位地址、电话、…

AI论文写作测评!类似茅茅虫论文写作助手网站

在当前的学术研究和写作环境中,AI论文写作助手成为了许多学者和学生的重要工具。其中,千笔-AIPassPaper和茅茅虫论文写作助手是两款备受关注的平台。本文将对这两款工具进行详细测评,并推荐适合不同需求的用户使用。 千笔-AIPassPaper AI论文…

linux安全软件Hydra使用教程

Hydra 是一个强大的网络登录工具,常用于渗透测试,支持对多种服务和协议(如 SSH、FTP、HTTP 等)进行暴力crack攻击。它可以通过字典攻击来测试用户名和密码的有效性。以下是关于如何使用 Hydra 的基本步骤和示例: 1. 安…

【mechine learning-九-梯度下降】

梯度下降 更加通用的梯度下降算法算法步骤 上一节讲过,随机的寻找w和b使损失最小不是一种合适的方法,梯度下降算法就是解决解决这个问题的,它不仅可以用于线性回归,还可以用于神经网络等深度学习算法,是目前的通用性算…

【QT】定时器使用

文章目录 关于 Qt 定时器使用的注意细节总结实例-检查工具使用周期时间是否合理UI设计头文件 remind.h源文件 remind.cpp实现效果 关于 Qt 定时器使用的注意细节总结 一、创建与初始化 使用 QTimer 类来创建定时器。可以在构造函数中指定父对象,确保定时器在正确的…