- testcase文件夹:存放测试用例表;
- api文件夹:存放接口路径表;
- common文件夹:common文件中存放通用的数据处理的脚本,如data.py和utlis.py(主要作用是将表中的数据进行处理,后面会进行详细的说明)、config.py(测试套件的基本配置);
- report文件夹:用于存放测试完成后生成的测试报告;
- conftest.py:属于pytest的一种全局公用的文件,一些通用的方法可以放在conftest.py中;
- pytest.ini:pytest的配置文件;
2、测试的运行流程
触发自动化测试之后,测试数据的提取与处理并不会使用到pytest框架,当把数据处理为测试套件后,按模块分配给pytest进行执行,包括测试模块、http请求、断言。所有模块执行完之后将测试结果体现在生成的测试报告report.html中。测试结束之后可以通过邮件或者钉钉机器人的方式通知测试或开发本次自动化测试的测试结果。
测试用例的实现过程
现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036【暗号:csdn999】
下面简单介绍一下测试用例实现过程中部分脚本的作用。
1、读取excel表
使用xlrd库读取excel表中的内容,python中还有很多可以对excel的数据进行操作的库,如:openpyxl、xlsxwriter;循环遍历每一行的数据,保存为列表并赋值给self.list_data。
# -*- coding: utf-8 -*-
import xlrd
class Excel(object):
def __init__(self, file_name):
# 读取excel
self.wb = xlrd.open_workbook(file_name)
self.sh = self.wb.sheet_names()
self.list_data = []
def read(self):
for sheet_name in self.sh:
sheet = self.wb.sheet_by_name(sheet_name)
rows = sheet.nrows
for i in range(0, rows):
rowvalues = sheet.row_values(i)
self.list_data.append(rowvalues)
2、将数据格式化成测试套件
第一步将表格数据保存为列表后,还不是我们需要的数据格式,这样的数据列表不能直接使用,这里进行了一次数据的格式化。需要用到config.py中的case_header的配置,将中文的标题换成英文,并作为字典的key值。之后从第1个元素开始循环遍历data,将data中每个元素都以 [{‘key1’: ‘value1’, ‘key2’: ‘value2’}, {}, {}, …]的形式保存为list_dict_data并返回。
def data_to_dict(data):
"""
:param data: data_list
:return:
"""
head = []
list_dict_data = []
for d in data[0]:
d = case_header.get(d, d)
head.append(d)
for b in data[1:]:
dict_data = {}
for i in range(len(head)):
if isinstance(b[i], str):
dict_data[head[i]] = b[i].strip()
else:
dict_data[head[i]] = b[i]
list_dict_data.append(dict_data)
return list_dict_data
case_header = {
'测试模块': 'module',
'用例编号': 'id',
'用例标题': 'title',
'前置条件': 'condition',
'测试步骤': 'step',
'请求接口': 'api',
'请求方式': 'method',
'请求头部': 'headers',
'请求数据': 'data',
'断言': 'assert',
'步骤结果': 'score' }
3、生成可执行的测试套件
上一步已经将数据处理成[{‘key1’: ‘value1’, ‘key2’: ‘value2’}, {}, {}, …]的格式,但是发现这样的格式没有将模块中的用例整合到一起,列表中每一个元素都是单独的一条用例,这样的话不利于用例的执行,所以,对上一步返回的数据再进行一次处理。因为测试用例和接口路径是保存在两个excel表中,所以需要将两个表的数据合并。首先将接口路径表中的数据读取出来并处理成需要的格式 {‘key’: {‘type’: ‘value’, ‘url’: ‘value’}},之后按照测试步骤中的顺序把测试用例保存在steps字典中。由于代码过长,下面只展示核心部分。
for d in data:
# 将请求数据和断言数据格式化
for key in ('data', 'assert', 'headers'):
if d[key].strip():
test_data = dict()
for i in d[key].split(','):
i = i.split('=')
test_data[i[0]] = i[1]
d[key] = test_data
if d['module'].strip():
if testcase:
testsuite.append(testcase)
testcase = {}
testcase['module'] = d['module']
testcase['steps'] = []
no = str(d['step']).strip()
if no:
step = {'no': str(int(d['step']))}
for key in ('id', 'title', 'condition', 'api', 'headers', 'data', 'assert'):
if key == 'api':
step[key] = {'type': apis[d.get(key, '')]['type'],
'url': apis['baseurl']['url'] + apis[d.get(key, '')]['url']}
else:
step[key] = d.get(key, '')
testcase['steps'].append(step)
if testcase:
testsuite.append(testcase)
4、pytest执行测试套件
将http请求封装在conftest.py中,使用pytest数据驱动的特点,在执行测试文件test_login。py中不需要import就可以直接调用。这里只展示发起post请求的代码,其它类型请求类似,pytest.fixture通过固定参数request传递数据,用’标记’中的pytest.mark.parametrize进行参数化和数据驱动更灵活。在fixture中的方法里面准备测试数据和前置依赖方法,在测试方法中参数化,测试方法调用准备数据和前置方法。
pytest.mark.parametrize(‘post_request’, data, indirect=True),indirect=True是把post_request当作函数去执行,data则是前面生成的模块的测试用例,其中包括了发起\http请求所需要的所有参数。
@pytest.fixture()
def post_request(request):
data = request.param['data']
header = request.param['headers']
url = request.param['api']['url']
no = request.param['no']
logger.info(f'request: {data}')
response = requests.request('POST', url=url, headers=header, data=json.dumps(data))
logger.info(f'response: {response.json()}')
return response, no