zoukankan      html  css  js  c++  java
  • 【webdriver自动化】Python数据驱动工具DDT

    一、Python数据驱动工具ddt

    1、  安装

    ddt pip install ddt

    DDT是 “Data-Driven Tests”的缩写

     资料:http://ddt.readthedocs.io/en/latest/

    2、  DDT的使用

    (1)   ddt.ddt:

    装饰类,也就是继承自TestCase的类

    (2)   ddt.data:

    装饰测试方法。参数是一系列的值。

    (3)   ddt.file_data:

    装饰测试方法。参数是文件名。文件可以是json 或者 yaml类型。

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

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

    (4)   ddt.unpack:

    传递的是复杂的数据结构时使用。比如使用元组或者列表,添加unpack之后,ddt会自动把元组或者列表对应到多个参数上。字典也可以这样处理。

    (5)   测试用例方法名生成规则

    使用ddt后,会产生一个新的测试用例方法名:之前的测试用例方法名_ordinal_data

    之前的测试用例方法名:即定义的测试用例方法名。比如def test_large(),这里就是test_large

    ordinal:整数,从1开始递加。

     data:如果传递过来的数据存在__name__属性,则这里就是该数据的__name__值。如果未定义__name__属性,ddt会尽量将传递过来的数据转化为python标识符,作为data显示。比如(3,2)就转化为3_2。需要注意的是,如果数据是字典,则这里就是字典的key。

     

     二、实例演示

     

    1、@ddt.ddt&&@ddt.data
    
    main.py:
    from selenium import webdriver
    import unittest, time
    import logging, traceback
    import ddt
    from selenium.common.exceptions import NoSuchElementException
    
    # 初始化日志对象
    logging.basicConfig(
        # 日志级别
        level = logging.INFO,
        # 日志格式
        # 时间、代码所在文件名、代码行号、日志级别名字、日志信息
        format = '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
        # 打印日志的时间
        datefmt = '%a, %d %b %Y %H:%M:%S',
        # 日志文件存放的目录(目录必须存在)及日志文件名
        filename = 'e:/report.log',
        # 打开日志文件的方式
        filemode = 'w'
    )
    
    @ddt.ddt
    class TestDemo(unittest.TestCase):
        def setUp(self):
            self.driver = webdriver.Ie(executable_path = "c:\IEDriverServer")
        @ddt.data([u"神奇动物在哪里", u"叶茨"],
                  [u"疯狂动物城", u"古德温"],
                  [u"大话西游之月光宝盒", u"周星驰"])
        @ddt.unpack   #解包,将测试数据对应到testdata 和 expectdata
        def test_dataDrivenByObj(self, testdata, expectdata):
            url = "http://www.baidu.com"
            # 访问百度首页
            self.driver.get(url)
            # 设置隐式等待时间为10秒
            self.driver.implicitly_wait(10)
            try:
                # 找到搜索输入框,并输入测试数据
                self.driver.find_element_by_id("kw").send_keys(testdata)
                # 找到搜索按钮,并点击
                self.driver.find_element_by_id("su").click()
                time.sleep(3)
                # 断言期望结果是否出现在页面源代码中
                self.assertTrue(expectdata in self.driver.page_source)
            except NoSuchElementException, e:
                logging.error(u"查找的页面元素不存在,异常堆栈信息:" 
                              + str(traceback.format_exc()))
            except AssertionError, e:
                logging.info(u"搜索“%s”,期望“%s”,失败" %(testdata, expectdata))
            except Exception, e:
                logging.error(u"未知错误,错误信息:" + str(traceback.format_exc()))
            else:
                logging.info(u"搜索“%s”,期望“%s”通过" %(testdata, expectdata))
    
        def tearDown(self):
            self.driver.quit()
    
    if __name__ == '__main__':
        unittest.main()

     

    2、@ddt.file_data
    
    test_data_list.json:
    [
            "邓肯||蒂姆",
            "乔丹||迈克尔",
            "库里||斯蒂芬",
            "杜兰特||凯文",
            "詹姆斯||勒布朗"
        ]
    
    main.py:
    
    from selenium import webdriver
    import unittest, time
    import logging, traceback
    import ddt
    from ReportTemplate import htmlTemplate
    from selenium.common.exceptions import NoSuchElementException
    
    #如果有no json的报错信息,请将json文件存储为utf-8,with Bom
    # 初始化日志对象
    logging.basicConfig(
        # 日志级别
        level = logging.INFO,
        # 日志格式
        # 时间、代码所在文件名、代码行号、日志级别名字、日志信息
        format = '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
        # 打印日志的时间
        datefmt = '%a, %Y-%m-%d %H:%M:%S',
        # 日志文件存放的目录(目录必须存在)及日志文件名
        filename = 'e:/report.log',
        # 打开日志文件的方式
        filemode = 'w'
    )
    
    @ddt.ddt
    class TestDemo(unittest.TestCase):
    
        @classmethod
        def setUpClass(cls):
            # 整个测试过程只被调用一次
            TestDemo.trStr = ""
    
        def setUp(self):
            self.driver = webdriver.Ie(executable_path = "c:\IEDriverServer")
            status = None # 用于存放测试结果状态,失败'fail',成功'pass'
            flag = 0 # 数据驱动测试结果的标志,失败置0,成功置1
    
        @ddt.file_data("test_data_list.json")
        def test_dataDrivenByFile(self, value):
            # 决定测试报告中状态单元格中内容的颜色
            flagDict = {0: 'red', 1: '#00AC4E'}
    
            url = "http://www.baidu.com"
            # 访问百度首页
            self.driver.get(url)
            # 将浏览器窗口最大化
            self.driver.maximize_window()
            print value
            # 将从.json文件中读取出的数据用“||”进行分隔成测试数据
            # 和期望数据
            testdata, expectdata = tuple(value.strip().split("||"))
            # 设置隐式等待时间为10秒
            self.driver.implicitly_wait(10)
    
            try:
                # 获取当前的时间戳,用于后面计算查询耗时用
                start = time.time()
                # 获取当前时间的字符串,表示测试开始时间
                startTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
                # 找到搜索输入框,并输入测试数据
                self.driver.find_element_by_id("kw").send_keys(testdata)
                # 找到搜索按钮,并点击
                self.driver.find_element_by_id("su").click()
                time.sleep(3)
                # 断言期望结果是否出现在页面源代码中
                self.assertTrue(expectdata in self.driver.page_source)
            except NoSuchElementException, e:
                logging.error(u"查找的页面元素不存在,异常堆栈信息:" 
                              + str(traceback.format_exc()))
                status = 'fail'
                flag = 0
            except AssertionError, e:
                logging.info(u"搜索“%s”,期望“%s”,失败" %(testdata, expectdata))
                status = 'fail'
                flag = 0
            except Exception, e:
                logging.error(u"未知错误,错误信息:" + str(traceback.format_exc()))
                status = 'fail'
                flag = 0
            else:
                logging.info(u"搜索“%s”,期望“%s”通过" %(testdata, expectdata))
                status = 'pass'
                flag = 1
            # 计算耗时,从将测试数据输入到输入框中到断言期望结果之间所耗时
            wasteTime = time.time() - start - 3 # 减去强制等待的3秒
            # 每一组数据测试结束后,都将其测试结果信息插入表格行
            # 的HTML代码中,并将这些行HTML代码拼接到变量trStr变量中,
            # 等所有测试数据都被测试结束后,传入htmlTemplate()函数中
            # 生成完整测试报告的HTML代码
            TestDemo.trStr += u'''
            <tr>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td>%.2f</td>
                <td style="color:%s">%s</td>
            </tr><br />''' % (testdata, expectdata,startTime,  wasteTime, flagDict[flag], status)
    
        def tearDown(self):
            self.driver.quit()
    
        @classmethod
        def tearDownClass(cls):
            # 写自定义的html测试报告
            # 整个测试过程只被调用一次
            htmlTemplate(TestDemo.trStr)
    
    if __name__ == '__main__':
        unittest.main()

     

     

  • 相关阅读:
    Velocity的使用小记
    fastJson的SerializeFilter使用
    快捷的时间转化
    How to execute a Stored Procedure with Entity Framework Code First
    自定义 ASP.NET Identity Data Model with EF
    Asp.Net Core get client IP
    HTTP 请求头中的 X-Forwarded-For
    HttpRequest,WebRequest,HttpWebRequest,WebClient,HttpClient 之间的区别
    【逻辑】500桶酒,找毒酒
    Asp.Net Core 输出 Word
  • 原文地址:https://www.cnblogs.com/jingsheng99/p/9236666.html
Copyright © 2011-2022 走看看