进行接口测试的方法多种多样,例如使用 postman 、Jmeter 等工具进行接口测试;也可以通过编写代码的方式进行接口测试,生成测试报告。
使用编写代码的方式进行接口测试,通常一个测试用例,需要进行正常、异常多个场景的测试,每个场景,需要用到不同的测试数据,一般情况下,会通过使用数据驱动测试实现不同数据运行同一个测试用例。 测试数据的管理,也有多种方式,比如 yaml 文件、py 文件,有些情况下,会用到表格类型的文件,如 excel 表格、csv 文件等等
这里简要介绍 DDT+Excel 进行接口测试
DDT简介
Data-Driven Tests (DDT)即数据驱动测试
DDT的优点:
- 避免编写重复代码
- 数据与测试脚本分离
- 通过使用数据驱动测试,来验证多组数据测试场景
DDT本质是装饰器,一组数据一个场景。
框架结构

接口测试内容
通常,进行接口测试,需要考虑以下几点:请求的url地址、请求方式、请求参数、响应内容
例:
url:http://192.168.31.111:8080/api/user/verify_phone
method:post
params:
{phone_num:15912349876}
response:
{ "success":true,
"code": 2000,
"msg":"手机号格式正确"
}
{ "success":false,
"code": 2001,
"msg":"输入手机号长度非11位"
}
路径配置
dir_config.py
import os
base_dir = os.path.split(os.path.split(os.path.abspath(__file__))[0])[0]
testdatas_dir = os.path.join(base_dir,"test_datas")
testcases_dir = os.path.join(base_dir,"test_cases")
htmlreport_dir = os.path.join(base_dir,"reports")
excel处理封装
详细解析,可查看该篇文章:Python封装excel操作
excel_handler.py
from openpyxl import load_workbook
from openpyxl.worksheet.worksheet import Worksheet
class ExcelHandler():
'''
操作Excel
'''
def __init__(self, file):
'''初始化函数'''
self.file = file
def open_sheet(self, sheet_name) -> Worksheet:
'''打开表单'''
wb = load_workbook(self.file)
sheet = wb[sheet_name]
return sheet
def read_header(self, sheet_name):
'''获取表单的表头'''
sheet = self.open_sheet(sheet_name)
headers = []
for i in sheet[1]:
headers.append(i.value)
return headers
def read_rows(self,sheet_name):
'''
读取除表头外所有数据(除第一行外的所有数据)
返回的内容是一个二维列表,若想获取每一行的数据,可使用for循环或*解包
'''
sheet = self.open_sheet(sheet_name)
rows = list(sheet.rows)[1:]
data = []
for row in rows:
row_data = []
for cell in row:
row_data.append(cell.value)
data.append(row_data)
return data
def read_key_value(self,sheet_name):
'''
获取所有数据,且将表头中的内容与数据结合展示(以字典的形式)
'''
sheet = self.open_sheet(sheet_name)
rows = list(sheet.rows)
data = []
for row in rows[1:]:
rwo_data = []
for cell in row:
rwo_data.append(cell.value)
data_dict = dict(zip(self.read_header(sheet_name),rwo_data))
data.append(data_dict)
return data
@staticmethod
def write_change(file,sheet_name,row,column,data):
'''写入Excel数据'''
wb = load_workbook(file)
sheet = wb[sheet_name]
sheet.cell(row,column).value = data
wb.save(file)
wb.close()
requests请求封装
详细解析,可查看该篇文章:接口请求封装
RequestsHandler.py
import requests
class HTTPHandler:
def __init__(self):
self.session = requests.Session()
def visit(self, url, method, params=None, data=None, json=None, **kwargs):
if method.lower() == 'get':
res = self.session.get(url=url, params=params, **kwargs)
elif method.lower() == 'post':
res = self.session.post(url=url, params=params, data=data, json=json, **kwargs)
try:
return res.json()
except ValueError:
print('return not json')
测试用例
测试数据

测试用例文件
test_user.py
import unittest
import os
import ddt
from TEST.common.RequestHandler import HTTPHandler
from TEST.common.excel_handler import ExcelHandler
from TEST.common import dir_config
test_data = ExcelHandler(os.path.join(dir_config.testdatas_dir,"data.xlsx")).read_key_value("Sheet1")
@ddt.ddt
class Test_Verify_Code(unittest.TestCase):
def setUp(self) -> None:
pass
def tearDown(self) -> None:
pass
@ddt.data(*test_data)
def test_verify_phone(self,test_data):
res = HTTPHandler().visit(test_data["url"],test_data["method"],json=test_data["phonenum"])
self.assertEqual(res["code"],test_data["excepted"])
通过调用 ExcelHandler 类中的read_key_value 方法,读取excel文件数据,将其转换成列表,列表里的每一个元素都是一组字典格式的测试数据
[
{'url': 'http://192.168.31.111:8080/api/user/verify_phone', 'method': 'post', 'phonenum': 17761523654, 'excepted': 2004},
{'url': 'http://192.168.31.111:8080/api/user/verify_phone', 'method': 'post', 'phonenum': 123, 'excepted': 2004},
{'url': 'http://192.168.31.111:8080/api/user/verify_phone', 'method': 'post', 'phonenum': '测试', 'excepted': 2004},
{'url': 'http://192.168.31.111:8080/api/user/verify_phone', 'method': 'post', 'phonenum': 'test', 'excepted': 2004}
]
通过 ddt 进行解包处理,读取每一组测试数据,通过调用 HTTPHandler 类中的visit 方法,读取每一组测试数据例的内容,请求接口,将响应的内容一一比对
执行文件
run_case.py
import os
import time
import unittest
from TEST.common import dir_config
from TEST.common.HTMLTestRunnerNew import HTMLTestRunner
from TEST.test_cases import test_user
testloader = unittest.TestLoader()
suit_total = testloader.discover(dir_config.testcases_dir)
curTime = time.strftime("%Y-%m-%d %H_%M", time.localtime())
file_path = os.path.join(dir_config.htmlreport_dir,'{}_test.html'.format(curTime))
with open(file_path,"wb") as f:
runner = HTMLTestRunner(f,title='测试报告',description='测试报告内容为:',tester='bobo')
runner.run(suit_total)
执行文件,生成测试报告

|