水果網(wǎng)站策劃書優(yōu)化大師免費(fèi)版
前情提要
請(qǐng)確保已經(jīng)熟練掌握元素定位的常用方法及基本支持,請(qǐng)參考Python自動(dòng)化測(cè)試系列[v1.0.0][元素定位]
數(shù)據(jù)驅(qū)動(dòng)測(cè)試是自動(dòng)化測(cè)試中一種重要的設(shè)計(jì)模式,這種設(shè)計(jì)模式可以將測(cè)試數(shù)據(jù)和測(cè)試代碼分開(kāi),實(shí)現(xiàn)數(shù)據(jù)與代碼解耦,與此同時(shí)還能夠?qū)崿F(xiàn)一次任務(wù)中使用不同的數(shù)據(jù)來(lái)執(zhí)行執(zhí)行相同的測(cè)試腳本,因此它會(huì)使得我們的代碼層次結(jié)構(gòu)清晰,容易維護(hù),并且大大降低了代碼量
數(shù)據(jù)驅(qū)動(dòng)是自動(dòng)化測(cè)試中非常常見(jiàn)的一種設(shè)計(jì)模式,應(yīng)用的場(chǎng)景非常多,無(wú)論是在Web自動(dòng)化還是在接口自動(dòng)化、單元測(cè)試,亦或是在數(shù)據(jù)分析應(yīng)用領(lǐng)域的測(cè)試上都會(huì)得到非常廣泛的使用,常見(jiàn)的比如Web自動(dòng)化的登錄功能、一些錄入類的功能,再比如接口入?yún)?、單元測(cè)試的入?yún)?#xff0c;甚至在數(shù)據(jù)類應(yīng)用的大量數(shù)據(jù)輸入及結(jié)果比較上
使用Excel存儲(chǔ)測(cè)試輸入數(shù)據(jù)
數(shù)據(jù)文件
假如我們有如下一組數(shù)據(jù)存儲(chǔ)在Excel里
序號(hào) | 檢索詞 | 期望結(jié)果 |
---|---|---|
1 | 北京 | 北京 |
2 | 上海 | 上海 |
3 | 廣州 | 廣州 |
獲取測(cè)試數(shù)據(jù)方法
通過(guò)python的openpyxl模塊解析Excel文件,并獲取數(shù)據(jù)
安裝openpyxl
C:\Users\Administrator>pip install openpyxl
Collecting openpyxlDownloading openpyxl-3.0.3.tar.gz (172 kB)|████████████████████████████████| 172 kB 384 kB/s
Collecting jdcalUsing cached jdcal-1.4.1-py2.py3-none-any.whl (9.5 kB)
Collecting et_xmlfileUsing cached et_xmlfile-1.0.1.tar.gz (8.4 kB)
Installing collected packages: jdcal, et-xmlfile, openpyxlRunning setup.py install for et-xmlfile ... doneRunning 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_workbookclass 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_rowdef 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 dataListif __name__ == '__main__':excelPath = u'D:\\Programs\\Python\\PythonUnittest\\TestData\\測(cè)試數(shù)據(jù).xlsx'sheetName = u'搜索數(shù)據(jù)表'pe = ParseExcel(excelPath, sheetName)for i in pe.getDatasFromSheet():print(i[0], i[1])
封裝了getDatasFromSheet方法,該方法將解析Excel,并將數(shù)據(jù)存到List中去,后續(xù)的測(cè)試代碼調(diào)用的實(shí)際上是從List里邊獲取數(shù)據(jù)
測(cè)試代碼
# 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# 初始化日志對(duì)象
logging.basicConfig(# 日志級(jí)別level=logging.INFO,# 時(shí)間、代碼所在文件名、代碼行號(hào)、日志級(jí)別名字、日志信息format='%(asctime)s %(filename)s[line: %(lineno)d] %(levelname)s %(message)s',# 打印日志的時(shí)間datefmt='%a, %d %b %Y %H:%M:%S',# 日志文件存放的目錄及日志文件名filename='D:\\Programs\\Python\\PythonUnittest\\Reports\\TestResults.TestResults',# 打開(kāi)日志的方式filemode='w'
)excelPath = u"D:\\Programs\\Python\\PythonUnittest\\TestData\\測(cè)試數(shù)據(jù).xlsx"
sheetName = u"搜索數(shù)據(jù)表"
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"查找的頁(yè)面元素不存在,異常堆棧信息為:" + str(traceback.format_exc()))except AssertionError as e:logging.info(u"搜索 ‘%s’,期望 ‘%s’ ,失敗" % (testData, expectData))except Exception as e:logging.error(u"未知錯(cuò)誤,錯(cuò)誤信息:" + str(traceback.format_exc()))else:logging.info(u"搜索 ‘%s’,期望 ‘%s’ ,通過(guò)" % (testData, expectData))def tearDown(self):self.driver.quit()
if __name__ == "__main__":unittest.main()
使用Parameterize模塊組織數(shù)據(jù)集作為測(cè)試輸入數(shù)據(jù)
安裝PARAMETERIZE
C:\Users\Administrator>pip install parameterized
Collecting parameterizedDownloading 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
測(cè)試代碼
# -*- 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.driverdriver.get(self.url)# 定義frame,他是頁(yè)面中的iframe控件frame = self.driver.find_element_by_xpath("//*[@id='loginDiv']/iframe")time.sleep(1)try:self.driver.switch_to.frame(frame) # 切換進(jìn)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() # 點(diǎn)擊登陸按鈕except NoSuchElementException as e:# 將未找到頁(yè)面元素的異常記錄進(jìn)日志raise eexcept Exception as e:raise e@parameterized.expand([('', "davieyang", "請(qǐng)輸入帳號(hào)"),("davieyang", '', "請(qǐng)輸入密碼"),("error", "error", "帳號(hào)或密碼錯(cuò)誤"),])def test_login(self, username, password, assert_text):self.user_login_163(username, password)message = self.driver.find_element_by_id("nerror").textself.assertEqual(message, assert_text)def tearDown(self):self.driver.quit()if __name__ == '__main__':unittest.main(verbosity=2)
使用JSON存儲(chǔ)測(cè)試輸入數(shù)據(jù)[List]
方式一
["北京||北京","上海||上海","廣州||廣州","深圳||深圳","香港||香港"
]
測(cè)試代碼
# 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# 初始化日志對(duì)象
logging.basicConfig(# 日志級(jí)別level=logging.INFO,# 時(shí)間、代碼所在文件名、代碼行號(hào)、日志級(jí)別名字、日志信息format='%(asctime)s %(filename)s[line: %(lineno)d] %(levelname)s %(message)s',# 打印日志的時(shí)間datefmt='%a, %d %b %Y %H:%M:%S',# 日志文件存放的目錄及日志文件名filename='F:\\DataDriven\\TestResults\TestResults.TestResults',# 打開(kāi)日志的方式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文件中讀取出的數(shù)據(jù)用“||”分割成測(cè)試數(shù)據(jù)和期望的數(shù)據(jù)testdata, execptdata = tuple(value.strip().split("||"))# 設(shè)置隱式等待時(shí)間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)# 斷言期望結(jié)果是否出現(xiàn)在頁(yè)面中self.assertTrue(execptdata in self.driver.page_source)except NoSuchElementException as e:logging.error(u"查找的頁(yè)面元素不存在,異常堆棧信息為:" + str(traceback.format_exc()))except AssertionError as e:logging.info(u"搜索 '%s',期望 '%s' ,失敗" % (testdata, execptdata))except Exception as e:logging.error(u"未知錯(cuò)誤,錯(cuò)誤信息:" + str(traceback.format_exc()))else:logging.info(u"搜索 '%s',期望 '%s' ,通過(guò)" % (testdata, execptdata))def tearDown(self):self.driver.quit()if __name__ == '__main__':unittest.main()
方式二
測(cè)試報(bào)告模板
# 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>單元測(cè)試報(bào)告</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:15pxtext-align:center}.tableStyle th{padding:15px;background-color:rgb(146,208,80);/*表格標(biāo)題欄設(shè)置漸變顏色*/background-image: -webkit -gradient(linear, left top, left bottom, from(#92D050), to(#A2D668))/*rgb(146,208,80)*/} </style></head><body><center><h1>測(cè)試報(bào)告</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 + endStrprint(html)with open("D:\\\Programs\\\Python\\\PythonUnittest\\\Reports\\testTemplate.html", "wb") as fp:fp.write(html.encode("gbk"))
測(cè)試腳本
# 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# 初始化日志對(duì)象
logging.basicConfig(# 日志級(jí)別level=logging.INFO,# 時(shí)間、代碼所在文件名、代碼行號(hào)、日志級(jí)別名字、日志信息format='%(asctime)s %(filename)s[line: %(lineno)d] %(levelname)s %(message)s',# 打印日志的時(shí)間datefmt='%a, %d %b %Y %H:%M:%S',# 日志文件存放的目錄及日志文件名filename='D:\\Programs\\Python\\PythonUnittest\\Reports\\TestResults.TestResults',# 打開(kāi)日志的方式filemode='w'
)@ddt.ddt
class DataDrivenTestByDDT(unittest.TestCase):@classmethoddef setUpClass(cls):# 整個(gè)測(cè)試過(guò)程只調(diào)用一次DataDrivenTestByDDT.trStr = ""def setUp(self):self.driver = webdriver.Chrome(executable_path="D:\\Programs\\Python\\PythonUnittest\\BrowserDrivers\\chromedriver.exe")status = None # 用于存放測(cè)試結(jié)果狀態(tài),失敗‘fail’,成功‘pass’flag = 0 # 數(shù)據(jù)驅(qū)動(dòng)測(cè)試結(jié)果的標(biāo)志,失敗置0,成功置1@ddt.file_data("D:\\Programs\\Python\\PythonUnittest\\TestData\\test_data_list.json")def test_dataDrivenByFile(self, value):# 決定測(cè)試報(bào)告中狀態(tài)單元格中內(nèi)容的顏色flagDict = {0: 'red', 1: '#00AC4E'}url = "http://www.baidu.com"self.driver.get(url)self.driver.maximize_window()print(value)# 從.json文件中讀取出的數(shù)據(jù)用“||”分割成測(cè)試數(shù)據(jù)和期望的數(shù)據(jù)testdata, execptdata = tuple(value.strip().split("||"))# 設(shè)置隱式等待時(shí)間self.driver.implicitly_wait(10)try:# 獲取當(dāng)前的時(shí)間戳,用于后面計(jì)算查詢耗時(shí)用start = time.time()# 獲取當(dāng)前時(shí)間的字符串,表示測(cè)試開(kāi)始時(shí)間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)# 斷言期望結(jié)果是否出現(xiàn)在頁(yè)面中self.assertTrue(execptdata in self.driver.page_source)except NoSuchElementException as e:logging.error(u"查找的頁(yè)面元素不存在,異常堆棧信息為:"+ str(traceback.format_exc()))status = 'fail'flag = 0except AssertionError as e:logging.info(u"搜索 ‘%s’,期望 ‘%s’ ,失敗" %(testdata, execptdata))status = 'fail'flag = 0except Exception as e:logging.error(u"未知錯(cuò)誤,錯(cuò)誤信息:" + str(traceback.format_exc()))status = 'fail'flag = 0else:logging.info(u"搜索 ‘%s’,期望 ‘%s’ ,通過(guò)" %(testdata, execptdata))status = 'pass'flag = 1# 計(jì)算耗時(shí),從將測(cè)試數(shù)據(jù)輸入到輸入框中到斷言期望結(jié)果之間所耗時(shí)wasteTime = time.time() - start - 3 # 減去強(qiáng)制等待3秒# 每一組數(shù)據(jù)測(cè)試結(jié)束后,都將其測(cè)試結(jié)果信息插入表格行的HTML代碼中,并將這些行HTML代碼拼接到變量trStr變量中,# 等所有測(cè)試數(shù)據(jù)都被測(cè)試結(jié)束后,傳入htmlTemplate()函數(shù)中,生成完整測(cè)試報(bào)告的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()@classmethoddef tearDownClass(cls):# 寫自定義的HTML測(cè)試報(bào)告,整個(gè)過(guò)程只被調(diào)用一次htmlTemplate(DataDrivenTestByDDT.trStr)if __name__ == '__main__':unittest.main()
生成日志
Fri, 07 Dec 2018 15:05:36 DataDrivenTestByDDT.py[line: 81] INFO 搜索 ‘北京’,期望 ‘北京’ ,通過(guò)
Fri, 07 Dec 2018 15:05:50 DataDrivenTestByDDT.py[line: 81] INFO 搜索 ‘上?!?期望 ‘上?!?,通過(guò)
Fri, 07 Dec 2018 15:06:04 DataDrivenTestByDDT.py[line: 81] INFO 搜索 ‘廣州’,期望 ‘廣州’ ,通過(guò)
Fri, 07 Dec 2018 15:06:18 DataDrivenTestByDDT.py[line: 81] INFO 搜索 ‘深圳’,期望 ‘深圳’ ,通過(guò)
Fri, 07 Dec 2018 15:06:32 DataDrivenTestByDDT.py[line: 81] INFO 搜索 ‘香港’,期望 ‘香港’ ,通過(guò)
HTML報(bào)告
使用JSON存儲(chǔ)測(cè)試輸入數(shù)據(jù)[字典]
除了在json文件中放置List類型的數(shù)據(jù),還可以放置Dict類型的數(shù)據(jù),在PO項(xiàng)目的TestData路徑下新建一個(gè)文件,并命名為login.json,然后在文件中寫入如下測(cè)試數(shù)據(jù)。
{"test_login_01": {"username":"","password":"davieyang","assert_text": "請(qǐng)輸入帳號(hào)"},"test_login_02": {"username":"davieyang","password":"","assert_text": "請(qǐng)輸入密碼"},"test_login_03":{"username":"error","password":"error","assert_text": "帳號(hào)或密碼錯(cuò)誤"}
}
測(cè)試腳本
# -*- 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
# 定義測(cè)試數(shù)據(jù)文件
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.driverdriver.get(self.url)# 定義frame,他是頁(yè)面中的iframe控件frame = self.driver.find_element_by_xpath("//*[@id='loginDiv']/iframe")time.sleep(1)try:self.driver.switch_to.frame(frame) # 切換進(jìn)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() # 點(diǎn)擊登陸按鈕except NoSuchElementException as e:# 將未找到頁(yè)面元素的異常記錄進(jìn)日志raise eexcept Exception as e:raise e@file_data(login_json)def test_login(self, username, password, assert_text): # 定義測(cè)試方法self.user_login_163(username, password) # 調(diào)用登陸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存儲(chǔ)測(cè)試輸入數(shù)據(jù)
測(cè)試數(shù)據(jù)
# encoding = utf-8create_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 '測(cè)試數(shù)據(jù)表';
"""
獲取數(shù)據(jù)庫(kù)測(cè)試數(shù)據(jù)方法
# 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_tableclass 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數(shù)據(jù)庫(kù)存在則刪除 cur.execute("create database davieyang") #新創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)davieyang cur.execute("use davieyang") #選擇davieyang這個(gè)數(shù)據(jù)庫(kù) # sql 中的內(nèi)容為創(chuàng)建一個(gè)名為testdata的表 sql = """create table testdata(id BIGINT,name VARCHAR(20),age INT DEFAULT 1)""" #()中的參數(shù)可以自行設(shè)置 conn.execute("drop table if exists testdata") # 如果表存在則刪除 conn.execute(sql)# 創(chuàng)建表 # 刪除 # conn.execute("drop table testdata") conn.close()# 關(guān)閉游標(biāo)連接 connect.close()# 關(guān)閉數(shù)據(jù)庫(kù)服務(wù)器連接 釋放內(nèi)存 '''except pymysql.Error as e:raise eelse:self.cur.close()self.conn.commit()self.conn.close()print(u"創(chuàng)建數(shù)據(jù)庫(kù)和表成功")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 eelse:self.conn.commit()print(u"初始數(shù)據(jù)插入成功")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):# 從數(shù)據(jù)庫(kù)中獲取數(shù)據(jù)# bookname作為搜索關(guān)鍵詞,author作為期望結(jié)果self.cur.execute("select bookname, author from testdata;")# 從查詢區(qū)域取回所有查詢結(jié)果dataTuple = self.cur.fetchall()return dataTupledef closeDataBase(self):# 數(shù)據(jù)庫(kù)清理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()
測(cè)試腳本
# 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# 初始化日志對(duì)象
logging.basicConfig(# 日志級(jí)別level=logging.INFO,# 時(shí)間、代碼所在文件名、代碼行號(hào)、日志級(jí)別名字、日志信息format='%(asctime)s %(filename)s[line: %(lineno)d] %(levelname)s %(message)s',# 打印日志的時(shí)間datefmt='%a, %d %b %Y %H:%M:%S',# 日志文件存放的目錄及日志文件名filename='F:\\DataDriven\\TestResults\TestResults.TestResults',# 打開(kāi)日志的方式filemode='w'
)def getTestDatas():db = MySQL(host="localhost",port=3306,dbName="davieyang",username="root",password="root",charset="utf8")# 從數(shù)據(jù)庫(kù)中獲取測(cè)試數(shù)據(jù)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):# 對(duì)獲得的數(shù)據(jù)進(jìn)行解包testData, expectData =dataurl = "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"查找的頁(yè)面元素不存在,異常堆棧信息為:" + str(traceback.format_exc()))except AssertionError as e:logging.info(u"搜索 ‘%s’,期望 ‘%s’ ,失敗" % (testData, expectData))except Exception as e:logging.error(u"未知錯(cuò)誤,錯(cuò)誤信息:" + str(traceback.format_exc()))else:logging.info(u"搜索 ‘%s’,期望 ‘%s’ ,通過(guò)" % (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# 初始化日志對(duì)象
logging.basicConfig(# 日志級(jí)別level=logging.INFO,# 時(shí)間、代碼所在文件名、代碼行號(hào)、日志級(jí)別名字、日志信息format='%(asctime)s %(filename)s[line: %(lineno)d] %(levelname)s %(message)s',# 打印日志的時(shí)間datefmt='%a, %d %b %Y %H:%M:%S',# 日志文件存放的目錄及日志文件名filename='F:\\DataDriven\\TestResults\TestResults.TestResults',# 打開(kāi)日志的方式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"美團(tuán)外賣", u"百度"], [u"餓了么", u"螞蟻金服"])@ddt.unpackdef 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"查找的頁(yè)面元素不存在,異常堆棧信息:" + str(traceback.format_exc()))except AssertionError as e:logging.info(u"搜索 '%s',期望 '%s' ,失敗" % (testdata, expectdata))except Exception as e:logging.error(u"未知錯(cuò)誤,錯(cuò)誤信息:" + str(traceback.format_exc()))else:logging.info(u"搜索 '%s',期望 '%s' ,通過(guò)" % (testdata, expectdata))def tearDown(self):self.driver.quit()if __name__ == '__main__':unittest.main()
使用XML存儲(chǔ)測(cè)試輸入數(shù)據(jù)
<?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 ElementTreeclass ParseXML(object):def __init__(self, xmlPath):self.xmlPath = xmlPathdef getRoot(self):# 打開(kāi)將要解析的XML文件tree = ElementTree.parse(self.xmlPath)# 獲取XML文件的根節(jié)點(diǎn)對(duì)象,然后返回給調(diào)用者return tree.getroot()def findNodeByName(self, parentNode, nodeName):# 通過(guò)節(jié)點(diǎn)的名字獲取節(jié)點(diǎn)對(duì)象nodes = parentNode.findall(nodeName)return nodesdef getNodeofChildText(self, node):# 獲取節(jié)點(diǎn)node下所有子節(jié)點(diǎn)的節(jié)點(diǎn)名作為key,本節(jié)點(diǎn)作為value組成的字典對(duì)象childrenTextDict = {i.tag: i.text for i in list(node.iter())[1:]}# 上面代碼等價(jià)于'''childrenTextDict = {}for i in list(node.iter())[1:]:fhildrenTextDict[i.tag] = i.text'''return childrenTextDictdef getDataFromXml(self):# 獲取XML文檔的根節(jié)點(diǎn)對(duì)象root = self.getRoot()# 獲取根節(jié)點(diǎn)下所有名為book的節(jié)點(diǎn)對(duì)象books = self.findNodeByName(root, "book")dataList = []# 遍歷獲取到的所有book節(jié)點(diǎn)對(duì)象# 取得需要的測(cè)試數(shù)據(jù)for book in books:childrenText = self.getNodeofChildText(book)dataList.append(childrenText)return dataListif __name__ == "__main__":xml = ParseXML(r"F:\seleniumWithPython\TestData\TestData.xml")datas = xml.getDataFromXml()for i in datas:print(i["name"], i["author"])
測(cè)試腳本
# 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# 初始化日志對(duì)象
logging.basicConfig(# 日志級(jí)別level=logging.INFO,# 時(shí)間、代碼所在文件名、代碼行號(hào)、日志級(jí)別名字、日志信息format='%(asctime)s %(filename)s[line: %(lineno)d] %(levelname)s %(message)s',# 打印日志的時(shí)間datefmt='%a, %d %b %Y %H:%M:%S',# 日志文件存放的目錄及日志文件名filename='D:\\Programs\\Python\\PythonUnittest\\Reports\\TestResults.TestResults',# 打開(kāi)日志的方式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)# 創(chuàng)建ParseXML類實(shí)例對(duì)象
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"查找的頁(yè)面元素不存在,異常堆棧信息為:" + str(traceback.format_exc()))except AssertionError as e:logging.info(u"搜索 ‘%s’,期望 ‘%s’ ,失敗" % (testData, expectData))except Exception as e:logging.error(u"未知錯(cuò)誤,錯(cuò)誤信息:" + str(traceback.format_exc()))else:logging.info(u"搜索 ‘%s’,期望 ‘%s’ ,通過(guò)" % (testData, expectData))def tearDown(self):self.driver.quit()if __name__ == "__main__":unittest.main()