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

news2024/11/25 10:55:12

前情提要

请确保已经熟练掌握元素定位的常用方法及基本支持,请参考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()


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

openHarmony添加system_basic权限安装报错

openHarmony添加system_basic权限安装报错 12/14 13:49:57: Install Failed: [Info]App install path:D:\huawei\project\FCTTest\entry\build\default\outputs\default\entry-default-signed.hap, queuesize:0, msg:error: failed to install bundle. error: install failed …

k8s常用命令及示例(三):apply 、edit、delete

k8s常用命令及示例(三)&#xff1a;apply 、edit、delete 1. kubectl apply -f 命令&#xff1a;从yaml文件中创建资源对象。 -f 参数为强制执行。kubectl apply和kubectl create的区别如下&#xff1a;kubectl create 和 kubectl apply 是 Kubernetes 中两个常用的命令&…

若依打包将vue放到.jar里面部署

1.vue静态文件&#xff0c;以及单页面 ruoyi-admin\src\main\resources\static \ruoyi-admin\src\main\resources\templates 2.后台开放白名单 "/cms", "/cms#/login" 3. mvc访问vue页面入口&#xff0c;接口 package com.ruoyi.web.controller.syst…

信号继电器 DX-31B DC220V 电压型 带板前接线底座

系列型号 DX-31B信号继电器DX-31BJ信号继电器 DX-32A信号继电器DX-32AJ信号继电器 DX-32B信号继电器DX-32BJ信号继电器 DX-31A信号继电器DX-33/1信号继电器 DX-33/2信号继电器DX-33/3信号继电器 DX-33/4信号继电器DX-33/5信号继电器 一. 继电器用途 DX-30系列信号继电器…

从池化的角度看GNN(包含PR-GNN,EdgePool等7篇论文)下篇

从池化的角度看GNN&#xff08;包含PR-GNN&#xff0c;EdgePool等7篇论文&#xff09;下篇 前言一些总结一些早期论文的简要介绍5️⃣论文StructPool&#xff1a;《StructPool: Structured Graph Pooling via Conditional Random Fields》6️⃣论文ASAP&#xff1a;《ASAP: Ada…

Kotlin 笔记 -- Kotlin 语言特性的理解(二)

都是编译成字节码&#xff0c;为什么 Kotlin 能支持 Java 中没有的特性&#xff1f; kotlin 有哪些 Java 中没有的特性&#xff1a; 类型推断、可变性、可空性自动拆装箱、泛型数组高阶函数、DSL顶层函数、扩展函数、内联函数伴生对象、数据类、密封类、单例类接口代理、inter…

Linux ed命令教程:如何使用ed命令编辑文本文件(附案例详解和注意事项)

Linux ed命令介绍 ed命令是Linux中的一个简单文本编辑器。它是一种基于行的文本编辑器&#xff0c;用于创建、修改和操作文本文件。它是Unix中最早的编辑器&#xff0c;后来被vi和emacs文本编辑器所取代。 Linux ed命令适用的Linux版本 ed命令在大多数Linux发行版中都可以使…

华为战略管理的核心工具与方法论:五看三定之“三定”定什么

上一篇文章&#xff0c;华研荟介绍了华为在战略管理中使用的工具之一&#xff1a;五看三定中的五看含义和主要的一些工具&#xff08;模型&#xff09;&#xff0c;今天继续为您介绍“三定”。 在“五看”中&#xff0c;最后一看是“看机会”&#xff0c;将我们面临的各种可能…

[Linformer]论文实现:Linformer: Self-Attention with Linear Complexity

文章目录 一、完整代码二、论文解读2.1 介绍2.2 Self-Attention is Low Rank2.3 模型架构2.4 结果 三、整体总结 论文&#xff1a;Linformer: Self-Attention with Linear Complexity 作者&#xff1a;Sinong Wang, Belinda Z. Li, Madian Khabsa, Han Fang, Hao Ma 时间&#…

Leetcode—1822.数组元素积的符号【简单】

2023每日刷题&#xff08;五十九&#xff09; Leetcode—1822.数组元素积的符号 实现代码 class Solution { public:int arraySign(vector<int>& nums) {int neg 0;for(int i 0; i < nums.size(); i) {if(nums[i] 0) {return 0;}if(nums[i] < 0) {neg;}}i…

机器人制作开源方案 | 智能助老机器人

作者&#xff1a;刘颖、王浩宇、党玉娟 单位&#xff1a;北京科技大学 指导老师&#xff1a;刘新洋、栗琳 1. 项目背景 1.1 行业背景 随着越来越多的服务机器人进入家庭&#xff0c;应用场景呈现多元化和专业化&#xff0c;机器人产业生态体系正在不断完善&#xff0c;服务…

亚马逊云科技发布企业生成式AI助手Amazon Q,助力企业迈向智能化时代

&#xff08;声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区、知乎、自媒体平台、第三方开发者媒体等亚马逊云科技官方渠道&#xff09; 一、前言 随着人工智能技术的快速发展和广泛应用&#xff0c;我们…

数据结构篇-双向循环链表

目录 一、学习目标 二、概念 节点设计&#xff1a; 节点初始化&#xff08;链表初始化&#xff09;&#xff1a; 节点头插&#xff1a; 插入数据的变形&#xff1a; 遍历显示&#xff1a; 有序插入&#xff1a; 四、总结 一、学习目标 知识点&#xff1a; 一文掌握数据…

芒果RT-DETR改进实验:深度集成版目标检测 RT-DETR 热力图来了!支持自定义数据集训练出来的模型

💡该教程为改进RT-DETR指南,属于《芒果书》📚系列,包含大量的原创改进方式🚀 💡🚀🚀🚀内含改进源代码 按步骤操作运行改进后的代码即可💡更方便的统计更多实验数据,方便写作 芒果RT-DETR改进实验:深度集成版目标检测 RT-DETR 热力图来了!支持自定义数据集…

103基于matlab的极限学习机(ELM)和改进的YELM和集成极限学习机(EELM)是现在流行的超强学习机

基于matlab的极限学习机&#xff08;ELM&#xff09;和改进的YELM和集成极限学习机(EELM)是现在流行的超强学习机&#xff0c;该程序是三者的方法比对。 包括学习时间&#xff0c;训练精度和测试精度的对比。数据可更换自己 的&#xff0c;程序已调通&#xff0c;可直接运行…

【带头学C++】----- 九、类和对象 ---- 9.13 运算符重载——9.13.9 设计MyString类案例

❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️创做不易&#xff0c;麻烦点个关注❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️ ❤️❤️❤️❤️❤️❤️❤️❤️❤️文末有惊喜&#xff01;献舞一支&#xff01;❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️ 目录 9.13…

Ps:曲线的基本操作

在曲线上通过添加控制点&#xff0c;然后拖动或编辑这些控制点就可实现对图像的精细调整。 添加控制点 方法一&#xff1a; 直接在曲线上点击&#xff0c;即可添加控制点。 方法二&#xff1a; 使用目标调整工具时&#xff0c;在图像上单击&#xff0c;即可添加控制点。若按住并…

【重点】23.合并K个升序链表

题目 法1&#xff1a;分治合并 class Solution {public ListNode mergeKLists(ListNode[] lists) {return merge(lists, 0, lists.length - 1);}public ListNode merge(ListNode[] lists, int l, int r) {if (l > r) {return null;}if (l r) {return lists[l];}int mid l…

我对迁移学习的一点理解——领域适应(系列3)

文章目录 1. 领域适应&#xff08;Domain Adaptation&#xff09;的基本概念2.领域适应&#xff08;Domain Adaptation&#xff09;的目标3.领域适应&#xff08;Domain Adaptation&#xff09;的实现方法4.领域适应&#xff08;Domain Adaptation&#xff09;的可以解决的问题…

VRRP协议与原理

文章目录 VRRP协议与原理一、VRRP 协议二、单网关和多网管的缺陷1、单网关缺陷2、多网管的缺陷 三、VRRP基本概述四、VRRP工作原理1、VRRP主备份备份工作工程2、VRRP 主备路由器切换过程3、VRRP 负载分担工作过程 五、VRRP配置命令1、vrrp配置命令2、配置VRRP步骤&#xff1a; …