AI智能
改变未来

【python接口自动化】- DDT数据驱动测试


简单介绍

​ DDT(Date Driver Test),所谓数据驱动测试,简单来说就是由数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变。通过使用数据驱动测试的方法,可以在需要验证多组数据测试场景中,使用外部数据源实现对输入输出与期望值的参数化,避免在测试中使用硬编码的数据,也就是测试数据和用例脚本代码分离。

​ DDT它其实就是一个装饰器,它会根据你传递进来的数据来决定要生成几个测试用例。

​ ?使用的意义

1.代码复用率高:一个测试逻辑只需要写一次,可以多条测试数据复用,同时提高测试脚本的编写效率。

2.异常排查效率高:根据测试数据,每条数据生成一条测试用例,用例相互分离,一条失败的情况下不会影响其他测试用例。

3.代码可维护性高:简洁明了的测试框架,利于其他同事阅读,提高代码的可维护性。

安装及导入

​ cmd命令行执行安装:

pip install ddt

​ 直接导入到模块:

import ddt

,或导入具体的装饰器:

from ddt import ddt, data, unpack

ddt使用详解

​ ?三个要点

  • @ddt

    :装饰测试类

  • @data

    :装饰测试用例

  • @unpack

    :装饰测试用例

​ 要使用ddt的前提是要有测试用例类,然后用

@ddt

去装饰测试用例类,用

@data(测试数据)

去装饰测试用例,如下登录接口例子:

from ddt import ddt, datafrom common.read_excel import ReadExcelfrom common.my_logger import log@ddt  # 装饰登录测试用例类,声明使用ddtclass LoginTestCase(unittest.TestCase):excel = ReadExcel("cases.xlsx", "login")cases = excel.read_data()@data(*cases)	# 装饰测试用例def test_login(self, case):case_data = eval(case["data"])expected = eval(case["expected"])case_id = case["case_id"]result = login_check(*case_data)response = self.http.send(url=url, method=method, json=data, headers=headers)result = response.json()try:self.assertEqual(expected["code"], result["code"])self.assertEqual((expected["msg"]), result["msg"])except AssertionError as e:log.info("用例:{}--->执行未通过".format(case["title"]))print("预期结果:{}".format(expected))print("实际结果:{}".format(result))raise eelse:log.info("用例:{}--->执行通过".format(case["title"]))if __name__ == \'__main__\':unittest.main()

@ddt

它做的事情其实就等同于这句代码:

LoginTestCase = ddt(LoginTestCase)

,把具体的类名传给ddt,告诉ddt是这个测试用例类要使用数据驱动。

@data

做的事情就是把测试数据作为一个参数传递给测试用例,一个数据对应生成一条测试用例,如果data里面有多个数据那么就对应生成多条测试用例。如果data里放的类似是元组、列表等这样的序列类型的数据,data会把他们当成是一个整体,即一个测试数据。

​ 如果想一次传递多个参数给测试用例,需要自行在脚本中对数据进行分解或者使用

@unpack

分解数据。如上例子中的测试用例,只使用了一个参数,但这个参数case是一个字典,字典中已经包含多个数据,直接用key获取对应的值即可。

@unpack

则是可以把序列类型的数据拆分为多个,以多个参数传给测试用例,但测试用例也需要定义同等数量的参数来接收。

​ 上面例子的测试数据cases来源是使用了openpyxl来读取excel中的测试数据的,关于openpyxl可以看我这个系列的另外一篇随笔。这里直接说明cases其实就是像下面这样的一个列表:

cases = [{\'case_id\': 1, \'title\': \'正常登录\', \'data\': \'("test", "Test1234")\', \'expected\': \'{"code": 0, "msg": "登录成功"}\'}, {\'case_id\': 2, \'title\': \'密码错误\', \'data\': \'("test", "123")\', \'expected\': \'{"code": 1, "msg": "账号或密码不正确"}\'}, {\'case_id\': 3, \'title\': \'账户名错误\', \'data\': \'("test11", "Test1234")\', \'expected\': \'{"code": 1, "msg": "账号或密码不正确"}\'}]# *解包后,一个字典就是一个测试用例数据# 如第一个字典:{\'case_id\': 1, \'title\': \'正常登录\', \'data\': \'("test", "Test1234")\', \'expected\': \'{"code": 0, "msg": "登录成功"}\'}

​ 通过*解包,它的数据就是3个字典,每次给测试用例传入1个字典,而这个字典里就存放了一条完整的登录接口测试用例的测试数据,包括用例id、用例标题、测试的账号密码、期望返回的结果。

​ ?小结:

  • @data(a,b):a和b各运行一次用例
  • @data(*(a,b):a和b各运行一次用例,使用*解包,相当于**@data(a,b)**
  • @data([a,d],[c,d])如果没有
    @unpack

    [a,b]、[c,d]都会被当成一个参数传入用例,即用[a,b]运行一次,用[c,d]运行一次;

  • 如果有
    @unpack

    ,[a,b]会被分解开,一次传递两个参数给用例,用例需要定义两个参数接收

  • @unpack

    可适用元组、列表或字典,但当传入的是字典时,字典的key和用例定义的参数名需要保持一致

扩展

关键代码

@file_data

,传递文件(json/yaml)

# 传递json"""json文件数据{"token":123456,"actionName": "api.login","content": {"user": "miki","pwd": "Test123"}}""""""yaml文件test_list:- 11- 22- 12sorted_list: [ 11, 12, 22 ]"""from ddt import *@ddt	# 声明使用ddtclass TestFile(unittest.TestCase):@file_data(\'D:/test/test.json\')def test_json(self, json_data):print(json_data)@file_data(\'D:/test/test.yaml\')def test_yaml(self, yaml_data):print("yaml", yaml_data)
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 【python接口自动化】- DDT数据驱动测试