• python数据驱动-ddt


    目录

    一、数据驱动介绍

            数据驱动,我的理解,说的简单一点,就是数据测试数据的参数化。

    二、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 使用步骤

    1. 导包
    from ddt import ddt, data, unpack
    
    1. 使用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格式的数据
    ")
                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 + '
    ')
                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
    
  • 相关阅读:
    JavaScript函数之美~
    如何用iframe标签以及Javascript制作时钟?
    Hammer.js
    leadJS初构建
    SQLite-创建、附加、分离数据库
    Javascript异步编程的4种方法
    JavaScript的数组实现队列与堆栈的方法
    使用PHP创建一个REST API(译)
    HTTP API响应数据规范整理
    CMD 模块定义规范
  • 原文地址:https://www.cnblogs.com/gupan/p/8970044.html
Copyright © 2020-2023  润新知