• 自动化测试框架-数据驱动(2)


    5、使用Excel进行数据驱动测试
    测试逻辑:
    (1)打开百度首页,从Excel文件中读取测试数据作为搜索关键词
    (2)在搜索输入框中输入读取出搜索关键词
    (3)单击搜索按钮
    (4)断言搜索结果页面中是否出Excel文件中提供的预期内容,包含则认为测试执行成功,否则认为失败

    测试数据准备:
    在本地磁盘D: estDataDrivenTesting目录中新建一个“测试数据.xlsx”,工作表名为“搜索数据表”,内容如下“
    序号 搜索词 期望结果
    1 邓肯 蒂姆
    2 乔丹 迈克尔
    3 库里 斯蒂芬

    实例代码:
    在Pycharm中新建一个ExcelDataDrivenProject的Python工程,工程下新建两个文件,文件名分别为ExcelUtil.py和DataDrivenByExcel.py和DataDrivenByExcel.py
    ExcelUtil.py文件用于编写读取Excel的脚本,具体内容如下:

    #encoding=utf-8
    from openpyxl import load_workbook
    
    class ParseExcel(object):
    
        def __init__(self, excelPath, sheetName):
            # 将要读取的excel加载到内存
            self.wb = load_workbook(excelPath)
            # 通过工作表名称获取一个工作表对象
            self.sheet = self.wb.get_sheet_by_name(sheetName)
            # 获取工作表中存在数据的区域的最大行号
            self.maxRowNum = self.sheet.max_row
    
        def getDatasFromSheet(self):
            # 用于存放从工作表中读取出来的数据
            dataList = []
            for line in self.sheet.rows:
                # 遍历工作表中数据区域的每一行,
                # 并将每行中各个单元格的数据取出存于列表tmpList中,
                # 然后再将存放一行数据的列表添加到最终数据列表dataList中
                tmpList = []
                tmpList.append(line[1].value)
                tmpList.append(line[2].value)
                dataList.append(tmpList)
            # 将获取工作表中的所有数据的迭代对象返回
            # 因为工作表中的第一行是标题行,所以需要去掉
            return dataList[1:]
    
    if __name__ == '__main__':
        excelPath = u'D:\test\DataDrivenTesting\测试数据.xlsx'
        sheetName = u"搜索数据表"
        pe = ParseExcel(excelPath, sheetName)
        print pe.getDatasFromSheet()
        for i in pe.getDatasFromSheet():
            print i[0], i[1]

      DataDrivenByExcel.py文件用于编写数据驱动测试脚本代码,具体内容如下:

    #encoding=utf-8
    import unittest,time
    import logging,traceback
    import ddt
    from selenium import webdriver
    from selenium.common.exceptions import NoSuchElementException
    from ExcelUtil import ParseExcel
    
    #初始化日志对象
    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 = "D:\test\DataDrivenTesting\report.log",
        #打开日志文件的方式
        filemode = "w"
    )
    
    excelPath = u"D:\test\DataDrivenTesting\测试数据.xlsx"
    sheetName = u"搜索数据表"
    #ParseExcel类的实例对象
    excel = ParseExcel(excelPath,sheetName)
    
    @ddt.ddt
    
    class TestDemo(unittest.TestCase):
    
        def setUp(self):
            self.driver = webdriver.Ie(executable_path = "D:\IEDriverServer")
    
        @ddt.data(*excel.getDatasFromSheet())
        def test_dataDrivenByExcel(self,data):
            testdata,expectdata = tuple(data)
            url = "http://www.baidu.com"
            self.driver.get(url)
            self.driver.maximize_window()
            #设置隐式等待时间为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()

    不使用ddt和uniitest的Excel数据驱动,DataDrivenByExcel.py:

    #encoding=utf-8
    from selenium import webdriver
    import time
    import datetime
    from openpyxl import *
    wb = load_workbook(u"D:\test\DataDrivenTesting\测试数据.xlsx")
    ws = wb.active  #获取第一个sheet
    print u"最大行号:", ws.max_row
    
    driver = webdriver.Ie(executable_path = "D:\IEDriverServer")
    test_result = []
    #Excel的行是从1开始的,所以我们从第二行开始遍历(第一行是标题)
    #且使用切片时,必须有结束行的索引号,不能写成[1:],这样会报错
    #Excel的列号是从0开始的,列读取以出来后是一个元组
    for row in ws[2:ws.max_row]:
        print row[1],row[2]
        try:
            driver.get("http://www.baidu.com")
            driver.find_element_by_id("kw").send_keys(row[1].value)
            driver.find_element_by_id("su").click()
            time.sleep(3)
            assert row[2].value in driver.page_source
            row[3].value = time.strftime("%Y-%m-%d %H:%M:%S")
            row[4].value = u"成功"
        except AssertionError,e:
            row[3].value = time.strftime("%Y-%m-%d %H:%M:%S")
            row[4].value = u"断言失败"
        except Exception,e:
            row[3].value = time.strftime("%Y-%m-%d %H:%M:%S")
            row[4].value = u"出现异常失败"
    
    driver.quit()
    wb.save(u"D:\test\DataDrivenTesting\测试数据.xlsx")


    6、使用XML进行数据驱动测试
    测试逻辑:
    (1)打开百度首页,从XML文件中读取测试数据作为搜索关键词
    (2)在搜索框中输入读取出的搜索关键词
    (3)单击搜索按钮
    (4)断言搜索结果页面中是否出现了XML文件中提供的预期内容,包含则认为测试执行成功,否则认为失败

    实例代码:
    在PyCharm中新建一个名叫XMLDataDrivenProject的Python工程,并在工程下新建三个文件,文件名分别为XmlUtil.py、TestData.xml以及DataDrivenByXML.py
    TestData.xml文件用于存放测试数据,具体内容如下:

    <?xml version = "1.0" encoding = "utf-8"?>
    <bookList type = "technology">
        <book>
            <name> Selenium WebDriver 实战宝典</name>
            <author>吴晓华</author>
        </book>
        <book>
            <name> HTTP 权威指南</name>
            <author>古尔利</author>
        </book>
            <book>
            <name>探索式软件测试</name>
            <author>惠特克</author>
        </book>
    </bookList>

      XmlUtil.py文件用于解析xmlutil.py文件,获取测试数据,具体内容如下:

    #encoding=utf-8
    from xml.etree import ElementTree
    
    class ParseXML(object):
        def __init__(self,xmlPath):
            self.xmlPath = xmlPath
    
        def getRoot(self):
            #打开将要解析的XML文件
            tree = ElementTree.parse(self.xmlPath)
            #获取XML文件的根节点对象,也就是树的根,然后返回给调用者
            return tree.getroot()
    
        def findNodeByName(self,parentNode,nodeName):
            #通过节点的名字,获取节点对象
            nodes = parentNode.findall(nodeName)
            return nodes
    
        def getNodeOfChildText(self,node):
            #获取节点node下所有子节点的节点名作为key,本节点作为value组成的字典对象
            childrenTextDick = {i.tag:i.text for i in list(node.iter())[1:]}
            #上面代码造价于下面代码
            """
            childrenTextDick = {}
            for i in list(node.iter())[1:]:
                childrenTextDick[i.tag] = i.text
            """
            return childrenTextDick
    
        def getDataFromXml(self):
            #获取XML文档树的根节点对象
            root = self.getRoot()
            #获取根节点下所有名叫book的节点对象
            books = self.findNodeByName(root,"book")
            dataList = []
            #遍历获取到的所有book节点对象,取得需要的测试数据
            for book in books:
                childrenText = self.getNodeOfChildText(book)
                dataList.append(childrenText)
            return dataList
    
    if __name__ == "__main__":
        xml = ParseXML(r"D:\PythonProject\XMLDataDrivenProject\TestData.xml")
        datas = xml.getDataFromXml()
        for i in datas:
            print i["name"],i["author"]

      DataDrivenByXml.py文件用于编写数据驱动测试脚本,具体内容如下:

    #encoding=utf-8
    from selenium import webdriver
    import unittest,time,os
    import logging,traceback
    import ddt
    from XmlUtil import ParseXML
    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 = "D:\test\DataDrivenTesting\report.log",
        #打开日志文件的方式
        filemode = "w"
    )
    
    #获取当前文件所在父目录的绝对路径
    currentPath = os.path.dirname(os.path.abspath(__file__))
    #获取数据文件的绝对路径
    dataFilePath = os.path.join(currentPath,"TestData.xml")
    print dataFilePath
    
    #创建ParseXML类实例对象
    xml = ParseXML(dataFilePath)
    
    @ddt.ddt
    class TestDemo(unittest.TestCase):
    
        def setUp(self):
            self.driver = webdriver.Ie(executable_path = "D:\IEDriverServer")
    
        @ddt.data(*xml.getDataFromXml())
        def test_dataDrivenByXml(self,data):
            testdata,expectdata = data["name"],data["author"]
            url = "http://www.baidu.com"
            #访问百度首页
            self.driver.get(url)
            #将浏览器窗口最大化
            self.driver.maximize_window()
            print testdata,expectdata
            #设置隐式等待时间为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()

    7、使用MySQL数据库进行数据驱动测试
    测试逻辑:
    (1)打开百度首页,从MySql数据库中获取测试过程中需要的测试数据
    (2)在搜索输入框中输入查询关键词测试数据
    (3)单击搜索按钮
    (4)断言搜索结果页面中是否出现数据库中提供的预期内容,包含则认为测试执行成功,否则认为失败
    环境准备:
    安装MySql

    实例代码:
    在PyCharm中新建一个名叫DataBaseDataDrivenProject的Python工程,并在工程下新建四个文件,文件名分别为Sql.py、DataBaseInit.py、MysqlUtil.py和DataDrivenByMySql.py
    Sql.py文件用于编写创建数据库及数据表的Sql语句,具体内容如下:

    #encoding=utf-8
    
    # 创建gloryroad数据库sql语句
    create_database = 'CREATE DATABASE IF NOT EXISTS gloryroad DEFAULT CHARSET utf8 COLLATE utf8_general_ci;'
    
    # 创建testdata表
    create_table = """
        drop table if exists testdata;
        create table testdata(
            id int not null auto_increment comment '主键',
            bookname varchar(40) unique not null comment '书名',
            author varchar(30) not null comment '作者',
            test_result varchar(30) default null,
            primary key(id)
        )engine=innodb character set utf8 comment '测试数据表';
    """

      DataBaseInit.py文件用于编写初始化数据库的脚本,具体内容如下:

    #encoding=utf-8
    import MySQLdb
    from Sql import *
    
    class DataBaseInit(object):
        # 本类用于完成初始化数据操作
        # 创建数据库,创建数据表,向表中插入测试数据
        def __init__(self, host, port, dbName, username, password, charset):
            self.host = host
            self.port = port
            self.db = dbName
            self.user = username
            self.passwd = password
            self.charset = charset
    
        def create(self):
            try:
                # 连接mysql数据库
                conn = MySQLdb.connect(
                    host = self.host,
                    port = self.port,
                    user = self.user,
                    passwd = self.passwd,
                    charset = self.charset
                )
                # 获取数据库游标
                cur = conn.cursor()
                # 创建数据库
                cur.execute(create_database)
                # 选择创建好的gloryroad数据库
                conn.select_db("gloryroad")
                # 创建测试表
                cur.execute(create_table)
            except MySQLdb.Error, e:
                print e
            else:
                # 关闭游标
                cur.close()
                # 提交操作
                conn.commit()
                # 关闭连接
                conn.close()
                print u"创建数据库及表成功"
    
        def insertDatas(self):
            try:
                # 连接mysql数据库中具体某个库
                conn = MySQLdb.connect(
                    host = self.host,
                    port = self.port,
                    db = self.db,
                    user = self.user,
                    passwd = self.passwd,
                    charset = self.charset
                )
                cur = conn.cursor()
                # 向测试表中插入测试数据
                sql = "insert into testdata(bookname, author) values(%s, %s);"
                res = cur.executemany(sql, [('Selenium WebDriver实战宝典', '吴晓华'),
                                      ('HTTP权威指南', '古尔利'),
                                      ('探索式软件测试', '惠特克'),
                                      ('暗时间', '刘未鹏')])
            except MySQLdb.Error, e:
                raise e
            else:
                conn.commit()
                print u"初始数据插入成功"
                # 确认插入数据成功
                cur.execute("select * from testdata;")
                for i in cur.fetchall():
                    print i[1], i[2]
                cur.close()
                conn.close()
    
    
    if __name__ == '__main__':
        db = DataBaseInit(
            host="localhost",
            port=3306,
            dbName="gloryroad",
            username="root",
            password="123456",
            charset="utf8"
        )
        db.create()
        db.insertDatas()
        print u"数据库初始化结束"

      MysqlUtil.py文件用于从数据库中获取测试数据,具体内容如下:

    #encoding=utf-8
    import MySQLdb
    from DataBaseInit import DataBaseInit
    
    class MyMySQL(object):
        def __init__(self, host, port, dbName, username, password, charset):
            # 进行数据库初始化
            dbInit = DataBaseInit(host, port, dbName, username, password, charset)
            dbInit.create()
            dbInit.insertDatas()
            self.conn = MySQLdb.connect(
                host = host,
                port = port,
                db = dbName,
                user = username,
                passwd = password,
                charset = charset
            )
            self.cur = self.conn.cursor()
    
        def getDataFromDataBases(self):
            # 从testdata表中获取需要的测试数据
            # bookname作为搜索关键词,author作为预期关键词
            self.cur.execute("select bookname, author from testdata;")
            # 从查询区域取回所有查询结果
            datasTuple = self.cur.fetchall()
            return datasTuple
    
        def closeDatabase(self):
            # 数据库后期清理工作
            self.cur.close()
            self.conn.commit()
            self.conn.close()
    
    if __name__ == '__main__':
        db = MyMySQL(
            host="localhost",
            port=3306,
            dbName="gloryroad",
            username="root",
            password="123456",
            charset="utf8"
        )
        print db.getDataFromDataBases()

      DataDrivenByMySQL.py文件用于编写数据驱动测试脚本代码,具体内容如下:

    # encoding=utf-8
    from selenium import webdriver
    import unittest, time
    import logging, traceback
    import ddt
    from MysqlUtil import MyMySQL
    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, %Y-%m-%d %H:%M:%S',
        # 日志文件存放的目录(目录必须存在)及日志文件名
        filename = 'D:\test\DataDrivenTesting\report.log',
        # 打开日志文件的方式
        filemode = 'w'
    )
    
    def getTestDatas():
        db = MyMySQL(
            host="localhost",
            port=3306,
            dbName="gloryroad",
            username="root",
            password="123456",
            charset="utf8"
        )
        # 从数据库测试表中获取测试数据
        testData = db.getDataFromDataBases()
        # 关闭数据库连接
        db.closeDatabase()
        return testData
    
    @ddt.ddt
    class TestDemo(unittest.TestCase):
    
        def setUp(self):
            self.driver = webdriver.Ie(executable_path = "D:\IEDriverServer")
    
        @ddt.data(*getTestDatas())
        def test_dataDrivenByDatabase(self, data):
            # 对获得的数据进行解包
            testData, expectData = data
            url = "http://www.baidu.com"
            # 访问百度首页
            self.driver.get(url)
            # 将浏览器窗口最大化
            self.driver.maximize_window()
            print testData, expectData
            # 设置隐式等待时间为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()
  • 相关阅读:
    禁止浏览器缓存input值
    网站性能分析插件
    获取没有key值的数据,用循环器
    //解决scrollview嵌套gridview不默认显示顶部
    解决ScrollView下嵌套ListView进页面不在顶部的问题
    Android:完美解决ScrollView嵌套GridView
    Android RadioButton代码去掉左边默认显示的圆圈
    Android设置虚线、圆角、渐变
    android在代码中四种设置控件(以及TextView的文字颜色)背景颜色的方法
    Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面
  • 原文地址:https://www.cnblogs.com/test-chen/p/10858289.html
Copyright © 2020-2023  润新知