做特卖网站有什么网站,asp网站转wap网站,手机摄影网站首页,深圳市建设工程交易服务网宝安分中心目录 1. 数据库以及数据库操作1.1 概念1.2 分类1.3 作用 2 python操作数据库的相关实现2.1 背景2.2 相关实现 3. pymysql基础3.1 整个流程3.2 案例3.3 Pymysql工具类封装 4 事务4.1 案例4.2 事务概念4.3 事务特征 5. requests库5.1 概念5.2 角色定位5.3 安装5.4 校验5.5 reques… 目录 1. 数据库以及数据库操作1.1 概念1.2 分类1.3 作用 2 python操作数据库的相关实现2.1 背景2.2 相关实现 3. pymysql基础3.1 整个流程3.2 案例3.3 Pymysql工具类封装 4 事务4.1 案例4.2 事务概念4.3 事务特征 5. requests库5.1 概念5.2 角色定位5.3 安装5.4 校验5.5 requests之GET请求5.6 requests之POST请求5.7 requests之PUT请求5.8 requests之DELETE请求5.9 补充5.10 响应5.11 登录案例5.11.1实现思路5.11.2 实现 6. PyTest基础6.1 pytest的配置文件6.2 setup和teardown6.3 实现6.4 数据参数化6.5 测试报告插件6.6 集成思路 7. 接口自动化实现7.1 自动化流程7.2 设计接口测试用例7.3 框架架构的图解7.4 项目架构目录7.5 项目框架的实现 8 总结 1. 数据库以及数据库操作
1.1 概念
是存储数据的仓库程序中数据的载体
1.2 分类
关系型数据库安全 例如MySQL、Oracle、SQLitedatabase tables 行列 非关系型数据库高效 例如Redis、MongODB数据存储的多样性键值对、列表、字符串…
1.3 作用
数据库和变量都可以存储数据二者的区别是
持久性不同数据库可以持久性能够存储数据数据被写入磁盘中变量不能运行在内存中
2 python操作数据库的相关实现
2.1 背景
python等不同语言本身不具备直连数据库的功能必须导入第三方包
2.2 相关实现
数据库驱动
MySQLdbMySQLClientt重点Pymysql
3. pymysql基础
3.1 整个流程
创建连接connection获取游标cursor执行SQL语句 执行查询语句执行增删改语句 判断是否出现异常 否没有出现异常–提交事务是出现异常–回滚事务 关闭游标cursor关闭连接connection
# 连接pymysql# 1. 导包
import pymysql# 2. 创建游标
con pymysql.connect(host127.0.0.1, port3306, databasetest, userroot, password123456, charsetutf8)
# 3. 创建链接
cur con.cursor()
# 4. 执行sql
# 编写sql
# sql select * from t_area
sql insert into t_area(area_name, priority) values(西安, 1)
# 执行SQL
cur.execute(sql)
# 逐行获取数据
# result cur.fetchone()
# print(result)
# 获取素有数据
result cur.fetchall()
for row in result:print(row[3])
# 影响的行数
print(影响行数, cur.rowcount)
# 提交事务
con.commit()
# 5. 释放资源
cur.close()
con.close()
注意
增删改执行完毕后需要执行提交操作否则执行失败提交方式 手动提交连接对象.commit()自动提交autocommit True (默认提交)
3.2 案例
# 1. 创建连接connection
# 2. 获取游标cursor
# 3. 执行SQL语句
# 1. 执行查询语句
# 2. 执行增删改语句
# 1. 判断是否出现异常
# - 否没有出现异常--提交事务
# - 是出现异常--回滚事务
# 4. 关闭游标cursor
# 5. 关闭连接connection
import pymysqlcon pymysql.connect(host127.0.0.1, port3306, databasetest, userroot, passwd123456, charsetutf8)
cur con.cursor()
try:sql select * from t_areacur.execute(sql)result cur.fetchall()for row in result:print(row)# 在添加和修改的时候需要提交事务# con.commit()except Exception as e:# 回滚事务cur.rollback()cur.close()con.close()
3.3 Pymysql工具类封装
import pymysqlclass DBUtil:# 获取连接classmethoddef get_connect(cls):# 创建连接return pymysql.connect(host127.0.0.1, port3306, userroot, passwd123456, charsetutf8)# 获取游标classmethoddef get_cursor(cls, con):# 创建连接return con.cursor()# 释放资源classmethoddef close(cls, cur, con):if cur:cur.close()if con:con.close()案例
# 获取连接
from demo.utils.DBUtil import DBUtilcon DBUtil.get_connect()
# 创建游标
cur DBUtil.get_cursor(con)
# 编写和执行sql
sql select * from t_aera
# 执行sql
result cur.execute(sql)
# 查看结果
for row in result:print(row[3])
# 关闭资源
DBUtil.close(con, cur)4 事务
4.1 案例
银行转账
假如用户A给用户B转账300用户A-300用户B300转账成功提交事务commit假如用户A转账300而用户B没有增加300转账失败这个事务不予提交回滚事务rollback
4.2 事务概念
事务是一套完整的业务逻辑在业务逻辑中困难包含多条sql语句在这些sql执行的时候要么都成功要么都失败
4.3 事务特征
原子性事务中的操作被看作一个单元要么都成功要么都失败一致性逻辑单中的每个操作不应该一部分操作一部分失败隔离性事务的中间状态对其他事务时不可见的每个事务之间时互不影响的持久性事务提交成功后它会永久性保存在数据库中
5. requests库
5.1 概念
requests库是使用python编写的可以调用该库的函数直接向服务器发送请求并接收响应
5.2 角色定位
类似于Jmeter中http请求
5.3 安装
pip install requests5.4 校验
在命令行输入pip list命令查找requests的名称和对应的版本号
5.5 requests之GET请求
import requests as requests# 请求
response requests.get(https://api-v2.xdclass.net/api/rank/v1/hot_product)print(状态码, response.status_code)
print(响应体, response.text)5.6 requests之POST请求
import requests as requestsdata {page: 1, size: 4}
response requests.post(https://api-v2.xdclass.net/api/play_record/v1/page, datadata)print(状态码, response.status_code)
print(响应体, response.text)5.7 requests之PUT请求
import requests as requests# 请求
myJson {areaId: 55,areaName: 上海,priority: 111
}response requests.put(http://localhost:8080/sa/modifyarea, jsonmyJson)print(状态码, response.status_code)
print(响应体, response.text)5.8 requests之DELETE请求
import requests as requests# 请求
response requests.delete(http://localhost:8080/sa/removearea, params{areaId: 40})print(状态码, response.status_code)
print(响应体, response.text)5.9 补充
四种操作代码结构基本一致 导包操作获取响应 区别 函数名不同对应的请求方式也不同提交数据的参数名不同 get和delete使用params提交数据post和put使用 data提交键值对数据json提交JSON格式数据 为什么get/delete和post/put提交数据使用的参数不一致 get/delete请求格式在请求行使用paramspost/put请求格式在请求体使用data/json
5.10 响应
import requestsresponse requests.get(https://www.baidu.com)
# 响应行
print(url, response.url)
print(状态码, response.status_code)
print(-*100)# 响应头
print(获取所有响应体头, response.headers)
print(获取所有cookie, response.cookies)
print(获取所有编码集, response.encoding)
print(-*100)# 响应体
print(以文本的方式获取响应体, response.text)
# print(以二进制的方式获取响应体, response.content)
# print(以JSON的方式获取响应体, response.json())
print(-*100)5.11 登录案例
5.11.1实现思路 需求案例先登录登陆成成功后获取“订单页面” login接口post–键值对提交数据username和passwordorder_list接口get cookie 例如使用jmeter请求百度搜索接口时会经常跳转到安全认证页面原因是没有cookie服务器识别不了身份不认识解决方式从浏览器中拿到一个BAIDUID并使用cookie管理器组件进行管理存在的问题获取cookie后,后面每一个接口实现都需要提交cookie,过程高度重复,requests库内置了相关实现的封装,封装了对cookie 的处理 # 核心知识点:关联
# 获取登录接口响应的 cookie提取出来作为查询订单接口要提交的参数
import requests
# 访问接口1:访问登录接口
response1 requests.post(login接囗, data{username: “xxx, password:yyy})
# 获取 cookie再获取 cookie 中的 xXID 形式类似于{“xxID:“zzz}
id response1.cookies.get(xxID)
# 访问接口2:订单查询接口
requests.get(查询订单接口cookies{“xxID:id})Session: 注意点: requests中的session是对 cookie的封装,并不是服务器端的 session,两者无关,只是重名 import requests
# 获取 session 对象
mySession requests.session()
# 请求1:使用 session 登录
#requests.post(...)
response1 mysession.post(1ogin接囗,data{username:xxx,password: yyy})
# 请求2:使用 session 获取订单
response2 mysession.get(查询订单接口)5.11.2 实现 需求使用 requests库调用 tpshop登录功能的相关接口,完成登录操作登录成功后获取“我的订单页面(访问订单列表接口) 相关接口1.获取验证码http://localhost/index.php?mHomecUseraverify GET(此接口返回验证码 和 cookie)
2.登录http://localhost/index.php?mHomecUserado_login POST参数: {username:xxxxx,password:yyyy,verify_code:zzzz},非 JSON 提交
3.我的订单http://localhost/Home/Order/order_list.html GETCookie实现
import requests
# 请求
cookieId_response requests.get(http://192.168.157.130/index.php?mHomecUseraverify)
print(状态码, cookieId_response.status_code)
print(Cookie对象, cookieId_response.cookies)
# 获取cookies,PHPSESSID
id cookieId_response.cookies.get(PHPSESSID)
print(Cookie, id)
print(-*100)
# 请求登录接口
data {username: 13012345678,password: 123456,verify_code: 8888
}
# 获取cookie的ID的值
cookie {PHPSESSID: id}# 登录接口
res_login requests.post(http://192.168.157.130/index.php?mHomecUserado_login, datadata, cookiescookie)
print(登录状态码, res_login.status_code)
print(登录响应体, res_login.text)
print(-*100)
# 订单接口
order_login requests.get(http://192.168.157.130/Home/Order/order_list.html, cookiescookie)
print(订单状态码, order_login.status_code)
print(订单响应体, order_login.text)Session实现
import requests
# 创建session对象
sesion requests.session()
print(-*100)
# 请求登录接口
data {username: 13012345678,password: 123456,verify_code: 8888
}# 登录接口
res_login sesion.post(http://192.168.157.130/index.php?mHomecUserado_login, datadata)
print(登录状态码, res_login.status_code)
print(登录响应体, res_login.text)
print(-*100)
# 订单接口
order_login sesion.get(http://192.168.157.130/Home/Order/order_list.html)
print(订单状态码, order_login.status_code)
print(订单响应体, order_login.text)6. PyTest基础
pytest是python第三方的单元测试框架
6.1 pytest的配置文件
概述
不用配置文件的方式 pytest会找到项目下的test_xxx开头的py文件以及该文件群下的Test开头的类以及类下面test开头的函数符合要求的测试函数都会被执行 使用配置文件可以通过配置来选择执行那些目录下的模块【更灵活】 项目下新建一个script模块将测试脚本放在sccript目录中pytest的配置文件放在自动化项目目录下配置文件名称为pytest.inipytest.ini第一行的内容为【pytest】后面逐行写具体的配置参数美丽运行时会使用该配置文件中的配置
6.2 setup和teardown
概念
运行于测试方法的始末, 运行一次测试函数会执行一次 setup 和 teardown 有多少个测试函数就会运行多少次的 setup 和 teardown方法 代码
test_xxx.py
class TestLogin:# 函数级初始化方法def setup(self):print(---setup---)# 函数级结束def teardown(self):print(---teardown---)def test_a(self):print(test_a)assert 1 # 断言成功def test_b(self):print(test_b)assert 0 # 断言失败
结果
test_setup和teardown[39].py ---setup--- # 第1次运行 setup
test_a
.---teardown--- # 第1次运行 teardown
---setup--- # 第2次运行 setup
test_b
F---teardown--- # 第2次运行 teardown应用场景
使用配置文件, 可以通过配置项来选择执行哪些目录下的哪些测试模块
使用方式
项目下新建一个 scripts 模块将测试脚本放到 scripts 中pytest 的配置文件放在自动化项目目录下配置文件名称为 pytest.inipytest.ini 第一行的内容为 [pytest] , 后面逐行写具体的配置参数命令行运行时会使用该配置文件中的配置
6.3 实现
示例
[pytest]
addopts -s
testpaths ./scripts
python_files test_*.py
python_classes Test*
python_functions test_*你写的时候可以直接拿来复制粘贴 参数解释: addopts -s 表示命令行参数 testpaths, python_files, python_classes, python_functions 表示执行哪一个包下面的哪些.py结尾的文件, 以及哪些前缀开头的类, 以及哪些前缀开头的测试函数 注意点
怎么确认配置文件被加载? 通过控制台的 inifile 进行查看 windows 可能出现 “gbk” 错误 删除 ini 文件中的所有中文 在工作中这个文件也需要复制粘贴? 是的, 一个项目只会用一个pytest.ini 文件, 只需要理解, 会修改就可以了
6.4 数据参数化
方法
pytest.mark.parametrize(参数名, 参数值)参数对应的值: 类型必须为可迭代的类型, 一般使用 list示例 import pytestclass TestLogin:pytest.mark.parametrize(params, [{username: zhangsan, password: 111}, {username: lisi, password: 222}])def test_a(self, params):print(params)print(params[username])print(params[password])结果
test_login[43].py {username: zhangsan, password: 111}
zhangsan
111
.{username: lisi, password: 222}
lisi
222
.参数化后, 有几组参数, 测试函数就会执行几次 6.5 测试报告插件
安装
# [推荐安装1.21.1的版本]命令行输入
pip install pytest-html1.21.1校验方式 pip list 使用
在配置文件中的命令行参数增加 --html用户路径/xxx.html
6.6 集成思路
伪代码
在 scripts 包下的文件 test_xxx.py
# 测试类
class TestDemo:# 初始化函数def setup(self):self.session requests.Session()# 资源销毁函数def teardown(self):self.session.close()# 测试函数1: 登录def test_login(self):写登录相关代码# 测试函数2: 我的订单def test_order(self):# 1.登录# 2.获取订单...如, # 3.断言存在的问题
参数化: 没有使用参数化动态导入数据封装: 测试函数中和请求业务相关的实现高度重复 7. 接口自动化实现
7.1 自动化流程
需求分析挑选出需要做自动化测试的功能接口编写测试计划设计测试用例搭建测试环境可选执行测试用例执行前需要编写代码生成测试报告并分析结果
7.2 设计接口测试用例
功能描述url和请求方式需要提交的数据状态码和响应体
7.3 框架架构的图解 7.4 项目架构目录
api------封装请求scripts------编写测试脚本data------存放测试数据untils------存放工具类report------测试报告app.py------存放常量pytest.ini------pytest配置文件
7.5 项目框架的实现
创建项目创建pytest.inipytest的配置文件
[pytest]
addopts -s --htmlreport/report.html # 将测试报告放入到report/report.htm的文件
testpath ./scripts # 放入测试脚本
python_files test_*.py # 以test_开头的脚本进行读取
python_classes Test* # 将Test开头的类文件读取
python_function test_* # 将test_开头的方法读取3. 创建app.py放入重复性常量
BASE_URL 127.0.0.1:8080 # 基础地址IP:端口号
AREA_URL /sa # 接口地址script创建脚本目录
创建test_area.py文件
import requestsfrom api.AreaAPI import AreaAPI
from api.AreaDBAPI import AreaDBAPIclass TestArea:def setup(self):self.session requests.Session()self.area_api AreaAPI(self.session)def teardown(self):self.session.close()# 测试查询列表接口def test_list_area(self):response self.area_api.area_list_url()print(状态码 , response.status_code)print(响应体 , response.text)# 测试新增接口def test_add_area(self):data {areaName: 12,priority: 321}response self.area_api.add_area(datadata)print(状态码 , response.status_code)print(响应体 , response.text)# 测试修改接口def test_update_area(self):id AreaDBAPI.select_id_by_name(12)json {areaId: id,areaName: 123}response self.area_api.update_area(jsonjson)print(状态码 , response.status_code)print(响应体 , response.text)# 测试删除接口def test_remove_area(self):id AreaDBAPI.select_id_by_name(123 )# 需要删除的变量params {areaId: id}# 响应结果response self.area_api.removeArea_url(paramsparams)print(状态码 , response.status_code)print(响应体 , response.text)创建api目录放入请求地址
创建AreaAPI.py
from app import BASE_URL, AREA_URLclass AreaAPI:def __init__(self, session):self.session sessionself.area_list_url BASE_URL AREA_URL /listareaself.addArea_url BASE_URL AREA_URL /addAreaself.updateArea_url BASE_URL AREA_URL /updateAreaself.removeArea_url BASE_URL AREA_URL /removeArea# 1查询areadef area_list(self):response self.session.get(self.area_list_url)return response# 2新增areadef add_area(self, data):response self.session.post(self.addArea_url, datadata)return response# 3修改areadef update_area(self, json):response self.session.put(self.updateArea_url, jsonjson)return response# 4删除areadef remove_area(self, params):response self.session.delete(self.removeArea_url, paramsparams)return response创建AreaDBAPI.py文件【用于数据库查询】
from utils.DBUtils import DBUtilsclass AreaDBAPI:classmethoddef select_id_by_name(cls, area_name):# 获取连接con DBUtils.get_connect()# 获取游标cur DBUtils.get_cursor(con)# 编写sqlsql select area_id from area where area_name %s % (area_name)# 执行sqlcur.execute(sql)# 获取所有数据row cur.fechall()# 释放资源DBUtils.close_res(con, cur)# 返回第一行第一列return row[0][0]创建工具类目录utils
创建DBUtils.py
import pymysqlclass DBUtils:classmethoddef get_connect(cls):# 获取连接return pymysql.Connect(host127.0.0.1, userroot, password123456, databasetest, port3306, charsetutf8)classmethoddef get_cursor(cls, con):# 获取游标return con.cursor()classmethoddef close_res(cls, con, cursor):# 释放资源if cursor:cursor.close()if con:con.close()结果截图 8 总结
总结接口自动化各个目录之间的互相调用
以脚本为基础【test_area.py】
测试脚本[scripts]会调用api目录里面的文件api里面的文件会含有一些常量它会调用app.py里面的数据在进行修改或者删除数据的时候一般会调用ID来进行修改或者删除这时候test_area.py文件会先调用api里面的AreaDBAPI.py进行查询数据在AreaDBAPI.py文件会调用DBUtils.py文件先进行连接数据库然后才根据sql查询数据最后才会获得响应