一.GET请求
第一步:导包
import json
import requests
第二步:发送请求
第一种方式:使用url传递参数
变量名=requests.get("请求的url")
第二种方式:通过params传递参数:
(1)字符串
变量1="url"
变量2="参数名=参数值"
变量3="参数名=参数值"
...
变量4=requests.get(变量1=url,params="keyword=变量2&变量3...")
(2)字典:
变量1="http://www.litemall360.com:8080/wx/goods/list"
变量2={
"keyword":"床",
"page":1,
"limit":10,
"categoryId":0
}
变量3=requests.get(变量1=url,params="变量2")
第三步:查看响应
print(变量名.text)//以文本方式查看
print(r.json())//以json格式查看
查看响应数据编码格式:
print(变量名.encoding)
设置响应数据编码格式:
变量名.encodings="utf-8"
二.post请求:
提交json数据:
第一步:导包
import json
import requests
第二步:发送请求
变量1=”url“
url="http://www.litemall360.com:8080/wx/auth/register"
变量2=”参数值”
date={
"code":"666666",
"username":"xiaoxiaoer",
"password":"123456",
"repeatPassword":"123456",
"mobile":"13106120403"
}
变量名3=requests.post(url=变量1,json=(变量2))
第三步:查看响应
print(变量3.json())
说明:
- data: 参数接收form表单数据,后台会⾃动附加form表单请求信息头(data数据格式为字典)
- json:参数接收json数据,后台会⾃动附加json表单请求信息头(headers = {"Content-Type":"application/json"})
提交表单数据:
第一步:导包
import requests
import json
第二步:发送请求
变量1=”url“
变量1 = "http://localhost/index.php?m=Home&c=User&a=do_login"
变量2=”参数值“
变量2 = {
"username": "13488888888",
"password": "123456",
"verify_code": "8888" }
变量名3 = requests.post(url="变量1", data="变量2")
第三步:查看响应
print(变量3.json())
三.其他请求方式(了解):
- put:修改资源
- delete:删除资源
- head:响应数据中只包含请求头,前提是项目中已实现该功能
- options:查看接口支持的请求方法,前提是项目中已实现该功能
响应内容解析:
用途:断言
实现:
- response.status_code :响应状态码
- response.url :url地址信息
- response.encoding :查看响应数据编码格式
- response.headers :查看头部信息
- response.cookies : 查看cookies信息
- response.text :文本形式查看响应数据
- response.content :字节码形式查看响应数据
- response.json() :json形式查看响应数据
# 案例:访问百度首页的接口`http://www.baidu.com`,获取以下响应数据
import requests
import json
r=requests.get("https://www.baidu.com")
r.encoding="utf-8"
# 获取响应状态码
print("响应状态码为:",r.status_code)
# 获取请求URL
print("请求URL为:",r.request.url)
# 获取响应字符编码
print("编码格式为:",r.encoding)
# 获取响应头数据
print("响应头数据为:",r.headers)
print("Content-Type:",r.headers.get("Content-Type"))
# 获取响应的cookie数据
print("响应的cookie数据为:",r.cookies)
print("提取指定的cookies为:",r.cookies.get("BDORZ"))
# 获取文本形式的响应内容
print("文本形式响应内容:",r.text)
# 获取字节形式的响应内容
print("字节形式响应内容:",r.content)
print("字节形式响应内容:",r.content.decode("utf-8"))
四.设置请求头:
变量名={
"Content-Type":"application/json;charset=utf-8"
}
import requests
import json
#URL
url1="http://www.litemall360.com:8080/wx/auth/login"
#请求头
headers1={
"Content-Type":"application/json;charset=utf-8"
}
#请求体
json1={
"username":"user123",
"password":"user123"
}
r=requests.post(url=url1,headers=headers1,json=json1)
print(r.json())
五.设置cookie:(了解)
例子:获取cookies传入其他依赖url里面
import requests
# 获取验证码
r = requests.get("http://localhost/index.php?m=Home&c=User&a=verify")
print(r.cookies)
#获取PHPSESSID的cookies
cookies1 = r.cookies.get("PHPSESSID")
print(cookies1)
# 登录
url = "http://localhost/index.php?m=Home&c=User&a=do_login"
data = {
"username": "13488888888",
"password": "123456",
"verify_code": "8888"
}
#设置请求头cookies的值为验证码的cookies1
cookies = {
"PHPSESSID": cookies1
}
w = requests.post(url=url, data=data, cookies=cookies1)
print(w.json())
# 我的订单:http://localhost/Home/Order/order_list.html
#把cookies1传入我的订单里面
e = requests.get("http://localhost/Home/Order/order_list.html",cookies=cookies1)
print(e.text)
设置session(掌握):
作用:在多个请求之间存储数据并自动添加数据,如cookies
使用:
- 实例化: session = requests.Session()
- 发送请求:
request.get() 变成session.get()
request.post() 变成session.postt()
...
import requests
import json
#实例化session,创建session对象
session = requests.Session()
# 获取验证码
r = session.get("http://localhost/index.php?m=Home&c=User&a=verify")
# 登录
url = "http://localhost/index.php?m=Home&c=User&a=do_login"
data = {
"username": "13488888888",
"password": "123456",
"verify_code": "8888"
}
w = session.post(url=url, data=data)
print(w.json())
# 我的订单:http://localhost/Home/Order/order_list.html
#把cookies1传入我的订单里面
e = session.get("http://localhost/Home/Order/order_list.html")
print(e.text)
六.获取Tokken:
获取方法:
变量1 = requests.post(url=url, json=json)
从变量1json的结果里面获取data下的token里面的token值并存在变量2里面
变量2=(变量1.json()["data"]["token"])
import requests
import json
# 登录
url = "http://www.litemall360.com:8080/wx/auth/login"
json = {
"username": "user123",
"password": "user123"
}
r = requests.post(url=url, json=json)
print(r.json())
#从json的结果里面获取data下的token里面的token值并存在w变量
w=(r.json()["data"]["token"])
print("token为:",w)
#添加购物车
url1="http://www.litemall360.com:8080/wx/cart/add"
#设置请求头X-Litemall-Token=w值
headers={
"X-Litemall-Token":w
}
json1={
"goodsId":1181000,
"number":1,
"productId":2
}
r1=requests.post(url=url1,json=json1,headers=headers)
print(r1.json())
七.集成UnitTest:
UnitTest优势:
- 管理测试用例
- 提供了丰富的断言
- 生成测试报告
作用:用来管理用例,加载用例,执行用例
原理:有几个核心组件
1、测试固件 setUp() 每条用例执行之前,首先会执行这个setUp()方法,在setUp()方法中完成准备初始化工作 比如:连接数据库,后期在将Web UI功能自动化的时候,可以在这里去打开浏览器,配置 tearDown() 每条用例执行完成之后,回收一些资源,比如:关闭数据库,关闭浏览器
2、测试用例 每一条用例需要实现一个用例方法,每个用例方法都必须要以test开头
3、测试套件 执行用例的时候,需要创建测试套件,把用例加入测试套件。
4、加载器 用来加载用例的,把测试用例加入测试套件中
5、执行器 用来执行测试套件中的用例的 如何使用unittest框架来编写用例
unittest.TestCase:TestCase类,所有测试用例类继承的基本类
class 类名(unittest.TestCase):
使用unittest框架编写测试用例思路:
1.导入模块包
import unittest
2.定义测试类,继承父类为unittest.TestCase
#可继承unittest.TestCase的方法,如setUp和tearDown方法,不过此方法可以在子类重写,覆盖父类方法。
#可继承unittest.TestCase的各种断言方法。
class Test(unittest.TestCase):
3.定义setUp()方法用于测试用例执行前的初始化工作(前置处理)
#注意,所有类中方法的入参为self,定义方法的变量也要“self.变量”
#注意,输入的值为字符型的需要转为int型
def setUp(self):
self.number=raw_input('Enter a number:')
self.number=int(self.number)
4.定义测试用例,以“test_”开头命名的方法
#注意,方法的入参为self
#可使用unittest.TestCase类下面的各种断言方法用于对测试结果的判断
#可定义多个测试用例
#最重要的就是该部分
def test_case1(self):
print self.number
self.assertEqual(self.number,10,msg='Your input is not 10')
def test_case2(self):
print self.number
self.assertEqual(self.number,20,msg='Your input is not 20')
@unittest.skip('暂时跳过用例3的测试')
def test_case3(self):
print self.number
self.assertEqual(self.number,30,msg='Your input is not 30')
5.定义tearDown()方法用于测试用例执行之后的善后工作(后置处理)
#注意,方法的入参为self
def tearDown(self):
print 'Test over'
6.如果直接运行该文件(name值为main),则执行以下语句,常用于测试脚本是否能够正常运行
if __name__=='__main__':
(1)执行测试用例方案一如下:
#unittest.main()方法会搜索该模块下所有以test开头的测试用例方法,并自动执行它们。
#执行顺序是命名顺序:先执行test_case1,再执行test_case2
unittest.main()
(2)执行测试用例方案二如下:
#6.2.1先构造测试集
#6.2.1.1实例化测试套件
suite=unittest.TestSuite()
#6.2.1.2将测试用例加载到测试套件中。
#执行顺序是安装加载顺序:先执行test_case2,再执行test_case1
suite.addTest(Test('test_case2'))
suite.addTest(Test('test_case1'))
#6.2.2执行测试用例
#6.2.2.1实例化TextTestRunner类
runner=unittest.TextTestRunner()
#6.2.2.2使用run()方法运行测试套件(即运行测试套件中的所有用例)
runner.run(suite)
'''
'''
#6.3执行测试用例方案三如下:
#6.3.1构造测试集(简化了方案二中先要创建测试套件然后再依次加载测试用例)
#执行顺序同方案一:执行顺序是命名顺序:先执行test_case1,再执行test_case2
test_dir = './'
discover = unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')
#6.3.2执行测试用例
#6.3.2.1实例化TextTestRunner类
runner=unittest.TextTestRunner()
#6.3.2.2使用run()方法运行测试套件(即运行测试套件中的所有用例)
runner.run(discover)
'''
八.生成测试报告:
1.先导包
import time
import unittest
from 登录实现unittest import test
from HtmlTestRunner import HTMLTestRunner
2.封装测试套件
#实例化TestSuite()对象
suite=unittest.TestSuite()
#添加测试用例或者类进来
suite.addTest(unittest.makeSuite(test))
3.指定报告路径
通过时间模块把日期传入文件名上(年月日-时分秒)
report="./report-{}.html".format(time.strftime("%Y%m%d-%H%M%S"))
4.打开文件流
#以二进制写入的方式打开
with open(report,"wb") as f:as f代表创建一个别名
#创建HTMLRUNNER运行器
runner=HTMLTestRunner(f,title="接口测试报告")
#执行测试套件
runner.run(suite)
九.参数化:
基本步骤:
参数化:
1.分析:哪些内容需要参数化
数据数据:用户名,密码,验证码
预期结果:content_type
状态码,业务码,业务消息
2.选择数据承载形式:
json
db
3.修改测试用例的代码
3.1构建参数化数据(build_date)
3.2在测试用例前引用参数化(@paramete)
3.3在具体的测试用例中按照获得的数据进行参数替换
基于json文件实现参数化:
第一步:导包
#导入引用参数化的包
from parameterized import parameterized
第二步: 构造测试数据
#参数化
#定义构造数据方法
def build_data():
#指定文件路径
file="../data/login.json"
#定义测试数据空列表
test_data=[]
#通过文件流的形式打开读取文件并取名为f
with open(file,encoding="utf-8") as f:
#加载f文件数据并用json_data接收
json_data=json.load(f)
#使用for循环遍历json_data文件把文件的数据一行一行的赋值,
for case_data in json_data:
#变量名等于你获取的第一条测试用例里面case_data通过他的get指明他的key
#实际上他的key就是文件里面定义的变量名
#基于文件里面的参数名来提取他的值并存下来
username = case_data.get("username")
password = case_data.get("password")
verify_code = case_data.get("verify_code")
content_type = case_data.get("content_type")
status_code = case_data.get("status_code")
status= case_data.get("status")
mag = case_data.get("mag")
#传递数据追加到空列表里面去
test_data.append((username,password,verify_code,content_type,status_code,status,mag))
#打印一下组装出来的数据
#print(test_data)
#返回数据
return test_data
第三步:在测试类里面的测试方法上引用参数化
# 通过parameterized.expand通过传入build_data()来获得相关的数据
# 引用参数化
@parameterized.expand(build_data())
基于数据库实现参数化:
第一步:导包
#导入db工具类
from tpshop.tools.dbutil import DBUtil
#导入引用参数化的包
from parameterized import parameterized
第二步:创建数据库的工具类连接执行数据库操作
# 导包
import pymysql
# 创建工具类
class DBUtil():
# 初始化
__conn = None
__cursor = None
# 创建连接
@classmethod
def __get_conn(cls):
if cls.__conn is None:
cls.__conn = pymysql.connect(host="localhost",
port=3306,
user="root",
password="123123123",
database="books")
return cls.__conn
# 获取游标
@classmethod
def __get_cursor(cls):
if cls.__cursor is None:
cls.__cursor = cls.__get_conn().cursor()
return cls.__cursor
# 执行sql
@classmethod
def exe_sql(cls, sql):
try:
# 获取游标对象
cursor = cls.__get_cursor()
# 调用游标对象的execute方法,执行sql
cursor.execute(sql)
# 如果是查询
if sql.split()[0].lower() == "select":
# 返回所有数据
return cursor.fetchall()
# 否则:
else:
# 提交事务
cls.__conn.commit()
# 返回受影响的行数
return cursor.rowcount
except Exception as e:
# 事务回滚
cls.__conn.rollback()
# 打印异常信息
print(e)
finally:
# 关闭游标
cls.__close_cursor()
# 关闭连接
cls.__close_conn()
# 关闭游标
@classmethod
def __close_cursor(cls):
if cls.__cursor:
cls.__cursor.close()
cls.__cursor = None
# 关闭连接
@classmethod
def __close_conn(cls):
if cls.__conn:
cls.__conn.close()
cls.__conn = None
第三步:构造测试数据
#DB参数化
#定义构造数据方法
def build_data():
#通过数据库去获取数据作为参数化的列表
sql="select * from t_login"
#执行dbutil.exe_sql方法把sql传入进去并把查询结果返回放在变量db_data里
db_data=DBUtil.exe_sql(sql)
#定义测试数据空列表
test_data=[]
#使用for循环遍历db_data的数据并一行一行的赋值,
for case_data in db_data:
#按照下标来提取数据并赋值给变量
username = case_data[2]
password = case_data[3]
verify_code = case_data[4]
status_code = case_data[5]
content_type = case_data[6]
status= case_data[7]
mag = case_data[8]
#传递数据追加到空列表里面去
test_data.append((username,password,verify_code,content_type,status_code,status,mag))
#打印一下组装出来的数据
#print(db_data)
#返回数据
return test_data
第四步:在测试类里面的测试方法上引用参数化
# 通过parameterized.expand通过传入build_data()来获得相关的数据
# 引用参数化
@parameterized.expand(build_data())
十.集成UnitTest:
UnitTest优势:
管理测试用例,提供了丰富的断言,生成测试报告
unittest.TestCase:TestCase类,所有测试用例类继承的基本类:class 类名(unittest.TestCase):
使用unittest框架编写测试用例思路:
1.导入模块包
import unittest
2.定义测试类,继承父类为unittest.TestCase
#可继承unittest.TestCase的方法,如setUp和tearDown方法,不过此方法可以在子类重写,覆盖父类方法。
#可继承unittest.TestCase的各种断言方法。
class Test(unittest.TestCase):
3.定义setUp()方法用于测试用例执行前的初始化工作(前置处理)
#注意,所有类中方法的入参为self,定义方法的变量也要“self.变量”
#注意,输入的值为字符型的需要转为int型
def setUp(self):
self.number=raw_input('Enter a number:')
self.number=int(self.number)
4.定义测试用例,以“test_”开头命名的方法
#注意,方法的入参为self
#可使用unittest.TestCase类下面的各种断言方法用于对测试结果的判断
#可定义多个测试用例
#最重要的就是该部分
def test_case1(self):
print self.number
self.assertEqual(self.number,10,msg='Your input is not 10')
def test_case2(self):
print self.number
self.assertEqual(self.number,20,msg='Your input is not 20')
@unittest.skip('暂时跳过用例3的测试')
def test_case3(self):
print self.number
self.assertEqual(self.number,30,msg='Your input is not 30')
5.定义tearDown()方法用于测试用例执行之后的善后工作(后置处理)
#注意,方法的入参为self
def tearDown(self):
print 'Test over'
6.如果直接运行该文件(name 值为 main ),则执行以下语句,常用于测试脚本是否能够正常运行
if __name__=='__main__':
(1)执行测试用例方案一如下:
#unittest.main()方法会搜索该模块下所有以test开头的测试用例方法,并自动执行它们。
#执行顺序是命名顺序:先执行test_case1,再执行test_case2
unittest.main()
(2)执行测试用例方案二如下:
#6.2.1先构造测试集
#6.2.1.1实例化测试套件
suite=unittest.TestSuite()
#6.2.1.2将测试用例加载到测试套件中。
#执行顺序是安装加载顺序:先执行test_case2,再执行test_case1
suite.addTest(Test('test_case2'))
suite.addTest(Test('test_case1'))
#6.2.2执行测试用例
#6.2.2.1实例化TextTestRunner类
runner=unittest.TextTestRunner()
#6.2.2.2使用run()方法运行测试套件(即运行测试套件中的所有用例)
runner.run(suite)
'''
'''
#6.3执行测试用例方案三如下:
#6.3.1构造测试集(简化了方案二中先要创建测试套件然后再依次加载测试用例)
#执行顺序同方案一:执行顺序是命名顺序:先执行test_case1,再执行test_case2
test_dir = './'
discover = unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')
#6.3.2执行测试用例
#6.3.2.1实例化TextTestRunner类
runner=unittest.TextTestRunner()
#6.3.2.2使用run()方法运行测试套件(即运行测试套件中的所有用例)
runner.run(discover)
'''
十一.使用接口测试框架实战:
操作步骤:
1.先进行初始步骤创建py文件,每个文件都会有不同的用途管理
apitestFramework #项目名称
api #定义封装被测系统的接口
scripts #定义测试用例脚本
date #存放测试数据
report #存放生成的测试报告
tools #存放第三方的文件
app.py #定义项目的配置信息
utils.py #定义工具类
run_suite.py #执行测试套件的入口
2.封装被测系统的接口
# 封装被测试系统接口
# 定义接口类
import requests
class LoginAPI:
# 初始化
def __init__(self):
self.url_verify = "http://192.168.0.222:5252/index.php?m=Home&c=User&a=verify"
self.url_login = "http://192.168.0.222:5252/index.php?m=Home&c=User&a=do_login"
# 获取验证码接口
def get_verify_code(self, session):
return session.get(self.url_verify)
# 登录接口
def login(self, session, username, password, verify_code):
login_data = {
"username": username,
"password": password,
"verify_code": verify_code
}
return session.post(url=self.url_login, data=login_data)
2.定义测试用例脚本
2.1使用传参的方式定义测试用例脚本
#设计测试用例
#导包
import requests
import unittest
from tpshop.api.login import LoginAPI
# 定义测试类
class TestLoginAPI(unittest.TestCase):
# 前置处理
def setUp(self):
self.login_api = LoginAPI()
self.session = requests.Session()
# 后置处理
def tearDown(self):
if self.session:
self.session.close()
# 定义测试方法
# 登录成功
def test01_login_success(self):
#调用验证码接口
response = self.login_api.get_verify_code(self.session)
#断言状态码是否等于200
self.assertEqual(200, response.status_code)
#断言Content-Type是否包含image
self.assertIn("image", response.headers.get("Content-Type"))
#调用登录接口
response = self.login_api.login(self.session, "18512829605", "123456","8888")
#打印响应结果
print(response.json())
#断言状态码是否等于200
self.assertEqual(200, response.status_code)
#断言status是否包含1
self.assertEqual(1, response.json().get("status"))
#断言mas是否包含登录成功
self.assertIn("登陆成功", response.json().get("msg"))
#账号不正确
def test02_user_isnot_exist(self):
#调用验证码接口
response=self.login_api.get_verify_code(self.session)
self.assertEqual(200, response.status_code)
#断言Content-Type是否包含image
self.assertIn("image", response.headers.get("Content-Type"))
#调用登录接口
response=self.login_api.login(self.session,18512829607,123456,8888)
#打印响应结果
print(response.json())
#断言状态码是否等于200
self.assertEqual(200, response.status_code)
#断言status是否包含1
self.assertEqual(-1, response.json().get("status"))
#断言mas是否包含登录成功
self.assertIn("账号不存在!", response.json().get("msg"))
#密码错误
def test03_password_exist(self):
# 调用验证码接口
response = self.login_api.get_verify_code(self.session)
self.assertEqual(200, response.status_code)
# 断言Content-Type是否包含image
self.assertIn("image", response.headers.get("Content-Type"))
# 调用登录接口
response = self.login_api.login(self.session, 18512829605, 1234567, 8888)
# 打印响应结果
print(response.json())
# 断言状态码是否等于200
self.assertEqual(200, response.status_code)
# 断言status是否包含1
self.assertEqual(-2, response.json().get("status"))
# 断言mas是否包含登录成功
self.assertIn("密码错误", response.json().get("msg"))
2.2使用参数化的方式定义测试用例脚本
首先把需要参数化的数据使用json的方式存放起来
[
{
"desc": "case01 登录成功",
"username": "18512829605",
"password": "123456",
"verify_code": "8888",
"content_type": "image",
"status_code": 200,
"status": 1,
"mag": "登陆成功"
},
{
"desc": "case02 账号不存在",
"username": "18512829606",
"password": "123456",
"verify_code": "8888",
"content_type": "image",
"status_code": 200,
"status": -1,
"mag": "账号不存在!"
},
{
"desc": "case03 密码错误",
"username": "18512829605",
"password": "1234567",
"verify_code": "8888",
"content_type": "image",
"status_code": 200,
"status": -2,
"mag": "密码错误"
}
]
引用参数化设计测试用例脚本
#设计测试用例
#导包
import json
import requests
import unittest
from tpshop.api.login import LoginAPI
#引用参数化导包
from parameterized import parameterized
#参数化
#定义构造数据方法
def build_data():
#指定文件路径
file="../data/login.json"
#定义测试数据空列表
test_data=[]
#通过文件流的形式打开读取文件并取名为f
with open(file,encoding="utf-8") as f:
#加载f文件数据并用json_data接收
json_data=json.load(f)
#使用for循环遍历json_data文件把文件的数据一行一行的赋值,
for case_data in json_data:
#变量名等于你获取的第一条测试用例里面case_data通过他的get指明他的key
#实际上他的key就是文件里面定义的变量名
#基于文件里面的参数名来提取他的值并存下来
username = case_data.get("username")
password = case_data.get("password")
verify_code = case_data.get("verify_code")
content_type = case_data.get("content_type")
status_code = case_data.get("status_code")
status= case_data.get("status")
mag = case_data.get("mag")
#传递数据追加到空列表里面去
test_data.append((username,password,verify_code,content_type,status_code,status,mag))
#打印一下组装出来的数据
#print(test_data)
#返回数据
return test_data
# 创建测试类
class TestLoginAPI(unittest.TestCase):
# 前置处理
def setUp(self):
self.login_api = LoginAPI()
self.session = requests.Session()
# 后置处理
def tearDown(self):
if self.session:
self.session.close()
# 通过parameterized.expand通过传入build_data()来获得相关的数据
# 引用参数化
@parameterized.expand(build_data())
# 定义测试方法创建测试用例
#引用参数名替换输入数据和预期结果
def test02_login(self,username,password,verify_code,content_type,status_code,status,mag):
#调用验证码接口
response = self.login_api.get_verify_code(self.session)
#断言状态码是否等于200
self.assertEqual(status_code, response.status_code)
#断言Content-Type是否包含image
self.assertIn(content_type, response.headers.get("Content-Type"))
#调用登录接口
response = self.login_api.login(self.session, username, password,verify_code)
#打印响应结果
print(response.json())
#断言状态码是否等于200
self.assertEqual(status_code, response.status_code)
#断言status是否包含1
self.assertEqual(status, response.json().get("status"))
#断言mag是否包含登录成功
self.assertIn(mag, response.json().get("msg"))
2.3使用DB参数化设计测试用例脚本
首先进行工具类的封装
# 导包
import pymysql
# 创建工具类
class DBUtil():
# 初始化
__conn = None
__cursor = None
# 创建连接
@classmethod
def __get_conn(cls):
if cls.__conn is None:
cls.__conn = pymysql.connect(host="localhost",
port=3306,
user="root",
password="123123123",
database="books")
return cls.__conn
# 获取游标
@classmethod
def __get_cursor(cls):
if cls.__cursor is None:
cls.__cursor = cls.__get_conn().cursor()
return cls.__cursor
# 执行sql
@classmethod
def exe_sql(cls, sql):
try:
# 获取游标对象
cursor = cls.__get_cursor()
# 调用游标对象的execute方法,执行sql
cursor.execute(sql)
# 如果是查询
if sql.split()[0].lower() == "select":
# 返回所有数据
return cursor.fetchall()
# 否则:
else:
# 提交事务
cls.__conn.commit()
# 返回受影响的行数
return cursor.rowcount
except Exception as e:
# 事务回滚
cls.__conn.rollback()
# 打印异常信息
print(e)
finally:
# 关闭游标
cls.__close_cursor()
# 关闭连接
cls.__close_conn()
# 关闭游标
@classmethod
def __close_cursor(cls):
if cls.__cursor:
cls.__cursor.close()
cls.__cursor = None
# 关闭连接
@classmethod
def __close_conn(cls):
if cls.__conn:
cls.__conn.close()
cls.__conn = None
然后引用DB工具类进行用例设计
#设计测试用例
#导包
import json
import requests
import unittest
from tpshop.api.login import LoginAPI
#导入db工具类
from tpshop.tools.dbutil import DBUtil
#导入引用参数化的包
from parameterized import parameterized
#DB参数化
#定义构造数据方法
def build_data():
#通过数据库去获取数据作为参数化的列表
sql="select * from t_login"
#执行dbutil.exe_sql方法把sql传入进去并把查询结果返回放在变量db_data里
db_data=DBUtil.exe_sql(sql)
#定义测试数据空列表
test_data=[]
#使用for循环遍历db_data的数据并一行一行的赋值,
for case_data in db_data:
#按照下标来提取数据并赋值给变量
username = case_data[2]
password = case_data[3]
verify_code = case_data[4]
status_code = case_data[5]
content_type = case_data[6]
status= case_data[7]
mag = case_data[8]
#传递数据追加到空列表里面去
test_data.append((username,password,verify_code,content_type,status_code,status,mag))
#打印一下组装出来的数据
#print(db_data)
#返回数据
return test_data
# 创建测试类
class TestLoginAPI(unittest.TestCase):
# 前置处理
def setUp(self):
self.login_api = LoginAPI()
self.session = requests.Session()
# 后置处理
def tearDown(self):
if self.session:
self.session.close()
# 通过parameterized.expand通过传入build_data()来获得相关的数据
# 引用参数化
@parameterized.expand(build_data())
# 定义测试方法创建测试用例
#引用参数名替换输入数据和预期结果
def test02_login(self,username,password,verify_code,content_type,status_code,status,mag):
#调用验证码接口
response = self.login_api.get_verify_code(self.session)
#断言状态码是否等于200
self.assertEqual(status_code, response.status_code)
#断言Content-Type是否包含image
self.assertIn(content_type, response.headers.get("Content-Type"))
#调用登录接口
response = self.login_api.login(self.session, username, password,verify_code)
#打印响应结果
print(response.json())
#断言状态码是否等于200
self.assertEqual(status_code, response.status_code)
#断言status是否包含1
self.assertEqual(status, response.json().get("status"))
#断言mag是否包含登录成功
self.assertIn(mag, response.json().get("msg"))
3.生成测试报告
首先需要导入HTMLTestRunner.py类
#生成测试报告
#练习.导包
import unittest
import time
from tpshop.scripts.test03_login_db import TestLoginAPI
from tools.HTMLTestRunner import HTMLTestRunner
#2.封装测试套件
#实例化对象
suite=unittest.TestSuite()
#调用addTest方法通过unittest.makeSuite把测试类添加进来
suite.addTest(unittest.makeSuite(TestLoginAPI))
#3.指定测试报告路径并借助format来占位并调用系统的时间模块
report="./report/-{}.html".format(time.strftime("%Y%m%d-%H%M%S"))
#4.以文件流的形式打开文件并取名为f
with open(report,"wb") as f:
#5.创建HtmlTestRunner运行器指明为文件f并完善报告的名字
runner=HTMLTestRunner(f,title="tpshop测试报告")
#6.执行测试套件,执行封装的套件
runner.run(suite)