目录
目录
一、数据驱动介绍
数据驱动,我的理解,说的简单一点,就是数据测试数据的参数化。
二、DDT基本使用介绍
2.0 测试基类
class Test:
def __init__(self, a, b):
self.a = a
self.b = b
def add(self):
return self.a + self.b
def sub(self):
return self.a - self.b
def multi(self):
return self.a * self.b
def div(self):
return self.a / self.b
2.1 使用步骤
- 导包
from ddt import ddt, data, unpack
- 使用ddt
2.1 ddt读取单个数据
这种方式应用的不多
2.2.1 案例
@ddt
class TestExample0428(unittest.TestCase):
def setUp(self):
pass
@data(1, 2, 3)
def test_add(self, *args, **kwargs):
print(*args)
打印3次,分别为1, 2, 3
2.2 ddt读取组合中的数据(@unpack)
这种方式是较为常见的方式,可以实现多参数用例的参数化
2.2.1 加unpack
@ddt
class TestExample0428(unittest.TestCase):
def setUp(self):
pass
@data((1, 2, 3), (2, 3, 5), (1, 1, 1))
@unpack
def test_dict(self, *args, **kwargs):
print("开始打印数据")
# print(*args, **kwargs)
print(*args)
打印结果
开始打印数据
1 2 3
开始打印数据
2 3 5
开始打印数据
1 1 1
2.2.2 不加unpack
@ddt
class TestExample0428(unittest.TestCase):
def setUp(self):
pass
@data((1, 2, 3), (2, 3, 5), (1, 1, 1))
def test_dict(self, *args, **kwargs):
print("开始打印数据")
# print(*args, **kwargs)
print(*args)
打印结果
开始打印数据
(1, 2, 3)
开始打印数据
(2, 3, 5)
开始打印数据
(1, 1, 1)
2.3 读取字典
@ddt
class TestExample0428(unittest.TestCase):
def setUp(self):
pass
@data({"name":"gupan", "length":"170cm"}, {"age":"12"})
def test_dict(self, *args, **kwargs):
print("开始打印数据")
print(*args, **kwargs)
打印结果
开始打印数据
{'name': 'gupan', 'length': '170cm'}
开始打印数据
{'age': '12'}
三、DDT和Excel结合
3.1 excel解析类写法
# -*- coding:utf-8 -*-
# __author__ = 'gupan'
from config import settings
import os
import sys
from src.utils import utils
import xlrd
import traceback
class ExcelParse:
"""
EXCEL解析类
self.file_path:测试数据存放路径
self.workbook:打开的excel对象
self.sheet_obj:打开的表单对象
self.nrows:表单有数据的行数
self.ncols:表单有数据的列数
__init__(self, file_path):
aquire_cell_data(self, row, col):获取一个单元格的数据,不需要-1
heads(self, *args, **kwargs):获取测试数据表头
aquire_methodName_col(self):获取测试方法名
aquire_each_col_type(self):获取每一个数据列的数据类型
datas(self, *args, **kwargs):获取所有的测试数据,根据方法名按字典存储
"""
def __init__(self, file_path):
'''
:param file_path: 测试数据存放路径
'''
self.file_path = file_path
if not os.path.exists(self.file_path):
utils.print_log_error(self.file_path + "不存在,请确认路径!!!!!")
sys.exit(1)
try:
self.workbook = xlrd.open_workbook(self.file_path)
except Exception as err:
utils.print_log_error("文件应为xls格式的数据\n")
utils.print_log_error(traceback.format_exc())
raise err
# 默认一个Excel表中只存储一个表单,并且,所以只需要获取第一个表单即可
self.sheet_obj = self.workbook.sheets()[0]
# 获取表单行数
self.nrows = self.sheet_obj.nrows
# 获取表单列数
self.ncols = self.sheet_obj.ncols
if self.nrows == 1 or self.ncols == 0:
utils.print_log_error(file_path + "表单为空,请填写测试数据!!!!!")
sys.exit(1)
def aquire_cell_data(self, row, col):
'''
获取单元格数据
:param row: 单元格所在行数(不必主动-1)
:param col: 单元格所在列数(不必主动-1)
:return: 该单元格数据(str类型)
'''
return self.sheet_obj.cell_value(row - 1,col - 1)
def heads(self, *args, **kwargs):
'''
获取表头
:param args:
:param kwargs:
:return: 表头列表
'''
heads_info = []
for col in range(0, self.ncols):
heads_info.append(self.sheet_obj.cell_value(0, col))
return heads_info
def aquire_methodName_col(self):
'''
获取测试方法名锁占据的列数
:return: 测试方法名存放路径
'''
heads = self.heads()
try:
idx = heads.index(settings.method_desc)
except IndexError as err:
utils.print_log_error(self.file_path+"中不存在"+settings.method_desc + '\n')
utils.print_log_error(traceback.format_exc())
raise err
return idx
def aquire_each_col_type(self):
'''
获取测试方法名锁占据的列数
:return: 获取每一个数据列的数据类型,以列表形式返回
'''
col_type_desc_list = []
for col in range(0, self.ncols):
col_type_desc_list.append(self.sheet_obj.cell_value(settings.desc_type_row - 1, col))
return col_type_desc_list
def datas(self, *args, **kwargs):
'''
获取测试数据,根据测试方法名按字典返回
:param args:
:param kwargs:
:return: 字典格式的测试数据,每一个测试方法名对应的key值为列表形式
'''
test_datas = {}
# 测试数据开始数据列数
data_begin_col = settings.data_begin_col - 1
# 获取测试开始数据行数
data_begin_row = settings.data_begin_row - 1
# 获取每一列数据对应的数据类型列表
type_list = self.aquire_each_col_type()
# 测试测试方法名所在列数
method_col = self.aquire_methodName_col()
# 初始化测试方法名字
pre_method_name = self.sheet_obj.cell_value(data_begin_row, method_col)
# 存储一个method的测试数据
method_datas = []
method_count = 0
# 表头无测试数据,去除表头
for row in range(settings.data_begin_row - 1, self.nrows):
row_data = []
cur_method_name = self.sheet_obj.cell_value(row, method_col)
# 开始获取数据
for col in range(data_begin_col, self.ncols):
type_desc = type_list[col]
cell_data = self.sheet_obj.cell_value(row, col)
cell_data = utils.type_switch(cell_data, type_desc)
row_data.append(cell_data)
if pre_method_name == cur_method_name:
method_datas.append(row_data)
method_count += 1
else:
test_datas[pre_method_name] = method_datas.copy()
# 测试方法改变后,测试数据前置条件清空
method_datas.clear()
method_count = 0
pre_method_name = cur_method_name
method_datas.append(row_data)
# 不为0表示有些数据没有加上去
if method_count != 0:
test_datas[pre_method_name] = method_datas
return test_datas
3.2 ddt和excel结合案例
@ddt
class TestExample0428(unittest.TestCase):
def setUp(self):
pass
@data(*test_datas['test_add'])
@unpack
def test_add(self, *args, **kwargs):
p1, p2, value = args
result = Test(p1, p2).add()
try:
self.assertEqual(result, value, "加法错误,请重新输入")
utils.print_log_info("加法测试成功")
except AssertionError as err:
err_str = traceback.format_exc()
utils.print_log_error(err_str)
raise err
测试结果
test_add_1__2__2__4_ (src.test.case.testExample.TestExample0428) ... 加法测试成功
ok
加法测试成功
test_add_2__2__2__4_ (src.test.case.testExample.TestExample0428) ... ok
加法测试成功
test_add_3__3__3__6_ (src.test.case.testExample.TestExample0428) ... ok
加法测试成功
test_add_4__4__4__8_ (src.test.case.testExample.TestExample0428) ... ok
test_dict (src.test.case.testExample.TestExample0428) ... ok
test_div (src.test.case.testExample.TestExample0428) ... ok
test_multi (src.test.case.testExample.TestExample0428) ... ok
test_sub (src.test.case.testExample.TestExample0428) ... ok