4.0-接口测试--接口自动化篇总结
一、requests库
requests 内容:
1,封装了get、post等;
2、以关键字参数的方式,封装了各类请求参数,params、data、headers、token、cookie等;
3,封装了响应内容,status_code、json()、cookies、url等;
4,’session会话对象,可以跨请求;
1 介绍及安装
-
介绍:基于python语言开发的一个开源的库,能够完全满足基于HTTP协议的接口测试。
-
安装:
-
安装: pip install requests
-
验证: pip show requests
-
2 发送get请求
2.1直接通过url传递参数
2.2通过params传递参数__字符串
2.3通过params传递参数__字典
需求:
1. 访问TPshop搜索商品的接口,通过查询字符串的方式传递搜索的关键字 iPhone ,并查看响应数据
2. 请求路径格式为: http://localhost/Home/Goods/search.html?q=iPhone
# 导包
import requests
# 发送请求
# 直接通过url传递参数
# response = requests.get(" http://localhost/Home/Goods/search.html?q=iphone")
# 通过params传递参数:
# (1)字符串
urlA = "http://localhost/Home/Goods/search.html"
stringA = "q=iphone"
response = requests.get(url=urlA, params=stringA)
# (2)字典
dictA = { "q": "iphone" }
response = requests.get(url=urlA, params=dictA)
# 查看响应
print(response.text)
补充:解决响应数据乱码问题
import requests
#发送请求
response=requests.get("http://www.baidu.com")
#查看响应
#查看响应数据编码格式 #ISO-8859-1
print("原始的数据编码为:", response.encoding)
print("设置前响应数据:", response.text)
#解决响应数据乱码问题,设置响应数据编码格式
response.encoding="utf-8"
print(response.text)
3 发送post请求
response = requests.post(url, data=None, json=None)
"""
:param url: 请求的URL
:param data: (可选) 要发送到请求体中的字典、元组、字节或文件对象
:param json: (可选) 要发送到请求体中的JSON数据
"""
说明:
-
data: 参数接收form表单数据,后台会⾃动附加form表单请求信息头(data数据格式为字典)
-
json:参数接收json数据,后台会⾃动附加json表单请求信息头
(headers = {"Content-Type":"application/json"})
3.1 提交form表单
需求:
1. 请求TPshop项目的登录接口,请求数据(username: 13088888888, password: 123456, verify_code: 1234)
2. 登录接口URL:http://localhost/index.php?m=Home&c=User&a=do_login
# 导包
import requests
# 发请求
login_url = "http://localhost/index.php?m=Home&c=User&a=do_login"
login_data = { "username": "13488888888",
"password": "123456", "
verify_code": "8888"
}
response = requests.post(url=login_url, data=login_data)
# 看响应
print(response.json())
3.2 提交json数据
需求:
1. 请求IHRM项目的登录接口,请求数据( {"mobile":"13800000002", "password":"123456"} )
2. 登录接口URL:http://ihrm-test.itheima.net/api/sys/login
#导包
import requests
#发请求
login_url="http://ihrm-test.itheima.net/api/sys/login"
login_data={
"mobile":"13800000002",
"password":"123456"
}
response=requests.post(url=login_url,json=login_data)
print(response.json())
4发送url请求(传递URL参数)
需求:
1. 访问TPshop搜索商品的接口,通过查询字符串的方式传递搜索的关键字 iPhone ,并查看响应数据
2. 请求路径格式为: http://localhost/Home/Goods/search.html?q=iPhone
# 导包
import requests
# 发送请求
# 直接通过url传递参数
# response = requests.get(" http://localhost/Home/Goods/search.html?q=iphone")
# 通过params传递参数:
# (1)字符串
urlA = "http://localhost/Home/Goods/search.html"
stringA = "q=iphone"
response = requests.get(url=urlA, params=stringA)
# (2)字典
dictA = { "q": "iphone" }
response = requests.get(url=urlA, params=dictA)
# 查看响应
print(response.text)
**5 **响应内容解析
用途:断言
实现:
- 响应状态码: response.status_code
- url地址信息: response.url
- 查看响应数据编码格式: response.encoding
- 查看响应头部信息: response.headers
- 查看cookies信息: response.cookies
- 文本形式查看响应数据: response.text
- 字节码形式查看响应数据:response.content
- **json形式查看响应数据: ** response.json()
案例:
1). 访问百度首页的接口`http://www.baidu.com`,获取以下响应数据
2). 获取响应状态码
3). 获取请求URL
4). 获取响应字符编码
5). 获取响应头数据
6). 获取响应的cookie数据
7). 获取文本形式的响应内容
8). 获取字节形式的响应内容
import requests
# 1). 访问百度首页的接口`http://www.baidu.com`,获取以下响应数据
response=requests.get("http://www.baidu.com")
# 2). 获取响应状态码
print("响应状态码:",response.status_code)
# 3). 获取请求URL
print("URL:",response.url)
# 4). 获取响应字符编码
print("编码格式:",response.encoding)
# 5). 获取响应头数据
print("响应头信息:",response.headers)
#如想提取响应头中的Content-Type
print("Content-Type",response.headers.get("Content-Type"))
# 6). 获取响应的cookie数据
print("cookie",response.cookies)
print("提取指定的cookie:",response.cookies.get("BDORZ"))
# 7). 获取文本形式的响应内容
response.encoding="utf-8"
print("文本形式显示响应内容:",response.text)
# 8). 获取字节形式的响应内容
print("获取字节形式的响应内容:",response.content)
print("获取字节形式的响应内容:",response.content.decode("utf-8"))
6 设置请求头
- 使用方法: headers=
- 案例:
1. 请求IHRM项目的登录接口,URL: http://ihrm-test.itheima.net/api/sys/login
2. 请求头: Content-Type: application/json
3. 请求体: {"mobile":"13800000002", "password":"123456"}
import requests
login_url="http://ihrm-test.itheima.net/api/sys/login"
login_header={"Content-Type":"application/json"}
login_data={"mobile":"13800000002","password":"123456"}
response=requests.post(url=login_url,json=login_data,headers=login_header)
r=response.json()
7 设置cookie(了解)
- 产生及应用
解决tpshop登录验证码问题(cookie)
案例:解决tpshop登录验证码问题
1. 使用requests库调用TPshop登录功能的相关接口,完成登录操作
2. 登录成功后获取‘我的订单’页面的数据
接口地址:
获取验证码:http://localhost/index.php?m=Home&c=User&a=verify
登录用户:(username: 13088888888, password: 123456, verify_code: 1234)
登录:http://localhost/index.php?m=Home&c=User&a=do_login
我的订单:http://localhost/Home/Order/order_list.html
- 登录的时候首先会发送一个验证码请求,-----查看“获取验证码”接口请求的cookie 并获取对应的cookie
- 问题1--- 登录不带cookie 登录会提示验证码错误 ,如下图:
- 解决--登录请求中带上获取的cookie,如下图:
- 需求,获取“我的订单”页面数据
- 问题2---访问我的订单接口,返回的是首页接口的页面数据
- 解决--在请求“我的订单”接口里加上cookies信息
Cookie案例总结:
-
比较麻烦,麻烦的点在每一个依赖的请求都需要单独设置它的cookie信息--不好用
-
如何解决?-----用session(会自动记录cookie信息)
-
代码
import requests
#获取验证码
response=requests.get("http://localhost/index.php?m=Home&c=User&a=verify")
print(response.cookies)
PHPSESSID = response.cookies.get("PHPSESSID")
print(PHPSESSID)
# 登录
login_url = "http://localhost/index.php?m=Home&c=User&a=do_login"
login_data = {"username": "13488888888",
"password": "123456",
"verify_code": "8888" }
cookies = { "PHPSESSID": PHPSESSID }
response = requests.post(url=login_url, data=login_data, cookies=cookies)
print(response.json())
# 我的订单:http://localhost/Home/Order/order_list.html
response = requests.get("http://localhost/Home/Order/order_list.html", cookies=cookies)
print(response.text)
9 设置session(掌握)
解决tpshop登录验证码问题(session)
-
作用:在多个请求之间存储数据并自动添加数据,如cookies
-
使用:
- 实例化: session = requests.Session()
- 发送请求:
- request.get() ==> session.get()
-
案例:
案例:解决tpshop登录验证码问题 1. 使用requests库调用TPshop登录功能的相关接口,完成登录操作 2. 登录成功后获取‘我的订单’页面的数据 接口地址: 获取验证码:http://localhost/index.php?m=Home&c=User&a=verify 登录用户:(username: 13088888888, password: 123456, verify_code: 1234) 登录:http://localhost/index.php?m=Home&c=User&a=do_login 我的订单:http://localhost/Home/Order/order_list.html
-
代码
import requests
#创建一个session对象
session=requests.Session()
#获取验证码
response=session.get("http://localhost/index.php?m=Home&c=User&a=verify")
# 登录
login_url = "http://localhost/index.php?m=Home&c=User&a=do_login"
login_data = {"username": "13488888888",
"password": "123456",
"verify_code": "8888" }
response = session.post(url=login_url, data=login_data)
print(response.json())
# 我的订单:http://localhost/Home/Order/order_list.html
response =session.get("http://localhost/Home/Order/order_list.html")
print(response.text)
二、集成UnitTest
- UnitTest优势
- 管理测试用例
- 提供了丰富的断言
- 生成测试报告
案例1:使用TPShop项目完成对登录功能的接口测试
获取验证码: http://localhost/index.php?m=Home&c=User&a=verify
登录 : http://localhost/index.php?m=Home&c=User&a=do_login
实现思路:
# 导包
# 创建测试类
# 创建测试方法
# setup
# 实例化session对象
# 定义验证接口url地址
# 定义正如接口url地址
# teardown
# 关闭session对象
# 登录成功
# 发送验证码请求并断言
# 发登录请求并断言
# 账号不存在
# 发送验证码请求并断言
# 发登录请求并断言
# 密码错误
# 发送验证码请求并断言
# 发登录请求并断言
实现代码:
import requests
import unittest
class TPShopLogin(unittest.TestCase):
def setUp(self):
#实例化session对象
self.session=requests.Session()
#定义验证码接口url地址
self.url_verify="http://localhost/index.php?m=Home&c=User&a=verify"
#定义登录接口url地址
self.url_login="http://localhost/index.php?m=Home&c=User&a=do_login"
#登录成功
def test01_success(self):
#发送验证码请求并断言
response=self.session.get(url=self.url_verify)
self.assertEqual(200,response.status_code)
self.assertIn("image",response.headers.get("Content-Type"))
#发送登录请求并断言
login_data={
"username":"13488888888",
"password":"123456",
"verify_code":"8888"
}
response=self.session.post(url=self.url_login,data=login_data)
print(response.json())
self.assertEqual(200,response.status_code)
self.assertEqual(1,response.json().get("status"))
self.assertIn("登陆成功",response.json().get("msg"))
#账号不存在
def test02_user_is_not_exist(self):
# 发送验证码请求并断言
response = self.session.get(url=self.url_verify)
self.assertEqual(200, response.status_code)
self.assertIn("image", response.headers.get("Content-Type"))
# 发送登录请求并断言
login_data = {
"username": "13823322221",
"password": "123456",
"verify_code": "8888"
}
response = self.session.post(url=self.url_login, data=login_data)
print(response.json())
self.assertEqual(200, response.status_code)
self.assertEqual(-1, response.json().get("status"))
self.assertIn("账号不存在", response.json().get("msg"))
#密码错误
def test03_password_error(self):
# 发送验证码请求并断言
response = self.session.get(url=self.url_verify)
self.assertEqual(200, response.status_code)
self.assertIn("image", response.headers.get("Content-Type"))
# 发送登录请求并断言
login_data = {
"username": "13488888888",
"password": "123356",
"verify_code": "8888"
}
response = self.session.post(url=self.url_login, data=login_data)
print(response.json())
self.assertEqual(200, response.status_code)
self.assertEqual(-2, response.json().get("status"))
self.assertIn("密码错误", response.json().get("msg"))
def tearDown(self):
#关闭session对象
self.session.close()
if __name__ == '__main__':
unittest.main()
生成报告:
#导包
import time
import unittest
from HTMLTestRunner import HTMLTestRunner
from test_requests.test10_unittest_tpshop import TPShopLogin
from test_requests.test12_unittest_params import TPShopLogin2
#封装测试套件
suite=unittest.TestSuite()
suite.addTest(unittest.makeSuite(TPShopLogin))
suite.addTest(unittest.makeSuite(TPShopLogin2))
#指定报告路径
report="../report/report-{}.html".format(time.strftime("%Y%m%d-%H%M%S"))
# 打开文件流
with open(report,"wb") as f:
# 创建HTMLTestRunner运行器
runner = HTMLTestRunner(f, title="tpshop接口测试报告")
# 执行测试套件
runner.run(suite)
tpshop登录unittest实现参数化
1参数化-json数据文件
- json数据准备--login.json
[
{
"desc": "登录成功",
"username": "13488888888",
"password": "123456",
"verify_code": "8888",
"status_code": 200,
"status": 1,
"msg": "登陆成功"
},
{
"desc": "账号不存在",
"username": "13488888899",
"password": "123456",
"verify_code": "8888",
"status_code": 200,
"status": -1,
"msg": "账号不存在"
},
{
"desc": "密码错误",
"username": "13488888888",
"password": "error",
"verify_code": "8888",
"status_code": 200,
"status": -2,
"msg": "密码错误"
}
]
#tpshop登录unittest实现参数化:
import json
import requests
import unittest
from parameterized import parameterized
#构造测试数据
def build_data():
test_data=[]
file="../data/login.json"
with open(file,encoding="utf-8") as f:
json_data=json.load(f)
for case_data in json_data:
username=case_data.get("username")
password = case_data.get("password")
verify_code = case_data.get("verify_code")
status_code = case_data.get("status_code")
status = case_data.get("status")
msg = case_data.get("msg")
test_data.append((username,password,verify_code,status_code,status,msg))
# print("test_data".format(username,password,verify_code,status_code,status,msg))
print(test_data)
return test_data
class TPShopLogin2(unittest.TestCase):
def setUp(self):
#实例化session对象
self.session=requests.Session()
#定义验证码接口url地址
self.url_verify="http://localhost/index.php?m=Home&c=User&a=verify"
#定义登录接口url地址
self.url_login="http://localhost/index.php?m=Home&c=User&a=do_login"
def tearDown(self):
#关闭session对象
self.session.close()
@parameterized.expand(build_data())
def test01_login(self,username,password,verify_code,status_code,status,msg):
#发送验证码请求并断言
response=self.session.get(url=self.url_verify)
self.assertEqual(200,response.status_code)
self.assertIn("image",response.headers.get("Content-Type"))
#发送登录请求并断言
login_data={
"username":username,
"password":password,
"verify_code":verify_code
}
response=self.session.post(url=self.url_login,data=login_data)
print(response.json())
self.assertEqual(status_code,response.status_code)
self.assertEqual(status,response.json().get("status"))
self.assertIn(msg,response.json().get("msg"))
if __name__ == '__main__':
unittest.main()
2参数化-csv数据文件
- csv数据准备--login01.csv
#tpshop登录unittest实现参数化:
import csv
import json
import requests
import unittest
from parameterized import parameterized
#构造测试数据
def build_data():
test_data=[]
file = open("../data/login01.csv", "r")
table = csv.reader(file)
table.__next__()
for case_data in table:
username=case_data[0]
password = case_data[1]
verify_code = case_data[2]
status_code = case_data[3]
status = case_data[4]
msg = case_data[5]
test_data.append((username,password,verify_code,status_code,status,msg))
print(test_data)
return test_data
class TPShopLogin2(unittest.TestCase):
def setUp(self):
#实例化session对象
self.session=requests.Session()
#定义验证码接口url地址
self.url_verify="http://localhost/index.php?m=Home&c=User&a=verify"
#定义登录接口url地址
self.url_login="http://localhost/index.php?m=Home&c=User&a=do_login"
def tearDown(self):
#关闭session对象
self.session.close()
@parameterized.expand(build_data())
def test01_login(self,username,password,verify_code,status_code,status,msg):
#发送验证码请求并断言
response=self.session.get(url=self.url_verify)
self.assertEqual(200,response.status_code)
self.assertIn("image",response.headers.get("Content-Type"))
#发送登录请求并断言
login_data={
"username":username,
"password":password,
"verify_code":verify_code
}
response=self.session.post(url=self.url_login,data=login_data)
print(response.json())
self.assertEqual(status_code,str(response.status_code))
self.assertEqual(status,str(response.json().get("status")))
self.assertIn(msg,str(response.json().get("msg")))
if __name__ == '__main__':
unittest.main()
3数据驱动-DDT
- 准备json 文件
#tpshop登录unittest实现参数化:
import json
from ddt import ddt,data,unpack
import requests
import unittest
from parameterized import parameterized
#构造测试数据
def build_data():
test_data=[]
file="../data/login.json"
with open(file,encoding="utf-8") as f:
json_data=json.load(f)
for case_data in json_data:
username=case_data.get("username")
password = case_data.get("password")
verify_code = case_data.get("verify_code")
status_code = case_data.get("status_code")
status = case_data.get("status")
msg = case_data.get("msg")
test_data.append((username,password,verify_code,status_code,status,msg))
# print("test_data".format(username,password,verify_code,status_code,status,msg))
print(test_data)
return test_data
@ddt
class TPShopLogin2(unittest.TestCase):
def setUp(self):
#实例化session对象
self.session=requests.Session()
#定义验证码接口url地址
self.url_verify="http://localhost/index.php?m=Home&c=User&a=verify"
#定义登录接口url地址
self.url_login="http://localhost/index.php?m=Home&c=User&a=do_login"
def tearDown(self):
#关闭session对象
self.session.close()
@data(*build_data())
@unpack
def test01_login(self,username,password,verify_code,status_code,status,msg):
#发送验证码请求并断言
response=self.session.get(url=self.url_verify)
self.assertEqual(200,response.status_code)
self.assertIn("image",response.headers.get("Content-Type"))
#发送登录请求并断言
login_data={
"username":username,
"password":password,
"verify_code":verify_code
}
response=self.session.post(url=self.url_login,data=login_data)
print(response.json())
self.assertEqual(status_code,response.status_code)
self.assertEqual(status,response.json().get("status"))
self.assertIn(msg,response.json().get("msg"))
if __name__ == '__main__':
unittest.main()
三、接口测试框架开发
1 框架结构
- 重点说明:
- (1)核心在于将测试用例与被测试系统API进行分离,便于后期维护
- (2)测试用例是通过unittest进行管理,并提供了丰富的断言(等于、包含等)
- (3)可以通过参数化思想测试数据与测试脚本的分离
- (4)可以调用数据库进行结果验证或将数据库作为参数化的数据源
- (5)借助第三方工具快速的生成HTML报告
2 框架目录结构
- tpshop -- 项目代号
-
data -- 管理测试数据的文件夹
-
report -- 管理测试结果报告的文件夹
-
api -- 封装被测试系统的接口
-
scripts -- 测试用例脚本
-
tools -- 第三方工具包管理
-
app.py -- 配置信息文件
-
run_suite.py -- 测试用例执行入口
-
utils.py -- 自定义工具类
-
或者
-
3 封装被测试系统接口
3.1 TPShop项目登录接口封装
-
其他接口脚本用到登录接口,调用这个封装脚本就行了
-
被测系统的接口封装 获取验证码:"http://localhost/index.php?m=Home&c=User&a=verify" 登录:"http://localhost/index.php?m=Home&c=User&a=do_login"
-
实现代码:
# 定义接口类
class LoginAPI():
#初始化
def __init__(self):
self.url_verify = "http://localhost/index.php?m=Home&c=User&a=verify"
self.url_login = "http://localhost/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)
4 定义接口测试用例
- 实现代码
import unittest
import requests
from tpshop.api.login import LoginAPI
#创建测试类
class TestLogin(unittest.TestCase):
def setUp(self):
self.login_api=LoginAPI() #实例化接口类
self.session=requests.Session() #创建session对象
def test01_login_cuccess(self):
#调用验证码接口获取验证码 并进行断言
response=self.login_api.get_verify_code(self.session)
self.assertEqual(200,response.status_code)
self.assertIn("image",response.headers.get("Content-Type"))
#调用登录接口获取登录信息,并进行断言
response=self.login_api.login(self.session,"13488888888","123456","8888")
print(response.json())
self.assertEqual(200,response.status_code)
self.assertEqual(1,response.json().get("status"))
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)
self.assertIn("image", response.headers.get("Content-Type"))
# 调用登录接口获取登录信息,并进行断言
response = self.login_api.login(self.session, "13488888388", "123456", "8888")
print(response.json())
self.assertEqual(200, response.status_code)
self.assertEqual(-1, response.json().get("status"))
self.assertIn("账号不存在", response.json().get("msg"))
def test03_password_error(self):
# 调用验证码接口获取验证码 并进行断言
response = self.login_api.get_verify_code(self.session)
self.assertEqual(200, response.status_code)
self.assertIn("image", response.headers.get("Content-Type"))
# 调用登录接口获取登录信息,并进行断言
response = self.login_api.login(self.session, "13488888888", "124456", "8888")
print(response.json())
self.assertEqual(200, response.status_code)
self.assertEqual(-2, response.json().get("status"))
self.assertIn("密码错误", response.json().get("msg"))
def tearDown(self):
if self.session:
self.session.close()
5 集成测试报告
-
实现代码
-
import time import unittest from tpshop.scripts.test01_login import TestLogin from tpshop.tools.HTMLTestRunner import HTMLTestRunner # 封装测试套件 suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestLogin)) # 指定报告路径 report="./report/report-{}.html".format(time.strftime("%Y%m%d-%H%M%S")) # 打开文件流 with open(report, "wb") as f: # 创建HTMLTestRunner执行器 runner = HTMLTestRunner(f, title="接口测试报告") # 执行测试套件 runner.run(suite)
6 测试数据参数化
6.1 基于json文件实现参数化
- 实现代码
import json
import unittest
import requests
from tpshop.api.login import LoginAPI
from parameterized import parameterized
#构造数据方法
#构造测试数据
def build_data():
test_data=[]
file="../data/login.json"
with open(file,encoding="utf-8") as f:
json_data=json.load(f)
for case_data in json_data:
username=case_data.get("username")
password = case_data.get("password")
verify_code = case_data.get("verify_code")
status_code = case_data.get("status_code")
status = case_data.get("status")
msg = case_data.get("msg")
test_data.append((username,password,verify_code,status_code,status,msg))
print(test_data)
return test_data
#创建测试类
class TestLogin(unittest.TestCase):
def setUp(self):
self.login_api=LoginAPI() #实例化接口类
self.session=requests.Session() #创建session对象
@parameterized.expand(build_data)
def test01_login(self, username, password, verify_code, status_code,content_type, status, msg):
#调用验证码接口获取验证码 并进行断言
response=self.login_api.get_verify_code(self.session)
self.assertEqual(status_code,response.status_code)
self.assertIn(Content_Type,response.headers.get("Content-Type"))
#调用登录接口获取登录信息,并进行断言
response=self.login_api.login(self.session,username,password,verify_code)
print(response.json())
self.assertEqual(status_code,response.status_code)
self.assertEqual(status,response.json().get("status"))
self.assertIn(msg,response.json().get("msg"))
def tearDown(self):
if self.session:
self.session.close()
if __name__ == '__main__':
unittest.main()
- 运行结果
6.2 基于数据库实现参数化
-
去数据库构建测试数据
- 建立单独的test库,t_login表
- 脚本
/* Navicat MySQL Data Transfer Source Server : localhost_3306 Source Server Version : 50553 Source Host : localhost:3306 Source Database : books Target Server Type : MYSQL Target Server Version : 50553 File Encoding : 65001 Date: 2020-07-26 20:23:19 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for t_login -- ---------------------------- DROP TABLE IF EXISTS `t_login`; CREATE TABLE `t_login` ( `id` int(11) NOT NULL AUTO_INCREMENT, `case_desc` varchar(100) NOT NULL COMMENT '用例描述', `username` varchar(11) NOT NULL COMMENT '用户名', `password` varchar(16) NOT NULL COMMENT '密码', `verify_code` varchar(4) NOT NULL COMMENT '验证码', `status_code` int(3) NOT NULL DEFAULT '0' COMMENT '响应状态码', `content_type` varchar(11) NOT NULL COMMENT 'Content-Type', `status` int(1) NOT NULL DEFAULT '0' COMMENT '业务状态码', `msg` varchar(100) NOT NULL COMMENT '业务状态消息', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='TPshopLogin参数化'; -- ---------------------------- -- Records of t_login -- ---------------------------- INSERT INTO `t_login` VALUES ('1', 'case01登录成功', '13488888888', '123456', '8888', '200', 'image', '1', '登陆成功'); INSERT INTO `t_login` VALUES ('2', 'case02账号不存在', '13488888899', '123456', '8888', '200', 'image', '-1', '账号不存在'); INSERT INTO `t_login` VALUES ('3', 'case03密码错误', '13488888888', 'error', '8888', '200', 'image', '-2', '密码错误');
- 检查数据库内 数据是否成功
-
实现代码
"""
接口测试用例 --参数化
"""
from tpshop.tools.dbutil import DBUtil
import unittest
import requests
from tpshop.api.login import LoginAPI
from parameterized import parameterized
#构造数据方法
def build_data():
sql="select * from t_login"
db_data=DBUtil.exe_sql(sql)
test_data=[]
for case_data in db_data:
username = case_data[2]
password = case_data[3]
verify_code = case_data[4]
Content_Type = case_data[6]
status_code = case_data[5]
status = case_data[7]
msg = case_data[8]
test_data.append((username,password,verify_code,status_code,status,msg))
print(test_data)
return test_data
#创建测试类
class TestLogin(unittest.TestCase):
def setUp(self):
self.login_api=LoginAPI() #实例化接口类
self.session=requests.Session() #创建session对象
@parameterized.expand(build_data)
def test01_login(self, username, password, verify_code, status_code,content_type, status, msg):
#调用验证码接口获取验证码 并进行断言
response=self.login_api.get_verify_code(self.session)
self.assertEqual(status_code,response.status_code)
self.assertIn(Content_Type,response.headers.get("Content-Type"))
#调用登录接口获取登录信息,并进行断言
response=self.login_api.login(self.session,username,password,verify_code)
print(response.json())
self.assertEqual(status_code,response.status_code)
self.assertEqual(status,response.json().get("status"))
self.assertIn(msg,response.json().get("msg"))
def tearDown(self):
if self.session:
self.session.close()
if __name__ == '__main__':
unittest.main()
- 运行结果
四、IHRM项目实战任务
- 登录模块
- 员工管理模块
- 任务
- 搭建IHRM项目接口测试框架
- 封装IHRM登录接口
- 创建登录模块的测试用例
- 普通模式
- 参数化
- 生成HTML测试报告
一、搭建接口测试框架
二、封装被测试系统接口
1 登录
- IHIM项目登录封装接口类
登录:"http://ihrm-test.itheima.net/api/sys/login"
Method: POST
请求参数:
Headers
Content-Type : application/json
Body
mobile
password
#IHIM项目登录封装接口类
import requests
class LoginAPI():
#初始化
def __init__(self):
self.url="http://ihrm-test.itheima.net/api/sys/login"
#定义接口调用方法
def login(self,login_data):
return requests.post(url=self.url,json=login_data)
2 员工管理(format函数拼接)
#************************ 封装【员工管理】四个模块接口类 ****************
#1.添加员工
#2,修改员工
#3,查询员工
#4,删除员工
#导包
import requests
import app
#创建接口类
class EmployeeAPI():
#初始化
def __init__(self):
self.url_add_employee="http://ihrm-test.itheima.net/api/sys/user"
#修改员工地址要接员工ID,通过{}占位符站位,后期通过 format 拼接
self.url_update_employee="http://ihrm-test.itheima.net/api/sys/user/{}"
self.url_select_employee = "http://ihrm-test.itheima.net/api/sys/user/{}"
self.url_delete_employee = "http://ihrm-test.itheima.net/api/sys/user/{}"
# 1.添加员工
def add_employee(self,add_employee_data):
return requests.post(url=self.url_add_employee,json=add_employee_data,headers=app.headers_data)
# 2,修改员工
def update_employee(self,employee_id,update_data):
url=self.url_update_employee.format(employee_id)
return requests.put(url=url,json=update_data,headers=app.headers_data)
# 3,查询员工
def select_employee(self,employee_id):
url=self.url_select_employee.format(employee_id)
return requests.get(url=url,header=app.headers_data)
# 4,删除员工
def delete_employee(self,employee_id):
url = self.url_delete_employee.format(employee_id)
return requests.delete(url=url,header=app.headers_data)
三、定义接口测试用例
1 登录
1.1 实现登陆成功
# 导包
import unittest
from api.login import LoginAPI
class TestLogin(unittest.TestCase):
def setUp(self):
self.login_api=LoginAPI()
def tearDown(self):
pass
#case001 登录成功
def test01_case001(self):
#调用登录接口进行登录
response=self.login_api.login({"mobile":"13800000002","password":"123456"})
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(True,response.json().get("success"))
self.assertEqual(10000,response.json().get("code"))
self.assertIn("操作成功",response.json().get("message"))
1.2 实现其他测试用(总共13条用例)
import unittest
from api.login import LoginAPI
class TestLogin(unittest.TestCase):
def setUp(self):
self.login_api=LoginAPI()
def tearDown(self):
pass
#case001 登录成功
def test01_case001(self):
#调用登录接口进行登录
response=self.login_api.login({"mobile":"13800000002","password":"123456"})
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(True,response.json().get("success"))
self.assertEqual(10000,response.json().get("code"))
self.assertIn("操作成功",response.json().get("message"))
#case002 不输入手机号
def test01_case002(self):
#调用登录接口进行登录
response=self.login_api.login({"mobile":"","password":"123456"})
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(False,response.json().get("success"))
self.assertEqual(20001,response.json().get("code"))
self.assertIn("用户名或密码错误",response.json().get("message"))
#case003 不输入密码
def test01_case003(self):
#调用登录接口进行登录
response=self.login_api.login({"mobile":"13800000002","password":""})
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(False,response.json().get("success"))
self.assertEqual(20001,response.json().get("code"))
self.assertIn("用户名或密码错误",response.json().get("message"))
#case004 手机号长度小于11位
def test01_case004(self):
#调用登录接口进行登录
response=self.login_api.login({"mobile":"1380000002","password":"123456"})
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(False,response.json().get("success"))
self.assertEqual(20001,response.json().get("code"))
self.assertIn("用户名或密码错误",response.json().get("message"))
#case005 手机号长度大于11位
def test01_case005(self):
#调用登录接口进行登录
response=self.login_api.login({"mobile":"138000000021","password":"123456"})
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(False,response.json().get("success"))
self.assertEqual(20001,response.json().get("code"))
self.assertIn("用户名或密码错误",response.json().get("message"))
#case006 手机号输入非数字
def test01_case006(self):
#调用登录接口进行登录
response=self.login_api.login({"mobile":"error","password":"123456"})
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(False,response.json().get("success"))
self.assertEqual(20001,response.json().get("code"))
self.assertIn("用户名或密码错误",response.json().get("message"))
#case007 输入未注册的手机号
def test01_case007(self):
#调用登录接口进行登录
response=self.login_api.login({"mobile":"13800000112","password":"123456"})
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(False,response.json().get("success"))
self.assertEqual(20001,response.json().get("code"))
self.assertIn("用户名或密码错误",response.json().get("message"))
#case008 多参
def test01_case008(self):
#调用登录接口进行登录
response=self.login_api.login({"mobile":"13800000002","password":"123456","parameter":"hahaha"})
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(True,response.json().get("success"))
self.assertEqual(10000,response.json().get("cdde"))
self.assertIn("操作成功",response.json().get("message"))
#case009 少参-缺少手机号
def test01_case009(self):
#调用登录接口进行登录
response=self.login_api.login({"password":"123456"})
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(False,response.json().get("success"))
self.assertEqual(20001,response.json().get("code"))
self.assertIn("用户名或密码错误",response.json().get("message"))
#case010 少参-密码
def test01_case010(self):
#调用登录接口进行登录
response=self.login_api.login({"mobile":"13800000002"})
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(False,response.json().get("success"))
self.assertEqual(20001,response.json().get("code"))
self.assertIn("用户名或密码错误",response.json().get("message"))
#case011 无参
def test01_case011(self):
#调用登录接口进行登录
response=self.login_api.login({})
#response = self.login_api.login(None)
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(False,response.json().get("success"))
self.assertEqual(99999,response.json().get("code"))
self.assertIn("抱歉,系统繁忙,请稍后重试!",response.json().get("message"))
#case012 错误参数-手机号参数拼写错误
def test01_case012(self):
#调用登录接口进行登录
response=self.login_api.login({"mob":"13800000002","password":"123456"})
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(False,response.json().get("success"))
self.assertEqual(20001,response.json().get("code"))
self.assertIn("用户名或密码错误",response.json().get("message"))
#case013 错误参数-密码参数拼写错误
def test01_case013(self):
#调用登录接口进行登录
response=self.login_api.login({"mob":"13800000002","password":"123456"})
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(False,response.json().get("success"))
self.assertEqual(20001,response.json().get("code"))
self.assertIn("用户名或密码错误",response.json().get("message"))
1.3 生成测试报告
#导包
import time
import unittest
from script.test01_login import TestLogin
#组装测试报告的路径
from tools.HTMLTestRunner import HTMLTestRunner
suite=unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestLogin))
#指定测试报告的路径
report="./report/report.html".format(time.strftime("%Y%m%d-%H%M%S"))
#打开文件流
with open(report, "wb") as f:
# 创建HTMLTestRunner执行器
runner = HTMLTestRunner(f, title="接口测试报告")
# 执行测试套件
runner.run(suite)
1.4 参数化-json文件
准备数据(重点)
-
思路:将请求体的两个参数(mobile,password)数据放在定义的字典login_data{}里,然后创建json数据的时候利用“字典套字典”的思想。
-
示例:
{
"desc": "case001 登录成功",
"login_data": {"mobile": "13800000002","password": "123456"},
"status_code": 200,
"success": true,
"code": 10000,
"message": "操作成功"
},
- 准备json数据13条
[
{
"desc": "case001 登录成功",
"login_data": {
"mobile": "13800000002",
"password": "123456"
},
"status_code": 200,
"success": true,
"code": 10000,
"message": "操作成功"
},
{
"desc": "case002 不输入手机号",
"login_data": {
"mobile": "",
"password": "123456"
},
"status_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "case003 不输入密码",
"login_data": {
"mobile": "13800000002",
"password": ""
},
"status_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "case004 手机长度小于11位",
"login_data": {
"mobile": "1380000000",
"password": "123456"
},
"status_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "case005 手机场地大于11位",
"login_data": {
"mobile": "138000000023",
"password": "123456"
},
"status_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "case006 手机号输入非数字",
"login_data": {
"mobile": "error",
"password": "123456"
},
"status_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "case007 输入未注册手机号",
"login_data": {
"mobile": "13812321236",
"password": "123456"
},
"status_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "case008 多参",
"login_data": {
"mobile": "13800000002",
"password": "123456",
"haha": "xixi"
},
"status_code": 200,
"success": true,
"code": 10000,
"message": "操作成功"
},
{
"desc": "case009 少参-缺少手机号",
"login_data": {
"password": "123456"
},
"status_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "case010 少参-缺少密码",
"login_data": {
"mobile": "13800000002"
},
"status_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "case011 无参",
"status_code": 200,
"success": false,
"code": 99999,
"message": "抱歉,系统繁忙"
},
{
"desc": "case012 错误参数-手机号",
"login_data": {
"mobiel": "13800000002",
"password": "123456"
},
"status_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "case013 错误参数-密码",
"login_data": {
"mobile": "13800000002",
"passwd": "123456"
},
"status_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
}
]
实现代码
import json
import unittest
from api.login import LoginAPI
from parameterized import parameterized
#构建测试数据
def build_data():
test_data=[]
#指定文件路径
json_file="../data/login.json"
#打开json文件
with open(json_file,encoding="utf-8") as f:
#将json文件转化为字典
jsondict_data=json.load(f)
for case_data in jsondict_data:
login_data =case_data.get("login_data")
status_code = case_data.get("status_code")
success = case_data.get("success")
code = case_data.get("code")
message = case_data.get("message")
test_data.append((login_data,status_code,success,code,message))
print(test_data)
return test_data
class TestLogin(unittest.TestCase):
def setUp(self):
self.login_api=LoginAPI()
def tearDown(self):
pass
@parameterized.expand(build_data)
def test01_login(self,login_data,status_code,success,code,message):
#调用登录接口进行登录
response=self.login_api.login(login_data)
print(response.json())
#添加断言
self.assertEqual(status_code,response.status_code)
self.assertEqual(success,response.json().get("success"))
self.assertEqual(code,response.json().get("code"))
self.assertIn(message,response.json().get("message"))
2 员工管理(重点)
2.0数据准备(token和员工ID)
-
编写配置文件app.py---用来保存获取的token,相当于作为"全局变量",其他脚本来调用(app.headers_data)
#配置信息文件脚本----相当于全局变量 #************************************************************************************* #token TOKEN=None #请求头数据 headers_data={ "Content-Type":"application/json", #"Authorization":"Bearer f5050a1b-7919-444c-9ec4-3c1a7286536d" #可不写 因为获取token会追加写入到字典 } #*************************************************************************************
-
获取token--可以在登录成功的用例脚本中写,也可单独写个登录成功脚本。
思路:
#提取token信息 保存在配置文件app.py中-----相当于全局变量 app.TOKEN="Bearer "+ response.json().get("data") print(app.TOKEN) #将获取到的token 追加写到app.py中定义的字典headers_data中,{"Authorization":app.TOKEN} app.headers_data["Authorization"]=app.TOKEN print(app.headers_data["Authorization"])
实现代码:
#提取token 然后拼接"Bearer "+token 再追加写到app.py文件定义的字典headers_data中,{"Authorization":app.TOKEN} import unittest import app from api.login import LoginAPI class TestLogin(unittest.TestCase): def setUp(self): self.login_api=LoginAPI() #case001 登录成功 def test01_case001(self): #调用登录接口进行登录 response=self.login_api.login({"mobile":"13800000002","password":"123456"}) print(response.json()) #添加断言 self.assertEqual(200,response.status_code) self.assertEqual(True,response.json().get("success")) self.assertEqual(10000,response.json().get("code")) self.assertIn("操作成功",response.json().get("message")) #提取token信息 保存在配置文件app.py中-----相当于全局变量 app.TOKEN="Bearer "+ response.json().get("data") print(app.TOKEN) #将获取到的token 追加写到app.py中定义的字典headers_data中, #{"Authorization":app.TOKEN} app.headers_data["Authorization"]=app.TOKEN print(app.headers_data["Authorization"])
2.1 添加员工
添加员工接口说明
接口地址:http://ihrm-test.itheima.net/api/sys/user"
请求方式:post
请求参数:
header:
{"Content-Type":"application/json","Authorization":"Bearer xxx-xxx"}
boby:
{
"username":"jack0709t2", #用户唯一 必填参数
"mobile":"13212332170", #手机号唯一 必填参数
"timeOfEntry":"2020-07-09",
"formOfEmployment":1,
"workNumber":"10086", #员工id唯一 必填参数
"departmentName":"销售",
"departmentId":"1266699057968001024",
"correctionTime":"2020-07-30T16:00:00.000Z"
}
封装接口
#导包
import requests
import app
#创建接口类
class EmployeeAPI():
#初始化
def __init__(self):
self.url_add_employee="http://ihrm-test.itheima.net/api/sys/user"
#修改员工地址要接员工ID,通过{}占位符站位,后期通过 format 拼接
self.url_update_employee="http://ihrm-test.itheima.net/api/sys/user/{}"
self.url_select_employee = "http://ihrm-test.itheima.net/api/sys/user/{}"
self.url_delete_employee = "http://ihrm-test.itheima.net/api/sys/user/{}"
# 1.添加员工
def add_employee(self,add_employee_data):
return requests.post(url=self.url_add_employee,json=add_employee_data,headers=app.headers_data)
定义用例
#调用封装好的【员工管理】模块类,执行测试用例
import unittest
from api.employee import EmployeeAPI
#创建测试类
class TestEmployee(unittest.TestCase):
employee_id=None
#前置处理方法
def setUp(self):
self.employee_api=EmployeeAPI() #实例化下封装好的【员工管理】模块类,准备调用
#添加员工测试用例设计
def test01_add_employee(self):
add_employee_data={
"username": "mike0709t2", #用户唯一
"mobile": "13212342367", #手机号唯一
"timeOfEntry": "2020-07-09",
"formOfEmployment": 1,
"workNumber": "124312", #员工id唯一
"departmentName": "销售",
"departmentId": "1266699057968001024",
"correctionTime": "2020-07-30T16:00:00.000Z"
}
#获取响应结果
response=self.employee_api.add_employee(add_employee_data=add_employee_data)
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(True,response.json().get("success"))
self.assertEqual(10000, response.json().get("code"))
self.assertIn("操作成功", response.json().get("message"))
#提取员工ID
TestEmployee.employee_id=response.json().get("data").get("id")
print(TestEmployee.employee_id)
2.2 修改员工
修改员工接口说明
接口地址:http://ihrm-test.itheima.net/api/sys/user{}" #{}里是后面要拼接员工ID
请求方式:put
请求参数:
header:
{"Content-Type":"application/json","Authorization":"Bearer xxx-xxx"}
boby:
{"username":"rose0709"}
封装接口
#导包
import requests
import app
#创建接口类
class EmployeeAPI():
#初始化
def __init__(self):
self.url_add_employee="http://ihrm-test.itheima.net/api/sys/user"
#修改员工地址要接员工ID,通过{}占位符站位,后期通过 format 拼接
self.url_update_employee="http://ihrm-test.itheima.net/api/sys/user/{}"
self.url_select_employee = "http://ihrm-test.itheima.net/api/sys/user/{}"
self.url_delete_employee = "http://ihrm-test.itheima.net/api/sys/user/{}"
# 1.添加员工
def add_employee(self,add_employee_data):
return requests.post(url=self.url_add_employee,json=add_employee_data,headers=app.headers_data)
# 2,修改员工
def update_employee(self,employee_id,update_data):
url=self.url_update_employee.format(employee_id)
return requests.put(url=url,json=update_data,headers=app.headers_data)
定义用例
#调用封装好的【员工管理】模块类,执行测试用例
import unittest
from api.employee import EmployeeAPI
#创建测试类
class TestEmployee(unittest.TestCase):
employee_id=None
#前置处理方法
def setUp(self):
self.employee_api=EmployeeAPI() #实例化下封装好的【员工管理】模块类,准备调用
#添加员工测试用例设计
def test01_add_employee(self):
add_employee_data={
"username": "mike0709t2", #用户唯一
"mobile": "13212342367", #手机号唯一
"timeOfEntry": "2020-07-09",
"formOfEmployment": 1,
"workNumber": "124312", #员工id唯一
"departmentName": "销售",
"departmentId": "1266699057968001024",
"correctionTime": "2020-07-30T16:00:00.000Z"
}
#获取响应结果
response=self.employee_api.add_employee(add_employee_data=add_employee_data)
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(True,response.json().get("success"))
self.assertEqual(10000, response.json().get("code"))
self.assertIn("操作成功", response.json().get("message"))
#提取员工ID
TestEmployee.employee_id=response.json().get("data").get("id")
print(TestEmployee.employee_id)
# 修改员工测试用例设计
def test02_updata_employee(self):
update_employee_data = {"username": "mike7676"}
# 获取响应结果
response = self.employee_api.update_employee(TestEmployee.employee_id,update_data=update_employee_data)
print(response.json())
# 添加断言
self.assertEqual(200, response.status_code)
self.assertEqual(True, response.json().get("success"))
self.assertEqual(10000, response.json().get("code"))
self.assertIn("操作成功", response.json().get("message"))
2.3 查询员工
修改员工接口说明
接口地址:http://ihrm-test.itheima.net/api/sys/user{}" #{}里是后面要拼接员工ID
请求方式:GET
请求参数:
header:
{"Content-Type":"application/json","Authorization":"Bearer xxx-xxx"}
封装接口
#导包
import requests
import app
#创建接口类
class EmployeeAPI():
#初始化
def __init__(self):
self.url_add_employee="http://ihrm-test.itheima.net/api/sys/user"
#修改员工地址要接员工ID,通过{}占位符站位,后期通过 format 拼接
self.url_update_employee="http://ihrm-test.itheima.net/api/sys/user/{}"
self.url_select_employee = "http://ihrm-test.itheima.net/api/sys/user/{}"
self.url_delete_employee = "http://ihrm-test.itheima.net/api/sys/user/{}"
# 1.添加员工
def add_employee(self,add_employee_data):
return requests.post(url=self.url_add_employee,json=add_employee_data,headers=app.headers_data)
# 2,修改员工
def update_employee(self,employee_id,update_data):
url=self.url_update_employee.format(employee_id)
return requests.put(url=url,json=update_data,headers=app.headers_data)
# 3,查询员工
def select_employee(self,employee_id):
url=self.url_select_employee.format(employee_id)
return requests.get(url=url,header=app.headers_data)
定义用例
import unittest
from api.employee import EmployeeAPI
#创建测试类
class TestEmployee(unittest.TestCase):
employee_id=None
#前置处理方法
def setUp(self):
self.employee_api=EmployeeAPI() #实例化下封装好的【员工管理】模块类,准备调用
#添加员工测试用例设计
def test01_add_employee(self):
add_employee_data={
"username": "mike0709t2", #用户唯一
"mobile": "13212342367", #手机号唯一
"timeOfEntry": "2020-07-09",
"formOfEmployment": 1,
"workNumber": "124312", #员工id唯一
"departmentName": "销售",
"departmentId": "1266699057968001024",
"correctionTime": "2020-07-30T16:00:00.000Z"
}
#获取响应结果
response=self.employee_api.add_employee(add_employee_data=add_employee_data)
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(True,response.json().get("success"))
self.assertEqual(10000, response.json().get("code"))
self.assertIn("操作成功", response.json().get("message"))
#提取员工ID
TestEmployee.employee_id=response.json().get("data").get("id")
print(TestEmployee.employee_id)
# 修改员工测试用例设计
def test02_updata_employee(self):
update_employee_data = {"username": "mike7676"}
# 获取响应结果
response = self.employee_api.update_employee(TestEmployee.employee_id,update_data=update_employee_data)
print(response.json())
# 添加断言
self.assertEqual(200, response.status_code)
self.assertEqual(True, response.json().get("success"))
self.assertEqual(10000, response.json().get("code"))
self.assertIn("操作成功", response.json().get("message"))
# 查询员工测试用例设计
def test03_select_employee(self):
# 获取响应结果
response = self.employee_api.select_employee(TestEmployee.employee_id)
print(response.json())
# 添加断言
self.assertEqual(200, response.status_code)
self.assertEqual(True, response.json().get("success"))
self.assertEqual(10000, response.json().get("code"))
self.assertIn("操作成功", response.json().get("message"))
2.4删除员工
删除员工接口说明
接口地址:http://ihrm-test.itheima.net/api/sys/user{}" #{}里是后面要拼接员工ID
请求方式:DELETE
请求参数:
header:
{"Content-Type":"application/json","Authorization":"Bearer xxx-xxx"}
封装接口
#导包
import requests
import app
#创建接口类
class EmployeeAPI():
#初始化
def __init__(self):
self.url_add_employee="http://ihrm-test.itheima.net/api/sys/user"
#修改员工地址要接员工ID,通过{}占位符站位,后期通过 format 拼接
self.url_update_employee="http://ihrm-test.itheima.net/api/sys/user/{}"
self.url_select_employee = "http://ihrm-test.itheima.net/api/sys/user/{}"
self.url_delete_employee = "http://ihrm-test.itheima.net/api/sys/user/{}"
# 1.添加员工
def add_employee(self,add_employee_data):
return requests.post(url=self.url_add_employee,json=add_employee_data,headers=app.headers_data)
# 2,修改员工
def update_employee(self,employee_id,update_data):
url=self.url_update_employee.format(employee_id)
return requests.put(url=url,json=update_data,headers=app.headers_data)
# 3,查询员工
def select_employee(self,employee_id):
url=self.url_select_employee.format(employee_id)
return requests.get(url=url,header=app.headers_data)
# 4,删除员工
def delete_employee(self,employee_id):
url = self.url_delete_employee.format(employee_id)
return requests.delete(url=url,header=app.headers_data)
定义用例
import unittest
from api.employee import EmployeeAPI
#创建测试类
class TestEmployee(unittest.TestCase):
employee_id=None
#前置处理方法
def setUp(self):
self.employee_api=EmployeeAPI() #实例化下封装好的【员工管理】模块类,准备调用
#添加员工测试用例设计
def test01_add_employee(self):
add_employee_data={
"username": "mike0709t2", #用户唯一
"mobile": "13212342367", #手机号唯一
"timeOfEntry": "2020-07-09",
"formOfEmployment": 1,
"workNumber": "124312", #员工id唯一
"departmentName": "销售",
"departmentId": "1266699057968001024",
"correctionTime": "2020-07-30T16:00:00.000Z"
}
#获取响应结果
response=self.employee_api.add_employee(add_employee_data=add_employee_data)
print(response.json())
#添加断言
self.assertEqual(200,response.status_code)
self.assertEqual(True,response.json().get("success"))
self.assertEqual(10000, response.json().get("code"))
self.assertIn("操作成功", response.json().get("message"))
#提取员工ID
TestEmployee.employee_id=response.json().get("data").get("id")
print(TestEmployee.employee_id)
# 修改员工测试用例设计
def test02_updata_employee(self):
update_employee_data = {"username": "mike7676"}
# 获取响应结果
response = self.employee_api.update_employee(TestEmployee.employee_id,update_data=update_employee_data)
print(response.json())
# 添加断言
self.assertEqual(200, response.status_code)
self.assertEqual(True, response.json().get("success"))
self.assertEqual(10000, response.json().get("code"))
self.assertIn("操作成功", response.json().get("message"))
# 查询员工测试用例设计
def test03_select_employee(self):
# 获取响应结果
response = self.employee_api.select_employee(TestEmployee.employee_id)
print(response.json())
# 添加断言
self.assertEqual(200, response.status_code)
self.assertEqual(True, response.json().get("success"))
self.assertEqual(10000, response.json().get("code"))
self.assertIn("操作成功", response.json().get("message"))
# 删除员工测试用例设计
def test04_delete_employee(self):
# 获取响应结果
response = self.employee_api.delete_employee(TestEmployee.employee_id)
print(response.json())
# 添加断言
self.assertEqual(200, response.status_code)
self.assertEqual(True, response.json().get("success"))
self.assertEqual(10000, response.json().get("code"))
self.assertIn("操作成功", response.json().get("message"))
2.5 封装公共断言方法
- 在untils.py文件中封装一个公共断言方法
# 公共断言方法
def common_assert(case,response,status_code,success,code,message):
case.assertEqual(status_code, response.status_code)
case.assertEqual(success, response.json().get("success"))
case.assertEqual(code, response.json().get(""))
case.assertIn(message, response.json().get("message"))
#或者给参数设置默认值
def common_assert(case, response, status_code=200, success=True, code=10000, message="操作成功"):
case.assertEqual(status_code, response.status_code)
case.assertEqual(success, response.json().get("success"))
case.assertEqual(code, response.json().get("code"))
case.assertIn(message, response.json().get("message"))
- 用例调用
import unittest
from api.employee import EmployeeAPI
from utils import common_assert
#创建测试类
class TestEmployee(unittest.TestCase):
employee_id=None
#前置处理方法
def setUp(self):
self.employee_api=EmployeeAPI() #实例化下封装好的【员工管理】模块类,准备调用
#添加员工测试用例设计
def test01_add_employee(self):
add_employee_data={
"username": "mike0709t2", #用户唯一
"mobile": "13212342367", #手机号唯一
"timeOfEntry": "2020-07-09",
"formOfEmployment": 1,
"workNumber": "124312", #员工id唯一
"departmentName": "销售",
"departmentId": "1266699057968001024",
"correctionTime": "2020-07-30T16:00:00.000Z"
}
#获取响应结果
response=self.employee_api.add_employee(add_employee_data=add_employee_data)
print(response.json())
#添加断言
# self.assertEqual(200,response.status_code)
# self.assertEqual(True,response.json().get("success"))
# self.assertEqual(10000, response.json().get("code"))
# self.assertIn("操作成功", response.json().get("message"))
common_assert(self,response,200,True,10000,"操作成功")
#提取员工ID
TestEmployee.employee_id=response.json().get("data").get("id")
print(TestEmployee.employee_id)
# 修改员工测试用例设计
def test02_updata_employee(self):
update_employee_data = {"username": "mike7676"}
# 获取响应结果
response = self.employee_api.update_employee(TestEmployee.employee_id,update_data=update_employee_data)
print(response.json())
# 添加断言
common_assert(self, response, 200, True, 10000, "操作成功")
# 查询员工测试用例设计
def test03_select_employee(self):
# 获取响应结果
response = self.employee_api.select_employee(TestEmployee.employee_id)
print(response.json())
# 添加断言
common_assert(self, response, 200, True, 10000, "操作成功")
# 删除员工测试用例设计
def test04_delete_employee(self):
# 获取响应结果
response = self.employee_api.delete_employee(TestEmployee.employee_id)
print(response.json())
# 添加断言
common_assert(self, response, 200, True, 10000, "操作成功")
2.6 生成测试报告
- 设计:
#先去执行TestLogin1类下的test01_case001方法---获取token,解决依赖关系
suite.addTest(TestLogin1("test01_case001"))
suite.addTest(unittest.makeSuite(TestEmployee))
- 运行 run_suite.py
#导包
import time
import unittest
from script.test01_login import TestLogin
from script.test03_login_token import TestLogin1
from script.test04_employee import TestEmployee
from tools.HTMLTestRunner import HTMLTestRunner
#组装测试套件
suite=unittest.TestSuite()
#登录接口测试用例
suite.addTest(unittest.makeSuite(TestLogin))
#用工管理场景测试用例
suite.addTest(TestLogin1("test01_case001")) #先去执行TestLogin1类下的test01_case001方法---获取token
suite.addTest(unittest.makeSuite(TestEmployee))
#指定测试报告的路径
report="./report/report.html".format(time.strftime("%Y%m%d-%H%M%S"))
#打开文件流
with open(report, "wb") as f:
# 创建HTMLTestRunner执行器
runner = HTMLTestRunner(f, title="接口测试报告")
# 执行测试套件
runner.run(suite)