• 自动化测试之 ddt 驱动 excel 文件


    一、ddt 用途

    • 一般进行接口测试时,每个接口的传参都不止一种情况,一般会考虑正向、逆向等多种组合,所以在测试一个接口时,通常会编写多条 case,而这些除了传参不同外,并没有什么区别。这个时候就可以利用 ddt 来管理测试数据,提高代码复用率。
    • ddt => data driver test 数据驱动测试

    二、安装 ddt

    • pip install ddt
    三、ddt 模块组成
    • ddt.ddt:装饰类,也就是继承 TestCase 的类。

    • ddt.data:装饰测试方法,参数是一系列的值

    • ddt.unpack:用来拆解 data 的数据。通常 data 中包含的每一个值都会作为一个单独的参数传给测试方法,如果这些值是用元组或者列表传进来的,可以用 unpack 方法将其自动分解成多个参数
    • ddt.file_data:装饰测试方法,参数是文件名。文件可以是 json 或者 yaml 类型。

      • 注意:如果文件是以 “.yml”或者".yaml" 结尾,ddt 会作为 yaml 类型处理,其他文件都会作为 json 文件处理。  

      • 如果文件是列表,列表的值会作为测试用例参数,同时,会作为测试用例方法名后缀显示。  

      • 如果文件是字典,字典的 key 会作为测试用例方法的后缀显示,字典的 value 会作为测试用例参数。  
    四、示例
    • 使用 data 传参数给测试用例
      • 如下示例,可以看出 data 分别传参数 2 和 4 给测试用例,然后测试用例执行了两遍
    from ddt import ddt, data
    import unittest
    
    @ddt
    class MyTestDdt(unittest.TestCase):
        def setUp(self):
            print('start')
    
        @data(2, 4)  # 使用 data 传参数给测试用例
        def test_one(self,value):
            print('the @data number is {}'.format(value))
    
        def tearDown(self):
            print('end')
    
    if __name__ == '__main__':
        unittest.main()
    
    # 结果如下:
    start
    the @data number is :2
    end
    start
    the @data number is :4
    end
    • 使用 unpack 分解 list 或者 tuple
      • 可以看出 data 分别传元组参数(1,2)和(4,5)给测试用例,然后测试用例执行了两遍  
    from ddt import ddt, data, unpack
    import unittest
    
    @ddt
    class MyTestDdt(unittest.TestCase):
        def setUp(self):
            print('start')
    
        @data((1, 2), (4, 5))  # 元组
        @unpack  # 二次分解元组
        def test_one(self, value1, value2):
            print('the @data number is {} and {}'.format(value1, value2))
    
        def tearDown(self):
            print('end')
    
    if __name__ == '__main__':
        unittest.main()
    
    # 结果如下
    start
    the @data number is 1 and 2
    end
    start
    the @data number is 4 and 5
    end
    •  用 unpack 分解字典
    from ddt import ddt, data, unpack
    import unittest
    
    @ddt
    class MyTestDdt(unittest.TestCase):
        def setUp(self):
            print('start')
    
        @data({'value1': 1, 'value2': 2}, {'value1': 3, 'value2': 4})  # 字典
        @unpack
        def test_one(self, value1, value2):
            print('the @data number is {} and {}'.format(value1, value2))
    
        def tearDown(self):
            print('end')
    
    if __name__ == '__main__':
        unittest.main()
    
    # 结果如下
    start
    the @data number is 1 and 2
    end
    start
    the @data number is 3 and 4
    end
    from ddt import ddt, data, unpack
    import unittest
    
    @ddt
    class MyTestDdt(unittest.TestCase):
        def setUp(self):
            print('start')
    
        @data(*[{'value1': 1, 'value2': 2}, {'value1': 3, 'value2': 4}])  # 这里加 * 后会将返回数据分为一个个的字典
        @unpack
        def test_one(self, **value):
            print('the @data number is {} and {}'.format(value.get("value1"), value.get("value2")))
    
        def tearDown(self):
            print('end')
    
    if __name__ == '__main__':
        unittest.main()
    
    # 结果如下
    start
    the @data number is 1 and 2
    end
    start
    the @data number is 3 and 4
    end

    五、cms 登录实例

    """
    getTestData.py  封装读取 excel 文件内容且返回 [['Evan', '123456'], ['duoceshi007', '123456'], ['Evan', 'xxxxxx']] 格式数据的方法
    """

    import xlrd def getdata(): book = xlrd.open_workbook("data.xls") sheet = book.sheet_by_name("Sheet1") rows = sheet.nrows data_list = [] for t in range(rows-1): row_list = [] row_data = sheet.row_values(t + 1) for i in row_data: if isinstance(i, float): d = int(i) row_list.append(str(d)) else: row_list.append(i) data_list.append(row_list) return data_list
    """
    lesson3_5_1.py cms 登录测试用例
    """
    
    from selenium import webdriver
    import time
    import unittest
    from ddt import ddt, data, unpack
    from Python_selenium.lesson3_2020_11_2.lesson3_5_ddt.getTestData import getdata
    
    @ddt
    class cmsLogin(unittest.TestCase):
        
        def setUp(self) -> None:
            self.dr = webdriver.Chrome()
            self.dr.get("http://xxx.xxxxxxxxx.xx/cms/manage/login.do")
            self.dr.maximize_window()
            self.dr.implicitly_wait(10)
        
        def tearDown(self) -> None:
            time.sleep(2)
            self.dr.quit()
    
        @data(*getdata())
        @unpack
        def test_login(self, username, password):
            self.dr.find_element_by_id("userAccount").send_keys(username)
            self.dr.find_element_by_id("loginPwd").send_keys(password)
            self.dr.find_element_by_id("loginBtn").click()
            time.sleep(2)
            if username == "Evan" and password == "123456":
                try:
                    nickName = self.dr.find_element_by_class_name("c-white").text
                except:
                    raise AssertionError("登录失败!")
                else:
                    assert username in nickName
            else:
                loginText = self.dr.find_element_by_css_selector('[for="online"]').text
                assert "使我保持登录状态" in loginText
    
    if __name__ == '__main__':
        unittest.main()

      

  • 相关阅读:
    oracle job
    mysql与oracle之间的数据类型转换
    Oracle ORA-02069: 此操作的 global_names 参数必须设置为 TRUE
    oracle sequence 详解
    ORA-08004: 序列 SEQ_XXX.NEXTVAL exceeds MAXVALUE 无法实例化
    How to change Hostname / IP for a Grid Infrastructure Oracle Restart Standalone Configuration (SIHA) (文档 ID 1552810.1)
    oracle-1条updata的故事
    ADAPTIVE LOG FILE SYNC 引起的高Log File Sync警示
    oracle 静默创建数据库
    oracle 中文Linux安装乱码问题
  • 原文地址:https://www.cnblogs.com/ZhengYing0813/p/13882005.html
Copyright © 2020-2023  润新知