2、练习:使用excel,使用关键字驱动,实现一个搜狗搜索
4个关键字:访问某个网站、输入文字、点击搜索按钮、断言
普通脚本如下:
test_no_keyword.py
#encoding=utf-8
from selenium import webdriver
import time
driver = webdriver.Firefox(executable_path = "D:\\geckodriver")
driver.maximize_window()
driver.get("http://www.sogou.com")
search_box = driver.find_element_by_id("query")
search_box.send_keys(u"光荣之路 吴老师")
button = driver.find_element_by_id("stb")
button.click()
time.sleep(3)
assert u"财富自由" in driver.page_source
driver.quit()
关键字驱动如下:
Excel数据列
动作(方法名),定位方式,定位表达式,操作值,执行结果
browser,,,firefox
visit_url,,,http://www.sogou.com
input,id,query,光荣之路 吴老师
click,id,stb
sleep,,,2
assert_word,,,财富自由
quit,,,
需要将以上数据通过框架拼接成可执行函数调用,再通过eval执行
browser("firefox")
visit_url("http://www.sogou.com")
input("id","query",u"光荣之路 吴老师")
click("id","stb")
sleep(2)
assert_word(u"财富自由")
quit()
创建一个工程sogou_search_keyword_driven
工程下创建一个包Util,项下放解析Excel的模块
ParseExcel.py,解析Excel类,内容如下:
# encoding=utf-8
import openpyxl
from openpyxl.styles import Border, Side, Font
import time
class ParseExcel(object):
def __init__(self):
self.workbook = None
self.excelFile = None
self.font = Font(color = None) #设置字体的颜色
#颜色对应的RGB值
self.RGBDict = {"red":"FFFF0303","green":"FF008B00"}
def loadWorkbook(self,excelPathAndName):
#将excel文件加载到内存,并获取其workbook对象
try:
self.workbook = openpyxl.load_workbook(excelPathAndName)
except Exception,e:
raise e
self.excelFile = excelPathAndName
return self.workbook
def getSheetByName(self,sheetName):
#根据sheet名获取该sheet对象
try:
sheet = self.workbook.get_sheet_by_name(sheetName)
return sheet
except Exception,e:
raise e
def getSheetByIndex(self,sheetIndex):
#根据sheet的索引号获取该sheet对象
try:
sheetName = self.workbook.get_sheet_names()[sheetIndex]
except Exception,e:
raise e
sheet = self.workbook.get_sheet_by_name(sheetName)
return sheet
def getRowsNumber(self,sheet):
#获取sheet中有数据区域的结束行号
return sheet.max_row
def getColsNumber(self,sheet):
#获取sheet中有数据区域的结束列号
return sheet.max_column
def getStartRowNumber(self,sheet):
#获取sheet中有数据区域的开始行号
return sheet.min_row
def getStartColNumber(self,sheet):
#获取sheet中有数据区域的开始列号
return sheet.min_column
def getRow(self,sheet,rowNo):
#获取sheet中某一行,返回的是这一行所有的数据内容组成的tuple
#下标从1开始,sheet.rows[1]表示第一行
try:
rows = []
for row in sheet.iter_rows():
rows.append(row)
return rows[rowNo - 1]
except Exception , e:
raise e
def getColumn(self,sheet,colNo):
#获取sheet中某一列,返回的是这一列所有数据内容组成的tuple
#下标从1开始,sheet,columns[1]表示第一列
try:
cols = []
for col in sheet.iter_cols():
cols.append(col)
return cols[colNo - 1]
except Exception,e:
raise e
def getAllRows(self,sheet):
#获取sheet中所有行
try:
rows = []
for row in sheet.iter_rows():
rows.append(row)
return rows
except Exception , e:
raise e
def getAllColumns(self,sheet):
#获取sheet中所有列
try:
cols = []
for col in sheet.iter_cols():
cols.append(col)
return cols
except Exception,e:
raise e
def getCellOfValue(self,sheet,coordinate = None,rowNo = None,colNo = None):
#根据单元格所在的位置索引获取该单元格的值,坐标从1开始
#sheet.cell(row = 1,column = 1).value 表示excel中第一行第一列的值
if coordinate != None:
try:
return sheet.cell(coordinate = coordinate).value
except Exception,e:
raise e
elif coordinate is None and rowNo is not None and colNo is not None:
try:
return sheet.cell(row = rowNo,column = colNo).value
except Exception,e:
raise e
else:
raise Exception("Insufficient Coordinates of Cell !!!")
def getCellOfObject(self,sheet,coordinate = None,rowNo = None,colNo = None):
#获取某个单元格的对象,可以根据单元格所在位置的数字索引,
#也可以直接根据excel中单元格的编码及坐标
#如getCellOfObject(sheet,corrdinate = "A1") 或者
#getCellOfObject(sheet,rowNo = 1,colNo = 1)
if coordinate != None:
try:
return sheet.cell(coordinate = coordinate)
except Exception,e:
raise e
elif coordinate == None and rowNo is not None and colNo is not None:
try:
return sheet.cell(row = rowNo,column = colNo)
except Exception,e:
raise e
else:
raise Exception("Insufficient Coordinates of Cell !!!")
def writeCell(self,sheet,content,coordinate = None,rowNo = None,colNo = None,style = None):
#根据单元格在excel中的编码位置或者数字索引坐标向单元格中写入数据
#下标从1开始,参数style表示字体颜色的名称,比如,red , green
if coordinate != None:
try:
sheet.cell(coordinate = coordinate).value = content
if style is not None:
sheet.cell(coordinate=coordinate).font = Font(color = self.RGBDict[style])
self.workbook.save(self.excelFile)
except Exception,e:
raise e
elif coordinate == None and rowNo is not None and colNo is not None:
try:
sheet.cell(row = rowNo,column = colNo).value = content
if style is not None:
sheet.cell(coordinate=coordinate).font = Font(color=self.RGBDict[style])
self.workbook.save(self.excelFile)
except Exception,e:
raise e
else:
raise Exception("Insufficient Coordinates of Cell !!!")
def writeCelCurrentTime(self,sheet,coordinate = None,rowNo = None,colNo = None,style = None):
#写入当前时间,下标从1开始
now = int(time.time()) #显示为时间戳
timeArray = time.localtime(now)
currentTime = time.strftime("%Y-%m-%d %H:%M:%S",timeArray)
if coordinate != None:
try:
sheet.cell(coordinate = coordinate).value = currentTime
self.workbook.save(self.excelFile)
except Exception,e:
raise e
elif coordinate == None and rowNo is not None and colNo is not None:
try:
sheet.cell(row = rowNo,column = colNo).value = currentTime
self.workbook.save(self.excelFile)
except Exception,e:
raise e
else:
raise Exception("Insufficient Coordinates of Cell !!!")
if __name__ == "__main__":
pe = ParseExcel()
pe.loadWorkbook("D:\\PythonProject\\keyword_driven_frame\\sogou_search_keyword_driven\\test_data_test.xlsx")
print u"通过名称获取sheet对象的名字:",pe.getSheetByName(u"测试步骤").title
print u"通过index获取sheet对象的名字:", pe.getSheetByIndex(0).title
sheet = pe.getSheetByIndex(0)
print type(sheet)
print "max row number:",pe.getRowsNumber(sheet)
print "max column Number:",pe.getColsNumber(sheet)
row = pe.getRow(sheet,1) #获取第一行
for i in row:
print i.value
#获取第一行第一列单元格内容
print "*" * 50
print pe.getCellOfValue(sheet,rowNo = 1,colNo = 1)
pe.writeCell(sheet,u"我爱中国",rowNo = 10,colNo = 10)
pe.writeCelCurrentTime(sheet,rowNo = 10,colNo = 11)
测试数据文件直接存放在工程目录下:
test_data.xslx中的“测试步骤”sheet数据如下:
动作 定位方式 定位表达式 操作值 执行结果
broswer firefox
visit_url http://www.sogou.com
input id query 光荣之路 吴老师
click xpath //*[@id='stb']
sleep 2
assert_word 自由
quit
再创建一个包Action,存放关键字方法:
PageAction.py内容如下:
#encoding=utf-8
from selenium import webdriver
import time
driver = ""
#定义函数
def browser(browser_name):
global driver #声明全局变量
try:
if browser_name.lower() == "firefox":
driver = webdriver.Firefox(executable_path = "D:\\geckodriver")
except Exception,e:
raise e
def visit_url(url):
global driver # 声明全局变量
try:
driver.get(url)
except Exception, e:
raise e
def input(locate_method,locate_expression,content):
global driver # 声明全局变量
try:
# 添加显式等待
driver.find_element(locate_method,locate_expression).send_keys(content)
except Exception, e:
raise e
def click(locate_method,locate_expression):
global driver # 声明全局变量
try:
# 添加显式等待
driver.find_element(locate_method,locate_expression).click()
except Exception, e:
raise e
def sleep(sleep_time):
global driver # 声明全局变量
try:
time.sleep(int(sleep_time))
except Exception, e:
raise e
def quit():
global driver # 声明全局变量
try:
driver.quit()
except Exception, e:
raise e
def assert_word(word):
global driver # 声明全局变量
try:
assert word in driver.page_source
except Exception, e:
raise e
在工程目录下创建测试脚本:
run.py内容如下:
#encoding=utf-8
from Util import ParseExcel
from Action.PageAction import *
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
test_data_excel = ParseExcel.ParseExcel()
test_data_excel.loadWorkbook("test_data.xlsx")
#测试解析Excel,可以删除
print u"通过名称获取sheet对象的名字:",test_data_excel.getSheetByName(u"测试步骤").title
test_data_sheet = test_data_excel.getSheetByName(u"测试步骤")
row_num = test_data_excel.getRowsNumber(test_data_sheet)
print "Total Rows:",row_num
for i in range(1,row_num+1):
print test_data_excel.getRow(test_data_sheet,i)
print "=" * 50
col_num = test_data_excel.getColsNumber(test_data_sheet)
print "Total Columns:",col_num
for j in range(1,col_num+1):
print test_data_excel.getColumn(test_data_sheet,j)
print "*" * 50
#遍历文件,开始进行测试
for i in range(1,row_num):
# for j in range(col_num-1): #行号是固定的,然后按列号遍历,获取每一行,结果列不需要读取
# print test_data_excel.getRow(test_data_sheet,i)[j].value
row = test_data_excel.getAllRows(test_data_sheet)[i]
print "-" * 50
print u"行号:",row[0].value
action = row[1].value
locate_method = row[2].value
locate_expression = row[3].value
operate_value = row[4].value
print action,locate_method,locate_expression,operate_value
print "+" * 50
#拼接字符串
#excel中组合情况有四种,即:(定位方式+定位表达式)和操作值为空或不空的组合情况
#定位方式和定位表达式只能同时存在或同时为空,所以可以当作是一个字段
#遍历组合情况,拼接不同形式的字符串
#将定位表达式中的单引号替换成双引号,因在后面拼接字符串时需要用单引号去包括参数
#所以需要进行替换,或者用双引号包括参数,则excel中的定位表达式需要用单引号
#两种情况取一种
test_step = ""
if action and locate_method is None and operate_value:
test_step = action + "('" + str(operate_value) + "')"
print test_step
elif action and locate_method and locate_expression and operate_value:
#加u后拼接会报错,需要使用sys.setdefaultencoding("utf-8")
test_step = action + "('" + locate_method + "','" + locate_expression.replace("\'","\"") + "',u'" + str(operate_value) + "')"
print test_step
elif action and locate_method and locate_expression and operate_value is None:
test_step = action + "('" + locate_method + "','" + locate_expression.replace("\'","\"") + "')"
print test_step
elif action and locate_method is None and locate_expression is None and operate_value is None:
test_step = action + "()"
print test_step
try:
eval(test_step)
#执行成功,在结果列中写入“Success”
test_data_excel.writeCell(test_data_sheet,"Success",rowNo = i+1,colNo = 6)
except Exception,e:
#执行失败,在结果列中写入“Fail”
test_data_excel.writeCell(test_data_sheet, "Fail", rowNo= i+1, colNo=6)
以上内容为一个简单的关键字驱动框架,真正的框架核心思想也是如此,通过拼接字符串,拼接出想要的函数调,再用eval执行每一步,只不过真正的框架中封装了更多的方法
软件测试技术交流群:1125760266
网友评论