目录
IHRM项目实战
学习目标
- 能够对IHRM系统中的登录接口实现接口对象的封装
- 能够对IHRM系统中的员工管理接口实现接口对象的封装
- 能够对IHRM系统中的登录接口实现测试脚本的编写(接口对象调用、断言)
- 能够对IHRM系统中的员工管理接口实现测试脚本的编写(接口对象调用、断言)
一、搭建接口测试框架
二、封装被测试系统接口
1 登录
# 导包
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 员工管理
# 导包
import app
import requests
# 创建接口类
class EmployeeAPI:
# 初始化
def __init__(self):
self.url_add_employee = app.BASE_URL + "/api/sys/user"
self.url_update_employee = app.BASE_URL + "/api/sys/user/{}"
self.url_get_employee = app.BASE_URL + "/api/sys/user/{}"
self.url_delete_employee = app.BASE_URL + "/api/sys/user/{}"
# 员工添加
def add_employee(self, add_employee_data):
return requests.post(url=self.url_add_employee, json=add_employee_data, headers=app.headers_data)
# 员工修改
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)
# 员工查询
def get_employee(self, employee_id):
url = self.url_update_employee.format(employee_id)
return requests.get(url=url, headers=app.headers_data)
# 员工删除
def delete_employee(self, employee_id):
url = self.url_update_employee.format(employee_id)
return requests.delete(url=url, headers=app.headers_data)
三、定义接口测试用例
1 登录
1.1 实现登陆成功
# 导包
import unittest
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"))
1.2 实现其他测试用1
# 导包
import unittest
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"))
# case002 不输入手机号
def test02_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 test03_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 test04_case004(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobile": "1380000000", "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 test05_case005(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobile": "138000000023", "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 test06_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 test07_case007(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobile": "13812321236", "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 test08_case008(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobile": "13800000002", "password": "123456", "haha": "xixi"})
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"))
# case009 少参-缺少手机号
def test09_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 test10_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 test11_case011(self):
# 调用登录接口进行登录
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 test12_case012(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobiel": "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 test13_case013(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobile": "13800000002", "passwd": "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 实现其他测试用2
# 导包
import app
import unittest
from api.login import LoginAPI
from utils import common_assert
# 创建测试类
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())
# 断言
common_assert(self, response, 200, True, 10000, "操作成功")
# 提取token信息
app.TOKEN = "Bearer " + response.json().get("data")
print(app.TOKEN)
app.headers_data["Authorization"] = app.TOKEN
print(app.headers_data["Authorization"])
# case002 不输入手机号
def test02_case002(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobile": "", "password": "123456"})
print(response.json())
# 断言
common_assert(self, response, 200, False, 20001, "用户名或密码错误")
# case003 不输入密码
def test03_case003(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobile": "13800000002", "password": ""})
print(response.json())
# 断言
common_assert(self, response, 200, False, 20001, "用户名或密码错误")
# case004 手机长度小于11位
def test04_case004(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobile": "1380000000", "password": "123456"})
print(response.json())
# 断言
common_assert(self, response, 200, False, 20001, "用户名或密码错误")
# case005 手机场地大于11位
def test05_case005(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobile": "138000000023", "password": "123456"})
print(response.json())
# 断言
common_assert(self, response, 200, False, 20001, "用户名或密码错误")
# case006 手机号输入非数字
def test06_case006(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobile": "error", "password": "123456"})
print(response.json())
# 断言
common_assert(self, response, 200, False, 20001, "用户名或密码错误")
# case007 输入未注册手机号
def test07_case007(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobile": "13812321236", "password": "123456"})
print(response.json())
# 断言
common_assert(self, response, 200, False, 20001, "用户名或密码错误")
# case008 多参
def test08_case008(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobile": "13800000002", "password": "123456", "haha": "xixi"})
print(response.json())
# 断言
common_assert(self, response, 200, True, 10000, "操作成功")
# case009 少参-缺少手机号
def test09_case009(self):
# 调用登录接口进行登录
response = self.login_api.login({"password": "123456"})
print(response.json())
# 断言
common_assert(self, response, 200, False, 20001, "用户名或密码错误")
# case010 少参-缺少密码
def test10_case010(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobile": "13800000002"})
print(response.json())
# 断言
common_assert(self, response, 200, False, 20001, "用户名或密码错误")
# case011 无参
def test11_case011(self):
# 调用登录接口进行登录
response = self.login_api.login(None)
print(response.json())
# 断言
common_assert(self, response, 200, False, 99999, "抱歉,系统繁忙")
# case012 错误参数-手机号
def test12_case012(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobiel": "13800000002", "password": "123456"})
print(response.json())
# 断言
common_assert(self, response, 200, False, 20001, "用户名或密码错误")
# case013 错误参数-密码
def test13_case013(self):
# 调用登录接口进行登录
response = self.login_api.login({"mobile": "13800000002", "passwd": "123456"})
print(response.json())
# 断言
common_assert(self, response, 200, False, 20001, "用户名或密码错误")
1.4 生成测试报告
# 导包
import time
import unittest
from scripts.test01_login import TestLogin
from scripts.test03_employee import TestEmployee
from tools.HTMLTestRunner import HTMLTestRunner
# 组装测试套件
suite = unittest.TestSuite()
# 登录接口测试用例
suite.addTest(unittest.makeSuite(TestLogin))
# 员工管理场景测试用例
suite.addTest(TestLogin("test01_case001"))
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="API Report")
# 执行测试套件
runner.run(suite)
1.5 参数化
login.json
[
{
"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():
# 指定文件路径
json_file = "../data/login.json"
# 打开json文件
test_data = []
with open(json_file, encoding="utf-8") as f:
json_data = json.load(f)
for case_data in json_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 = {}".format((login_data, status_code, success, code, message)))
return test_data
# 创建测试类
class TestLogin(unittest.TestCase):
# 前置处理
def setUp(self):
self.login_api = LoginAPI()
@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 员工管理
封装公共断言方法
# 公共断言方法
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
# employee_id = 1288061322868658176
# 前置处理
def setUp(self):
self.employee_api = EmployeeAPI()
# 添加员工测试用例设计
def test01_add_employee(self):
add_employee_data = {
"username": "jack0709t0728066", # 用户名唯一
"mobile": "13212072866", # 手机号唯一
"timeOfEntry": "2020-07-09",
"formOfEmployment": 1,
"workNumber": "072866", # 员工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, "操作成功")
common_assert(self, response) # 直接使用公共断言方法的默认值即可
# 提取员工ID
TestEmployee.employee_id = response.json().get("data").get("id")
print(TestEmployee.employee_id)
# 修改员工测试用例设计
def test02_update_employee(self):
update_employee_data = {"username": "rose0728"}
# 获取响应结果
response = self.employee_api.update_employee(TestEmployee.employee_id, update_data=update_employee_data)
print(response.json())
# 断言
common_assert(self, response) # 直接使用公共断言方法的默认值即可
# 查询员工测试用例设计
def test03_get_employee(self):
# 获取响应结果
response = self.employee_api.get_employee(TestEmployee.employee_id)
print(response.json())
# 断言
common_assert(self, response) # 直接使用公共断言方法的默认值即可
# 删除员工测试用例设计
def test04_delete_employee(self):
# 获取响应结果
response = self.employee_api.delete_employee(TestEmployee.employee_id)
print(response.json())
# 断言
common_assert(self, response) # 直接使用公共断言方法的默认值即可
生成测试报告
# 导包
import time
import unittest
from scripts.test01_login import TestLogin
from scripts.test03_employee import TestEmployee
from tools.HTMLTestRunner import HTMLTestRunner
# 组装测试套件
suite = unittest.TestSuite()
# 登录接口测试用例
suite.addTest(unittest.makeSuite(TestLogin))
# 员工管理场景测试用例
suite.addTest(TestLogin("test01_case001"))
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="API Report")
# 执行测试套件
runner.run(suite)