首先已安装ddt库
pip install ddt
一、为什么要做参数化
当我们在编写测试代码时,往往会遇到类似但稍有不同的测试场景。为了避免重复编写大量相似的测试代码,并提高代码的可读性和维护性,可以使用参数化。
二、举例
假设我们需要测试两个数相加的功能。我们需要编写多个测试用例来验证该功能是否正常工作。
传统的方式是针对每个测试用例编写一个独立的方法,这样会产生大量重复的代码。
例如:
import unittest
def add(a, b):
return a + b
class Test(unittest.TestCase):
def test_addition_1(self):
result = add(2, 3)
self.assertEqual(result, 5)
def test_addition_2(self):
result = add(0, 0)
self.assertEqual(result, 0)
def test_addition_3(self):
result = add(-5, 5)
self.assertEqual(result, 0)
if __name__ == "__main__":
unittest.main()
我们会发现上面示例中有大量重复的代码,我们可以把相同的方法合并为一个方法,把被测数据抽离出来作为参数化数据用例。
参数化示例如下:
import unittest
from ddt import ddt, data, unpack
def add(a, b):
return a + b
@ddt # 使用ddt装饰器
class Test(unittest.TestCase):
# 使用data装饰器定义参数化数据
@data(
(2, 3, 5),
(0, 0, 0),
(-5, 5, 0)
)
@unpack
# 修改测试方法名为test_addition,并接受三个参数:a、b和expected
def test_addition(self, a, b, expected):
result = add(a, b)
self.assertEqual(result, expected)
if __name__ == "__main__":
unittest.main()
在上述参数化示例中,我们首先导入了ddt
模块,并使用@ddt
装饰器将测试类标记为参数化。然后,在test_addition()
方法上使用了两个装饰器:@data
和@unpack
。
@data
装饰器用于指定多组测试数据,每组数据作为一个元组传递给被装饰的方法。在这个示例中,我们指定了三组数据(2, 3, 5)
、(0, 0 ,0)
和(-5, 5 ,0)
。@unpack
装饰器用于拆分元组,并将其作为多个参数传递给被装饰的方法。在这个示例中,每个元组都被拆分成了两个参数a
和b
,以及一个期望的结果expected
。
在测试过程中会根据传入的不同数据执行多次测试,并通过断言self.assertEqual(result, expected)
判断计算结果是否与预期一致。
三、ddt是什么
ddt
是一个用于 Python 单元测试的数据驱动测试(Data-Driven Testing)库。通过使用 ddt
可以轻松地在单个测试方法中运行多组输入和输出数据。
使用 ddt
可以避免编写大量重复代码来处理不同的测试数据情况。它提供了装饰器和装饰器参数,使得我们能够在测试方法中定义多组输入参数,并针对每组参数执行相同的断言逻辑。
通过使用 ddt
,可以更加灵活、高效地进行接口测试、函数测试等各种场景下的参数化测试。同时,它还可以结合其他单元测试框架(如 unittest、pytest 等)一起使用。
四、ddt
库中常用的函数方法
1、@ddt
: 这是一个装饰器函数,用于将测试方法标记为数据驱动测试。它可以应用于测试类或测试方法上。
@ddt # 使用ddt装饰器
class Test(unittest.TestCase):
# 使用data装饰器定义参数化数据
@data(
(2, 3, 5),
(0, 0, 0)
)
def test_addition(self, value):
# 测试逻辑
2、@data
: 这个装饰器函数用于指定测试数据,可以接受一个或多个参数作为输入数据。
# 使用data装饰器定义参数化数据
@data(
(2, 3, 5),
(0, 0, 0)
)
def test_addition(self, expected):
#测试逻辑
3、@file_data
: 这个装饰器函数用于从外部文件加载测试数据。可以从CSV、Excel等文件格式中读取数据,并将其传递给被装饰的测试方法。
@file_data("testdata.csv")
def test_data_from_csv(self, value):
# 测试逻辑
pass
@file_data("testdata.xlsx", sheet="Sheet1")
def test_data_from_excel(self, a, b):
# 测试逻辑
4、@unpack
: 如果测试数据是元组或列表形式,该装饰器函数可将其解包并将每个元素作为单独的参数传递给被装饰的测试方法。
@data(
(2, 3, 5),
(0, 0, 0),
(-5, 5, 0)
)
@unpack # 使用unpack将数据拆分为两个参数传递给测试方法
def test_addition(self, a, b, expected):
# 测试逻辑
5、@data_class
: 该装饰器函数用于从类属性中获取测试数据,类似于通过属性来定义静态变量。
@ddt
class MyTestCase(unittest.TestCase):
data = [(1, 2), (3, 4), (5, 6)]
@data_class(data)
@unpack
def test_addition(self, a, b):
# 测试逻辑