Python自动化测试系列[v1.0.0][多种数据驱动实现附源码]

前情提要

请确保已经熟练掌握元素定位的常用方法及基本支持,请参考Python自动化测试系列[v1.0.0][元素定位]

数据驱动测试是自动化测试中一种重要的设计模式,这种设计模式可以将测试数据和测试代码分开,实现数据与代码解耦,与此同时还能够实现一次任务中使用不同的数据来执行执行相同的测试脚本,因此它会使得我们的代码层次结构清晰,容易维护,并且大大降低了代码量

数据驱动是自动化测试中非常常见的一种设计模式,应用的场景非常多,无论是在Web自动化还是在接口自动化、单元测试,亦或是在数据分析应用领域的测试上都会得到非常广泛的使用,常见的比如Web自动化的登录功能、一些录入类的功能,再比如接口入参、单元测试的入参,甚至在数据类应用的大量数据输入及结果比较上

使用Excel存储测试输入数据

数据文件

假如我们有如下一组数据存储在Excel里

序号检索词期望结果
1北京北京
2上海上海
3广州广州

获取测试数据方法

通过python的openpyxl模块解析Excel文件,并获取数据

安装openpyxl
C:\Users\Administrator>pip install openpyxl
Collecting openpyxl
  Downloading openpyxl-3.0.3.tar.gz (172 kB)
     |████████████████████████████████| 172 kB 384 kB/s
Collecting jdcal
  Using cached jdcal-1.4.1-py2.py3-none-any.whl (9.5 kB)
Collecting et_xmlfile
  Using cached et_xmlfile-1.0.1.tar.gz (8.4 kB)
Installing collected packages: jdcal, et-xmlfile, openpyxl
    Running setup.py install for et-xmlfile ... done
    Running setup.py install for openpyxl ... done
Successfully installed et-xmlfile-1.0.1 jdcal-1.4.1 openpyxl-3.0.3

方法封装

# encoding = utf-8
from openpyxl import load_workbook
 
 
class ParseExcel(object):
 
    def __init__(self, excelPath, sheetName):
        self.wb = load_workbook(excelPath)
        #  self.sheet = self.lwb.get_sheet_by_name(sheetName)
        self.sheet = self.wb[sheetName]
        self.maxRowNum = self.sheet.max_row
 
    def getDatasFromSheet(self):
        dataList = []
        for line in list(self.sheet.rows)[1:]:
            tmpList = []
            tmpList.append(line[1].value)
            tmpList.append(line[2].value)
            dataList.append(tmpList)
        return dataList
 
 
if __name__ == '__main__':
    excelPath = u'D:\\Programs\\Python\\PythonUnittest\\TestData\\测试数据.xlsx'
    sheetName = u'搜索数据表'
    pe = ParseExcel(excelPath, sheetName)
    for i in pe.getDatasFromSheet():
        print(i[0], i[1])

封装了getDatasFromSheet方法,该方法将解析Excel,并将数据存到List中去,后续的测试代码调用的实际上是从List里边获取数据

测试代码

# encoding = utf-8
from selenium import webdriver
import unittest
import time
import traceback
import ddt
import logging
from Util.ParseExcelUtil import ParseExcel
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:\\Programs\\Python\\PythonUnittest\\Reports\\TestResults.TestResults',
    # 打开日志的方式
    filemode='w'
)
 
excelPath = u"D:\\Programs\\Python\\PythonUnittest\\TestData\\测试数据.xlsx"
sheetName = u"搜索数据表"
excel = ParseExcel(excelPath, sheetName)
 
@ddt.ddt
class TestDataDrivenByExcel(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
 
    @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()
        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 as e:
            logging.error(u"查找的页面元素不存在,异常堆栈信息为:" + str(traceback.format_exc()))
        except AssertionError as e:
            logging.info(u"搜索 ‘%s’,期望 ‘%s’ ,失败" % (testData, expectData))
        except Exception as 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()

使用Parameterize模块组织数据集作为测试输入数据

安装PARAMETERIZE

C:\Users\Administrator>pip install parameterized
Collecting parameterized
  Downloading https://files.pythonhosted.org/packages/a3/bf/6ef8239028beae8298e0806b4f79c2466b1b16ca5b85dc13d631c5ea92c4/parameterized-0.7.1-py2.py3-none-any.whl
Installing collected packages: parameterized
Successfully installed parameterized-0.7.1

测试代码

# -*- coding: utf-8 -*-
# @Time: 4/27/2019 1:52 PM
# @Author : Yang DaWei
# @Project : DataDrivenTest
# @FileName: Unittest_Parameterized.py
import unittest
from selenium import webdriver
import time
from parameterized import parameterized
from selenium.common.exceptions import NoSuchElementException  # 引入NoSuchElementException异常类

class LoginTest(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.url = "http://mail.163.com"
        self.driver.implicitly_wait(10)

    def user_login_163(self, username, password):
        driver = self.driver
        driver.get(self.url)
        # 定义frame,他是页面中的iframe控件
        frame = self.driver.find_element_by_xpath("//*[@id='loginDiv']/iframe")
        time.sleep(1)
        try:
            self.driver.switch_to.frame(frame)  # 切换进iframe控件
            self.driver.find_element_by_name("email").send_keys(username)  # 输入用户名
            self.driver.find_element_by_name("password").send_keys(password)  # 输入密码
            self.driver.find_element_by_id("dologin").click()  # 点击登陆按钮
        except NoSuchElementException as e:
            # 将未找到页面元素的异常记录进日志
            raise e
        except Exception as e:
            raise e

    @parameterized.expand([
        ('', "davieyang", "请输入帐号"),
        ("davieyang", '', "请输入密码"),
        ("error", "error", "帐号或密码错误"),
    ])
    def test_login(self, username, password, assert_text):
        self.user_login_163(username, password)
        message = self.driver.find_element_by_id("nerror").text
        self.assertEqual(message, assert_text)

    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    unittest.main(verbosity=2)

使用JSON存储测试输入数据[List]

方式一

[
  "北京||北京","上海||上海","广州||广州","深圳||深圳","香港||香港"
]
测试代码
# encoding = utf-8
"""
__title__ = ''
__author__ = 'davieyang'
__mtime__ = '2018/4/21'
"""
from selenium import webdriver
import unittest
import time
import logging
import 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='F:\\DataDriven\\TestResults\TestResults.TestResults',
    # 打开日志的方式
    filemode='w'
)


@ddt.ddt
class DataDrivenTestByDDTHTR(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path="F:\\automation\\webdriver\\chromedriver.exe")

    # json文件所在路径
    @ddt.file_data("F:\\DataDriven\\testData\\test_data_list.json")
    def test_dataDrivenHTRByFile(self, value):
        url = "http://www.baidu.com"
        self.driver.get(url)
        self.driver.maximize_window()
        print(value)
        # 将从.json文件中读取出的数据用“||”分割成测试数据和期望的数据
        testdata, execptdata = tuple(value.strip().split("||"))
        # 设置隐式等待时间
        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(execptdata in self.driver.page_source)
        except NoSuchElementException as e:
            logging.error(u"查找的页面元素不存在,异常堆栈信息为:" + str(traceback.format_exc()))
        except AssertionError as e:
            logging.info(u"搜索 '%s',期望 '%s' ,失败" % (testdata, execptdata))
        except Exception as e:
            logging.error(u"未知错误,错误信息:" + str(traceback.format_exc()))
        else:
            logging.info(u"搜索 '%s',期望 '%s' ,通过" % (testdata, execptdata))

    def tearDown(self):
        self.driver.quit()


if __name__ == '__main__':
    unittest.main()

方式二

测试报告模板
# encoding = utf-8
"""
__title__ = 'DataDrivenTestByDDT use this template for generating testing report'
__author__ = 'davieyang'
__mtime__ = '2018/4/21'
"""
# encoding = utf-8
def htmlTemplate(trData):
    htmlStr = u'''<!DOCTYPE HTML>
    <html>
    <head>
    <title>单元测试报告</title>
    <style>
    body {
        width:80%;
        margin:40px auto;
        font-weight:bold;
        font-family: 'trebuchet MS', 'Lucida sans', SimSun;
        font-size:18px;
        color: #000;
    }
    table {
        * border-collapse:collapse;
        border-spacing:0;
        width:100%;
    }
    .tableStyle {
        /* border:solid #ggg 1px;*/
        border-style:outset;
        border-width:2px;
        /*border:2px;*/
        border-color:blue;
    }
    .tableStyle tr:hover {
        background: rgb(173.216.230);
    }
    
    .tableStyle td,.tableStyle th{
        border-left:solid 1px rgb(146,208,80);
        border-top:1px solid rgb(146,208,80);
        padding:15px
        text-align:center
    }
    .tableStyle th{
        padding:15px;
        background-color:rgb(146,208,80);
        /*表格标题栏设置渐变颜色*/
        background-image: -webkit -gradient(linear, left top, left bottom, from(#92D050), to(#A2D668))
        /*rgb(146,208,80)*/
    }     
    </style>
    </head>
    <body>
        <center><h1>测试报告</h1></center><br />
        <table class="tableStyle">
            <thead>
            <tr>
            <th>Search Words</th>
            <th>Assert Words</th>
            <th>Start Time</th>
            <th>Waste Time(s)</th>
            <th>Status</th>
            </tr>
            </thead>'''
    endStr = u'''
        </table>
    </body>
    </html>'''
    html = htmlStr + trData + endStr
    print(html)
    with open("D:\\\Programs\\\Python\\\PythonUnittest\\\Reports\\testTemplate.html", "wb") as fp:
        fp.write(html.encode("gbk"))
测试脚本
# encoding = utf-8
"""
__title__ = ''
__author__ = 'davieyang'
__mtime__ = '2018/4/21'
"""
from selenium import webdriver
import unittest
import time
import logging
import traceback
import ddt
from DataDrivenTest.ReportTemplate import htmlTemplate
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:\\Programs\\Python\\PythonUnittest\\Reports\\TestResults.TestResults',
    # 打开日志的方式
    filemode='w'
)
 
 
@ddt.ddt
class DataDrivenTestByDDT(unittest.TestCase):
 
    @classmethod
    def setUpClass(cls):
        # 整个测试过程只调用一次
        DataDrivenTestByDDT.trStr = ""
 
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path="D:\\Programs\\Python\\PythonUnittest\\BrowserDrivers\\chromedriver.exe")
        status = None  # 用于存放测试结果状态,失败‘fail’,成功‘pass’
        flag = 0  # 数据驱动测试结果的标志,失败置0,成功置1
 
    @ddt.file_data("D:\\Programs\\Python\\PythonUnittest\\TestData\\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, execptdata = tuple(value.strip().split("||"))
        # 设置隐式等待时间
        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(execptdata in self.driver.page_source)
        except NoSuchElementException as e:
            logging.error(u"查找的页面元素不存在,异常堆栈信息为:"+ str(traceback.format_exc()))
            status = 'fail'
            flag = 0
        except AssertionError as e:
            logging.info(u"搜索 ‘%s’,期望 ‘%s’ ,失败" %(testdata, execptdata))
            status = 'fail'
            flag = 0
        except Exception as e:
            logging.error(u"未知错误,错误信息:" + str(traceback.format_exc()))
            status = 'fail'
            flag = 0
        else:
            logging.info(u"搜索 ‘%s’,期望 ‘%s’ ,通过" %(testdata, execptdata))
            status = 'pass'
            flag = 1
        # 计算耗时,从将测试数据输入到输入框中到断言期望结果之间所耗时
            wasteTime = time.time() - start - 3  # 减去强制等待3秒
        # 每一组数据测试结束后,都将其测试结果信息插入表格行的HTML代码中,并将这些行HTML代码拼接到变量trStr变量中,
        # 等所有测试数据都被测试结束后,传入htmlTemplate()函数中,生成完整测试报告的HTML代码
            DataDrivenTestByDDT.trStr += u'''
            <tr>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td>%.2f</td>
                <td style = "color: %s">%s</td>
            </tr><br/>''' % (testdata, execptdata, startTime, wasteTime, flagDict[flag], status)
 
    def tearDown(self):
        self.driver.quit()
 
    @classmethod
    def tearDownClass(cls):
        # 写自定义的HTML测试报告,整个过程只被调用一次
        htmlTemplate(DataDrivenTestByDDT.trStr)
 
 
if __name__ == '__main__':
    unittest.main()
生成日志
Fri, 07 Dec 2018 15:05:36 DataDrivenTestByDDT.py[line: 81] INFO 搜索 ‘北京’,期望 ‘北京’ ,通过
Fri, 07 Dec 2018 15:05:50 DataDrivenTestByDDT.py[line: 81] INFO 搜索 ‘上海’,期望 ‘上海’ ,通过
Fri, 07 Dec 2018 15:06:04 DataDrivenTestByDDT.py[line: 81] INFO 搜索 ‘广州’,期望 ‘广州’ ,通过
Fri, 07 Dec 2018 15:06:18 DataDrivenTestByDDT.py[line: 81] INFO 搜索 ‘深圳’,期望 ‘深圳’ ,通过
Fri, 07 Dec 2018 15:06:32 DataDrivenTestByDDT.py[line: 81] INFO 搜索 ‘香港’,期望 ‘香港’ ,通过
HTML报告

在这里插入图片描述

使用JSON存储测试输入数据[字典]

除了在json文件中放置List类型的数据,还可以放置Dict类型的数据,在PO项目的TestData路径下新建一个文件,并命名为login.json,然后在文件中写入如下测试数据。

{
  "test_login_01": {
    "username":"",
    "password":"davieyang",
    "assert_text": "请输入帐号"
  },
  "test_login_02": {
    "username":"davieyang",
    "password":"",
    "assert_text": "请输入密码"
  },
  "test_login_03":{
    "username":"error",
    "password":"error",
    "assert_text": "帐号或密码错误"
  }
}

测试脚本

# -*- coding: utf-8 -*-
import unittest
from selenium import webdriver
from ddt import ddt, file_data
import time
# 引入NoSuchElementException异常类
from selenium.common.exceptions import NoSuchElementException
from Configuration import ConstantConfig
#  定义测试数据文件
login_json = ConstantConfig.jsondictdata

@ddt
class TestLogin(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.url = "http://mail.163.com"
        self.driver.implicitly_wait(10)
    def user_login_163(self, username, password):
        driver = self.driver
        driver.get(self.url)
        # 定义frame,他是页面中的iframe控件
        frame = self.driver.find_element_by_xpath("//*[@id='loginDiv']/iframe")
        time.sleep(1)
        try:
            self.driver.switch_to.frame(frame)  # 切换进iframe控件
            self.driver.find_element_by_name("email").send_keys(username)  # 输入用户名
            self.driver.find_element_by_name("password").send_keys(password)  # 输入密码
            self.driver.find_element_by_id("dologin").click()  # 点击登陆按钮
        except NoSuchElementException as e:
            # 将未找到页面元素的异常记录进日志
            raise e
        except Exception as e:
            raise e
    @file_data(login_json)
    def test_login(self, username, password, assert_text):  # 定义测试方法
        self.user_login_163(username, password)  # 调用登陆163的方法
        message = self.driver.find_element_by_id("nerror").text  
        self.assertEqual(message, assert_text)  # 断言
    def tearDown(self):
        self.driver.quit()
if __name__ == '__main__':
    unittest.main(verbosity=2)

使用MySQL存储测试输入数据

测试数据

# encoding = utf-8
 
create_database = 'CREATE DATABASE IF NOT EXISTS davieyang DEFAULT CHARSET utf8 COLLATE utf8_general_ci;'
drop_table = 'DROP TABLE testdata;'
create_table = """
    CREATE TABLE testdata(
        ID int primary key not null auto_increment comment '主键',
        BOOKNAME varchar(40) unique not null comment '书名',
        AUTHOR varchar(30) not null comment '作者'
    )engine = innodb character set utf8 comment '测试数据表';
"""

获取数据库测试数据方法

# encoding = utf-8
"""
__title__ = ''
__author__ = 'davieyang'
__mtime__ = '2018/4/21'
"""
import pymysql
from TestData.SqlScripts import create_table
from TestData.SqlScripts import create_database
from TestData.SqlScripts import drop_table
 
 
class MySQL(object):
    def __init__(self, host, port, dbName, username, password, charset):
        self.conn = pymysql.connect(
            host=host,
            port=port,
            db=dbName,
            user=username,
            password=password,
            charset=charset
        )
        self.cur = self.conn.cursor()
 
    def create(self):
        try:
            self.cur.execute(create_database)
            self.conn.select_db("davieyang")
            self.cur.execute(drop_table)
            self.cur.execute(create_table)
            '''
            cur.execute("drop database if exists davieyang")   #如果davieyang数据库存在则删除  
            cur.execute("create database davieyang")   #新创建一个数据库davieyang  
            cur.execute("use davieyang")         #选择davieyang这个数据库  
            # sql 中的内容为创建一个名为testdata的表  
            sql = """create table testdata(id BIGINT,name VARCHAR(20),age INT DEFAULT 1)"""  #()中的参数可以自行设置  
            conn.execute("drop table if exists testdata") # 如果表存在则删除  
            conn.execute(sql)# 创建表    
            # 删除  
            # conn.execute("drop table testdata")  
            conn.close()# 关闭游标连接  
            connect.close()# 关闭数据库服务器连接 释放内存  
            '''
        except pymysql.Error as e:
            raise e
        else:
            self.cur.close()
            self.conn.commit()
            self.conn.close()
            print(u"创建数据库和表成功")
 
    def insertDatas(self):
        try:
            sql = "insert into testdata(bookname, author) values(%s, %s);"
            self.cur.executemany(sql, [('selenium xml DataDriven', 'davieyang'),
                                    ('selenium excel DataDriven', 'davieyang'),
                                    ('selenium ddt data list', 'davieyang')])
        except pymysql.Error as e:
            raise e
        else:
            self.conn.commit()
            print(u"初始数据插入成功")
            self.cur.execute("select * from testData;")
            for i in self.cur.fetchall():
                print(i[1], i[2])
            self.cur.close()
            self.conn.close()
 
 
    def getDataFromDataBase(self):
        # 从数据库中获取数据
        # bookname作为搜索关键词,author作为期望结果
        self.cur.execute("select bookname, author from testdata;")
        # 从查询区域取回所有查询结果
        dataTuple = self.cur.fetchall()
        return dataTuple
 
    def closeDataBase(self):
        # 数据库清理
        self.cur.close()
        self.conn.commit()
        self.conn.close()
 
 
if __name__ == "__main__":
    db = MySQL(
        host="localhost",
        port=3306,
        dbName="davieyang",
        username="root",
        password="root",
        charset="utf8"
    )
    print(db.getDataFromDataBase())
    db.closeDataBase()

测试脚本

# encoding = utf-8
"""
__title__ = ''
__author__ = 'davieyang'
__mtime__ = '2018/4/21'
"""
from selenium import webdriver
import unittest
import time
import logging
import traceback
import ddt
from Util.MysqlDBUtil import MySQL
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='F:\\DataDriven\\TestResults\TestResults.TestResults',
    # 打开日志的方式
    filemode='w'
)
 
 
def getTestDatas():
    db = MySQL(
        host="localhost",
        port=3306,
        dbName="davieyang",
        username="root",
        password="root",
        charset="utf8"
    )
    # 从数据库中获取测试数据
    testData = db.getDataFromDataBase()
    db.closeDataBase()
    return testData
 
@ddt.ddt
class DataDrivenByMySQL(unittest.TestCase):
 
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path=r"F:\automation\webdriver\chromedriver.exe")
 
    @ddt.data(* getTestDatas())
    def test_dataDrivenByMySQL(self, data):
        # 对获得的数据进行解包
        testData, expectData =data
        url = "http://www.baidu.com"
        self.driver.get(url)
        self.driver.maximize_window()
        print(testData, expectData)
        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 as e:
            logging.error(u"查找的页面元素不存在,异常堆栈信息为:" + str(traceback.format_exc()))
        except AssertionError as e:
            logging.info(u"搜索 ‘%s’,期望 ‘%s’ ,失败" % (testData, expectData))
        except Exception as 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()
# encoding = utf-8
"""
__title__ = ''
__author__ = 'davieyang'
__mtime__ = '2018/4/21'
"""
from selenium import webdriver
import unittest
import time
import logging
import 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='F:\\DataDriven\\TestResults\TestResults.TestResults',
    # 打开日志的方式
    filemode='w'
)
 
 
@ddt.ddt
class DataDrivenDDT(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path="F:\\automation\\webdriver\\chromedriver.exe")
 
    @ddt.data([u"阿里巴巴", u"腾讯"], [u"美团外卖", u"百度"], [u"饿了么", u"蚂蚁金服"])
    @ddt.unpack
    def test_dataDrivenByDDT(self, testdata, expectdata):
        url = "http://www.baidu.com"
        self.driver.get(url)
        self.driver.implicitly_wait(30)
        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 as e:
            logging.error(u"查找的页面元素不存在,异常堆栈信息:" + str(traceback.format_exc()))
        except AssertionError as e:
            logging.info(u"搜索 '%s',期望 '%s' ,失败" % (testdata, expectdata))
        except Exception as 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()

使用XML存储测试输入数据

<?xml version = "1.0" encoding = "utf-8"?>
<bookList type = "technology">
    <book>
        <name>selenium xml datadriven</name>
        <author>davieyang</author>
    </book>
    <book>
        <name>selenium excel datadriven</name>
        <author>davieyang</author>
    </book>
    <book>
        <name>selenium ddt data list</name>
        <author>davieyang</author>
    </book>
</bookList>

解析XML方法

# encoding = utf-8
"""
__title__ = ''
__author__ = 'davieyang'
__mtime__ = '2018/4/21'
"""
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组成的字典对象
        childrenTextDict = {i.tag: i.text for i in list(node.iter())[1:]}
        # 上面代码等价于
        '''
        childrenTextDict = {}
        for i in list(node.iter())[1:]:
            fhildrenTextDict[i.tag] = i.text
        '''
        return childrenTextDict
 
    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"F:\seleniumWithPython\TestData\TestData.xml")
    datas = xml.getDataFromXml()
    for i in datas:
        print(i["name"], i["author"])

测试脚本

# encoding = utf-8
"""
__title__ = ''
__author__ = 'davieyang'
__mtime__ = '2018/4/21'
"""
from selenium import webdriver
import unittest
import time
import logging
import traceback
import ddt
from Util.ParseXMLUtil 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:\\Programs\\Python\\PythonUnittest\\Reports\\TestResults.TestResults',
    # 打开日志的方式
    filemode='w'
)
 
# currentPath = os.path.dirname(os.path.abspath(__file__))
# dataFilePath = os.path.join(currentPath, "TestData.xml")
dataFilePath = "D:\\Programs\\Python\\PythonUnittest\\TestData\\TestData.xml"
print(dataFilePath)
 
# 创建ParseXML类实例对象
xml = ParseXML(dataFilePath)
 
 
@ddt.ddt
class DataDrivenTestByXML(unittest.TestCase):
 
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path=r"F:\automation\webdriver\chromedriver.exe")
 
    @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()
        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 as e:
            logging.error(u"查找的页面元素不存在,异常堆栈信息为:" + str(traceback.format_exc()))
        except AssertionError as e:
            logging.info(u"搜索 ‘%s’,期望 ‘%s’ ,失败" % (testData, expectData))
        except Exception as 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()


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/245443.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++随记

#include<bits/stdc.h> using namespace std; int main() { char* p "C Language"; cout<<p<<\n; cout<<p1<<\n; cout<<*p<<\n; cout<<*(p2)<<\n; } 随记 C Language Language C L 输出结果是p会输入整个字符…

【一秒梵高】基于OpenCV4实现图像九种风格迁移

风格迁移 图像风格迁移、色彩填充与色彩变换等&#xff0c;严格意义上来说都属于计算机视觉任务中图像处理的分支。它们输入的是图像&#xff0c;输出的也是图像&#xff0c;过程实现图像到图像的内容与风格的转换&#xff0c;深度学习在这类图像处理任务上也取得了良好的效果…

吴恩达深度学习L2W3作业

欢迎来到本周的编程作业。 到目前为止&#xff0c;你一直使用numpy来构建神经网络。现在&#xff0c;我们将引导你使用深度学习框架&#xff0c;该框架将使你可以更轻松地构建神经网络。TensorFlow&#xff0c;PaddlePaddle&#xff0c;Torch&#xff0c;Caffe&#xff0c;Kera…

小项目:迷宫

目录 引言1.题目描述及思想2.代码实现3.最终结果 引言 这个迷宫的话就是去年这时候&#xff0c;我记得当时讲这个的时候我还是一脸懵逼&#xff0c;就是事后花时间能够看懂&#xff0c;能够理解&#xff0c;但是自己肯定是不能够实现的&#xff0c;而且觉得这个东西非常的庞大…

一文讲清 QWidget 大小位置

一文讲清 QWidget 大小位置 前言 ​ QWidget 的位置基于桌面坐标系&#xff0c;以左上角为原点&#xff0c;向右x轴增加&#xff0c;向下y轴增加。 一、图解 ​ ​ 如上图所示&#xff0c;当窗口为顶层窗口时&#xff08;即没有任何父窗口&#xff09;&#xff0c;系统会自…

docker小白第三天

docker小白第三天 docker为什么会比虚拟机快 1、docker有着比虚拟机更少的抽象层。不需要Hypervisor实现硬件资源虚拟化&#xff0c;运行在docker容器上的程序直接使用的都是实际物理机的硬件资源&#xff0c;因此在CPU、内存利用率上docker将会在效率上有明显优势。 2、dock…

利用闭包与高阶函数实现缓存函数的创建

缓存函数是一种用于存储和重复利用计算结果的机制。其基本思想是&#xff0c;当一个函数被调用并计算出结果时&#xff0c;将该结果存储在某种数据结构中 (通常是一个缓存对象)以备将来使用。当相同的输入参数再次传递给函数时&#xff0c;不再执行实际的计算&#xff0c;而是直…

Unity 控制刚体的移动与旋转的方法

在场景创建一个Cube,并添加刚体&#xff0c;如图&#xff1a; 编写脚本&#xff1a; using System.Collections; using System.Collections.Generic; using UnityEngine;[RequireComponent(typeof(Rigidbody))] public class RibRotate : MonoBehaviour {//private Vector3 mo…

使用过滤器Filter实现请求拦截

早期使用servlet进行网络开发时&#xff0c;没有拦截器这些内容&#xff0c;那时做请求拦截都是使用Filter过滤器实现的&#xff0c;配置Filter要对哪些请求路径处理&#xff0c;有权限或不需要拦截的路径放行&#xff0c;没有权限的路径直接拦截请求。 一、Filter直接进行拦截…

JAVA架构师或者teamleader要了解的东西

一、java架构师必备基本知识 什么是Java中的内存泄漏?如何避免内存泄漏? Java中的内存泄漏是指程序在申请内存后,无法释放未再使用的内存空间。避免内存泄漏的方法包括:避免使用finalize方法,使用缓存时需要手动清理不再使用的对象,及时关闭资源等。 什么是Java中的多态…

dockerfile---创建镜像

dockerfile创建镜像&#xff1a;创建自定义镜像。 包扩配置文件的创建&#xff0c;挂载点&#xff0c;对外暴露的端口。设置环境变量。 docker镜像的方式: 1、基于官方源进行创建 根据官方提供的镜像源&#xff0c;创建镜像&#xff0c;然后拉起容器。是一个白板&#xff0c…

<JavaEE> 网络编程 -- 网络通信基础(协议和协议分层、数据封装和分用)

目录 一、IP地址 1&#xff09;IP地址的概念 2&#xff09;IP地址的格式 二、端口号 1&#xff09;端口号的概念 2&#xff09;端口号的格式 3&#xff09;什么是知名端口号&#xff1f; 三、协议 1&#xff09;协议的概念 2&#xff09;协议的作用 3&#xff09;TC…

IBIS AMI Model 算法模式的选择

常规的信号完整性仿真&#xff0c;只会包含传统的基于IBIS的芯片行为级模型&#xff0c;但高速串行总线在使用过程中&#xff0c;经常会由于传输信道或链路过长以及信号频率较高而造成信号衰减过大&#xff0c;接收端无法正确判别信号&#xff0c;因此&#xff0c;这类SerDes芯…

Amazon SageMaker:让机器学习变得更简单、更强大

授权说明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道。 前言&#xff1a; 在大数据时代的浪潮中&#xff0c;数据不再只…

指令数据:训练大模型的“隐形助力”

作者&#xff1a;谭婧 &#xff08;一&#xff09;指令数据&#xff0c;了解一下 先聊一件圈内趣事&#xff1a; 2023年初&#xff0c;大约在1月到2月份前后&#xff0c; 百度公司如流工作卡上有一个任务&#xff0c; 让百度员工打开脑洞&#xff0c;写“问答对”。 一问一答都…

HashMap常见面试问题

简述HashMap原理&#xff1f; HashMap基于数组加链表的方式来实现&#xff0c;数组下标通过hash值来计算&#xff0c;当下表冲突时&#xff0c;就会进行遍历链表&#xff0c;当链表长度大于8的时候会转化为红黑树。 HashMap的put过程&#xff1f; put的第一步是计算hash值&a…

什么时候使用匿名类,匿名类解决了什么问题?为什么需要匿名类 ?

匿名类通常在以下场景下使用&#xff1a; 一次性使用&#xff1a; 当你需要创建一个类的实例&#xff0c;但该类只在一个地方使用&#xff0c;而不打算在其他地方重复使用时&#xff0c;可以考虑使用匿名类。 简化代码&#xff1a; 当创建一个小型的、一次性的类会让代码更简洁…

VUE中如果让全局组件在某一页面不显示

目录 前言 方法一 1.在全局组件中添加一个变量用于控制显示与隐藏。 2.在全局组件的模板中使用 v-if 条件来决定是否显示该组件 3.在不需要显示全局组件的页面中&#xff0c;修改 showGlobalComponent 变量的值为 false&#xff0c;以隐藏全局组件。 4.在需要隐藏全局组…

TrustZone之总线请求

接下来&#xff0c;我们将查看系统中的总线请求者&#xff0c;如下图所示&#xff1a; 系统中的A型处理器具有TrustZone感知&#xff0c;并在每个总线访问中发送正确的安全状态。然而&#xff0c;大多数现代SoC还包含非处理器总线请求者&#xff0c;例如GPU和DMA控制器。 与完成…

​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展

在数字化时代&#xff0c;云计算成为推动创新和业务发展的关键驱动力。Amazon Lightsail 作为亚马逊云科技家族中的一员轻量应用服务器&#xff0c;为小型企业和创业公司提供了简便、强大的云计算服务。无论您是刚刚起步的初创公司&#xff0c;还是需要灵活而高效的云解决方案&…