zoukankan      html  css  js  c++  java
  • unittest+ddt 实现数据驱动

     1 @ddt
     2 class RegisterTestCase(unittest.TestCase):
     3     cases = [
     4         {"title": "注册成功", "excepted": {"code": 1, "msg": "注册成功"}, "data": ['python1', '123456', '123456']},
     5         {"title": "密码不一致", "excepted": {"code": 0, "msg": "两次密码不一致"}, "data": ['python12', '1234567', '123456']},
     6         {"title": "账户已存在", "excepted": {"code": 0, "msg": "该账户已存在"}, "data": ['python26', '1234567', '123456']}
     7     ]
     8 
     9     @data(*cases)
    10     def test_register(self, case):
    11         # pass
    12         # print("用例方法中打印的case:", case)
    13 
    14         # 1、准备用例参数
    15         expected = case["excepted"]
    16         data = case["data"]
    17         # 2:调用被测试的功能函数,传入参数,获取实际结果:
    18         res = register(*data)
    19         # 3:断言(比对预期结果和实际结果)
    20         self.assertEqual(expected, res)
    21 
    22 
    23 print("------------------")

    @ddt  类级装饰器

    @data  方法级装饰器,这里不对装饰器进行展开,

    具体掌握用法即可,

    @ddt加在测试用例类头上,@data加载测试方法上

    @data(用例参数集对象) 参数集前加 " * " 是为了拆包,将参数集遍历拆分导入,

    然后测试方法中使用case形参接收,并在测试方法内使用。

     

    针对ddt的优化,

    原始的ddt库执行出来的测试报告中没有针对用例的详细描述。,

    对此可以二次开发在ddt中进行方法扩展

     for name, func in list(cls.__dict__.items()):
            if hasattr(func, DATA_ATTR):
                for i, v in enumerate(getattr(func, DATA_ATTR)):
                    test_name = mk_test_name(name, getattr(v, "__name__", v), i)
                    # 将用例的描述信息,改为用例数据的title字段
                    # 在此处进行修改之后,就可以吧详情返回到测试报告中
                    test_data_docstring = v["title"]
                    if hasattr(func, UNPACK_ATTR):
                        if isinstance(v, tuple) or isinstance(v, list):
                            add_test(
                                cls,
                                test_name,
                                test_data_docstring,
                                func,
                                *v
                            )
                        else:
                            # unpack dictionary
                            add_test(
                                cls,
                                test_name,
                                test_data_docstring,
                                func,
                                **v
                            )
                    else:
                        add_test(cls, test_name, test_data_docstring, func, v)
                delattr(cls, name)
            elif hasattr(func, FILE_ATTR):
                file_attr = getattr(func, FILE_ATTR)
                process_file_data(cls, name, func, file_attr)
                delattr(cls, name)
        return cls

    python操作excel

    此操作将用到openpyxl第三方库,事前应当pip install一下,

    # 首先将指定的excel,加载为一个workbook对象
    wb = openpyxl,load_workbook('case.xlsx')
    # 选中工作簿中的表单对象即sheet
    sh = wb["addicated"]
    # 常用的方法
    cell = sh.cell(row=1,column=3) # 读取指定列的各自对象
    c12 = cell.value  # 得到格子中的数据
    max_row = sh.max_row  # 获得表单最大行数
    max_column = sh.max_column  # 获得表单最大列数 
    # rows 按行获取表单中所有的各自对象,每行的内容,放在一个元祖中
    res = list(sh.rows)  # sh.rows 返回为元祖,强转为list,内部元素为格子对象
    for item in res1:
         for j in item:
            print(j.value)
    [(<Cell 'musen'.A1>, <Cell 'musen'.B1>, <Cell 'musen'.C1>, <Cell 'musen'.D1>),
     (<Cell 'musen'.A2>, <Cell 'musen'.B2>, <Cell 'musen'.C2>, <Cell 'musen'.D2>),
     (<Cell 'musen'.A3>, <Cell 'musen'.B3>, <Cell 'musen'.C3>, <Cell 'musen'.D3>)
    ]
    # columns 按列获取表单中所有格子对象,每列内容,放在一个元祖中
    res = list(sh.columns)
    # 需求:读取第三行的数据
    # res = list(sh.rows)
    # print(res[2])
    # 需求:读取第二列到第四列的内容
    # res1 = list(sh.columns)
    # print(res1[1:4])
    # 写入数据的操作
    # sh.cell(row=3, column=2, value="python")
    # # 将工作簿对象保存为文件
    # wb.save("cases.xlsx")  # 一定要保存
    @ddt
    class RegisterTestCase(unittest.TestCase):
        cases = [
            {"title": "注册成功", "excepted": {"code": 1, "msg": "注册成功"}, "data": ['python1', '123456', '123456']},
            {"title": "密码不一致", "excepted": {"code": 0, "msg": "两次密码不一致"}, "data": ['python12', '1234567', '123456']},
            {"title": "账户已存在", "excepted": {"code": 0, "msg": "该账户已存在"}, "data": ['python26', '1234567', '123456']}
        ]
        @data(*cases)
        def test_register(self, case):
            # pass
            # print("用例方法中打印的case:", case)
            # 1、准备用例参数
            expected = case["excepted"]
            data = case["data"]
            # 2:调用被测试的功能函数,传入参数,获取实际结果:
            res = register(*data)
            # 3:断言(比对预期结果和实际结果)
            self.assertEqual(expected, res)
    print("------------------")
     
  • 相关阅读:
    ExtJS专题(十):layout布局的使用(3)
    ExtJS专题(十一):lTree的Treepanel使用
    ExtJS专题(四):ExtJS组件的属性
    ExtJS专题(七):ExtJS面板Panel中视图区ViewPort的使用
    ExtJS专题(二):ExtJS类库和组件介绍
    ExtJS专题(十):layout布局的使用(1)
    EXtJS专题(九):ExtJS对话框的使用
    ExtJS专题(五):ExtJS面板Panel的使用
    ExtJS专题(三):ExtJS组件的使用
    ExtJS专题(八):ExtJS窗口Window的使用
  • 原文地址:https://www.cnblogs.com/addicated/p/13194381.html
Copyright © 2011-2022 走看看