selenium+python自动化框架
流程:
环境准备
eclipse :需安装pydev、testng插件
python :安装python完成后,需 pip下安装selenium:命令: pip install selenium
我现在的环境:eclipse【 Neon.3 Release (4.6.3)】+JDK1.8+python3.6.3+pydev 6.4.4+selenium3.8.1
2 eclipse创建python项目
1 src:框架主要代码,很重要!!其中,framework主要实现 配置文件的读取,日志类,读取数据库,selenium常用方法封装,浏览器启动类等
2 config :配置文件,配置url,数据库等
data:放的测试案例的数据—因为表太多,现在不用了,数据改放在了数据库中
3 logs:顾名思义,放生成的日志
4 PageElement:放需要的页面元素
5 report:生成的测试报告会在这里
6 result:本来想放具体的测试结果,如哪条案例未通过放这里!!现在也没啥用!可以不用
7 screenshot:放运行错误后的截图
8 tools:工具类:如驱动啥的
- 测试数据准备
3.1 测试元素表
3.2测试数据表**
- 测试主框架的搭建
4.1框架目录
每个包的解释:
framework:自动化测试框架的支撑,主要实现功能为对selenium一些常用方法的封装,配置文件的读取、测试数据的读取,浏览器驱动的调用,日志文件的创建等;
【11月更新】现在添加了读取数据库的类
pageobject:采用了页面对象模型Page-Object的思想,将被测系统的每个页面对应成一个页面类,将每个页面对象的唯一属性存放于页面元素表中,并通过该页面类进行读取,实现该页面的操作方法,如:输入,点击等操作
testsuit:测试套件。测试套件是很多测试用例的集合,一个测试套件可以随意管理多个测试用例
testrunner:用来执行加载测试用例,并执行用例,且提供测试输出的一个组件。test runner可以加载test case或者test suite进行执行测试任务。
test:自测用的,可以不要!!!
4.2框架之-----浏览器引擎配置 browser-engine类
4.2.1.config下新建:config.ini
# this is config file, only store browser type and server URL [browserType]
browserName = Firefox
#browserName = Chrome
#browserName = IE [testServer]
URL = http://XXXXXXXXXXXXXXX #输入你要测得url地址
#URL = http://www.google.com
4.2.2 framework下新建browser_engine.py
封装对浏览器的操作
from selenium import webdriver
import configparser
import sys,os
class Browser(object): # 打开浏览器
def open_browser(self):
config = configparser.ConfigParser()
dir = os.path.abspath('.').split('src')[0]
config.read( dir+"/config/config.ini")
browser = config.get("browserType", "browserName")
logger.info("You had select %s browser." % browser)
url = config.get("testServer", "URL")
if browser == "Firefox":
self.driver = webdriver.Firefox()
elif browser == "Chrome":
self.driver = webdriver.Chrome()
elif browser == "IE":
self.driver = webdriver.Ie()
self.driver.set_window_size(1920,1080) #分辨率
#self.driver.maximize_window()#最大化
self.driver.get(url)
return self.driver # 打开url站点
def open_url(self, url):
self.driver.get(url) # 关闭浏览器
def quit_browser(self):
self.driver.quit() # 浏览器前进操作
def forward(self):
self.driver.forward() # 浏览器后退操作
def back(self):
self.driver.back() # 隐式等待
def wait(self, seconds):
self.driver.implicitly_wait(seconds)
4.3 框架之-----日志配置 logger类
4.3.1 framework下新建logger.py
import logging
import time
import os
class Logger(object):
def __init__(self, logger):
'指定保存日志的文件路径,日志级别,以及调用文件,将日志存入到指定的文件中' # 创建一个logger
self.logger = logging.getLogger(logger)
#self.logger.setLevel(logging.DEBUG)
# 创建一个handler,用于写入日志文件
rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time())) log_dir = os.path.abspath('.').split('src')[0] + '/logs/'
log_name = log_dir + rq + '.log'
fh = logging.FileHandler(log_name) fh.setLevel(logging.INFO) # 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()
#ch.setLevel(logging.INFO)
ch.setLevel(logging.ERROR)
# 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter) # 给logger添加handler
self.logger.addHandler(fh)
self.logger.addHandler(ch) def getlog(self):
return self.logger
4.3.2 其他类中引用日志类
在其他类前面先导入日志类:
from framework.logger import Logger
logger = Logger("XXXXX页面").getlog()
# 在你想打印日志的地方加上:
logger.info(XXXXXX)
logger.error(XXXXX) #可参考下面的类
4.4框架之-----selenium二次封装 basepage类
framework下新建basepage.py封装对页面的基本操作,其中包含:查找元素、点击元素、输入、下拉选择、切换iframe,执行js等
import time
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.action_chains import ActionChains
import os.path
from framework.logger import Logger
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.keys import Keys
from random import choice
logger = Logger("BasePage").getlog() class BasePage(object):
"定义一个页面基类,让所有页面都继承这个类,封装一些常用的页面操作方法到这个类" def __init__(self, driver):
self.driver = driver # 查找元素
def find_element(self, selector):
element = ''
if '=>' not in selector:
return self.driver.find_element_by_id(selector)
selector_by = selector.split('=>')[0]
selector_value = selector.split('=>')[1]
if selector_by == 'id':
try:
element = self.driver.find_element_by_id(selector_value)
logger.info("Had find the element \' %s \' successful "
"by %s via value: %s " % (element.text, selector_by, selector_value))
except NoSuchElementException as e:
logger.error("NoSuchElementException: %s" % e)
elif selector_by == "n" or selector_by == 'name':
element = self.driver.find_element_by_name(selector_value)
elif selector_by == 'css_selector':
element = self.driver.find_element_by_css_selector(selector_value)
elif selector_by == 'classname':
element = self.driver.find_element_by_class_name(selector_value)
elif selector_by == "l" or selector_by == 'link_text':
element = self.driver.find_element_by_link_text(selector_value)
elif selector_by == "p" or selector_by == 'partial_link_text':
element = self.driver.find_element_by_partial_link_text(selector_value)
elif selector_by == "t" or selector_by == 'tag_name':
element = self.driver.find_element_by_tag_name(selector_value)
elif selector_by == "x" or selector_by == 'xpath':
try:
element = self.driver.find_element_by_xpath(selector_value)
logger.info("Had find the element \' %s \' successful "
"by %s via value: %s " % (element.text, selector_by, selector_value))
except NoSuchElementException as e:
logger.error("NoSuchElementException: %s" % e)
elif selector_by == "s" or selector_by == 'selector_selector':
element = self.driver.find_element_by_css_selector(selector_value)
else:
raise NameError("Please enter a valid type of targeting elements.")
return element # 输入
def input(self, selector, text):
el = self.find_element(selector)
try:
el.clear()
el.send_keys(text)
logger.info("Had type \' %s \' in inputBox" % text)
except NameError as e:
logger.error("Failed to type in input box with %s" % e) @staticmethod
def sleep(seconds):
time.sleep(seconds)
logger.info("Sleep for %d seconds" % seconds) # 点击
def click(self, selector):
el = self.find_element(selector)
try:
el.click()
#logger.info("The element \' %s \' was clicked." % el.text)
except NameError as e:
logger.error("Failed to click the element with %s" % e) # 切到iframe
def switch_frame(self):
iframe = self.find_element('classname=>embed-responsive-item')
try:
self.driver.switch_to_frame(iframe)
# logger.info("The element \' %s \' was clicked." % iframe.text)
except NameError as e:
logger.error("Failed to click the element with %s" % e) # 处理标准下拉选择框,随机选择
def select(self, id):
select1 = self.find_element(id)
try:
options_list=select1.find_elements_by_tag_name('option')
del options_list[0]
s1=choice(options_list)
Select(select1).select_by_visible_text(s1.text)
logger.info("随机选的是:%s" % s1.text)
except NameError as e:
logger.error("Failed to click the element with %s" % e) # 执行js
def execute_js(self, js):
self.driver.execute_script(js) # 模拟回车键
def enter(self, selector):
e1 = self.find_element(selector)
e1.send_keys(Keys.ENTER)
# 模拟鼠标左击
def leftclick(self, element):
#e1 = self.find_element(selector)
ActionChains(self.driver).click(element).perform() # 截图,保存在根目录下的screenshots
def take_screenshot(self):
screen_dir = os.path.dirname(os.path.abspath('../..')) + '/screenshots/'
rq = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
screen_name = screen_dir + rq + '.png'
try :
self.driver.get_screenshot_as_file(screen_name)
logger.info("Had take screenshot and saved!")
except Exception as e:
logger.error("Failed to take screenshot!", format(e))
def isElementExist(self,xpath):
flag=True
driver=self.driver
try:
driver.find_element_by_xpath(xpath)
return flag
except:
flag=False
return flag
4.5框架之-----读表操作封装【现在有些方法不需要了,因为是从数据库读】
framework下新建readexcle.py,主要获取表中的数据
需先pip安装:xlrd
import xlrd
class ReadExcle(object):
'''
classdoc
'''
def __init__(self,file,tag='True'):
self.file=file
self.tag=tag '''
输入参数,返回某个sheet列表中的所有值
sheetname:excel文件的具体sheet名称
n:开始行数,从第n行开始读
num:读取num行
'''
def read(self,sheetname,n=1,num=1000):#i,sheet索引
ExcelFile = xlrd.open_workbook(self.file)
table = ExcelFile.sheet_by_name(sheetname)
nrows = table.nrows #行数
ncols = table.ncols #列数
j = 0 #循环次数
for row in range(1,nrows):
j+=1
line = []
if self.tag == 'True':
for col in range(0,ncols):
line.append(table.cell(row,col).value)
yield line
elif self.tag == 'False':
if j >= n and j< n+num:
for col in range(0,ncols):
line.append(table.cell(row,col).value)
yield line
'''
读取页面元素表
list1 页面元素路径列表
list2 页面元素js列表
'''
def get(self,sheetname):
ExcelFile=xlrd.open_workbook(self.file)
sheet=ExcelFile.sheet_by_name(sheetname)#'Sheet1'
nrows = sheet.nrows #总行数
list0=[]#元素名称列表
list1=[]#元素路径列表
list2=[]#js列表
for i in range(1,nrows):#i为行数
if sheet.row(i)[2].value != 'null':
r1=sheet.row(i)[2].value
r2=sheet.row(i)[3].value
list0.append(sheet.row(i)[0].value)
list1.append(r1+'=>'+r2)
dict1=dict(zip(list0,list1))
else:
list2.append(sheet.row(i)[3].value)
return dict1,list2 '''
返回excel文件具体sheet的具体某个单元格的值
i,j为单元格所在位置
'''
def read_1(self,sheetname,i,j):
ExcelFile = xlrd.open_workbook(self.file)
table = ExcelFile.sheet_by_name(sheetname)
#print(table.cell(1,0).value)
return table.cell(i,j).value
'''
读取给定列数,如读取该表中第3列~5列
'''
def read_ncols(self,sheetname,ncols,n=1,num=1000):#i,sheet索引
ExcelFile = xlrd.open_workbook(self.file)
table = ExcelFile.sheet_by_name(sheetname)
nrows = table.nrows #行数
ncols = table.ncols #列数
j = 0 #循环次数
for row in range(1,nrows):
j+=1
line = []
if self.tag == 'True':
for col in range(0,ncols):
line.append(table.cell(row,col).value)
yield line
elif self.tag == 'False':
if j >= n and j< n+num:
for col in range(0,ncols):
line.append(table.cell(row,col).value)
yield line
selenium+python自动化框架的更多相关文章
- selenium+python自动化98--文件下载弹窗处理(PyKeyboard)
前言 在web自动化下载操作时,有时候会弹出下载框,这种下载框不属于web的页面,是没办法去定位的(有些同学一说到点击,脑袋里面就是定位!定位!定位!) 有时候我们并不是非要去定位到这个按钮再去点击, ...
- selenium+python自动化79-文件下载(SendKeys)
前言 文件下载时候会弹出一个下载选项框,这个弹框是定位不到的,有些元素注定定位不到也没关系,就当没有鼠标,我们可以通过键盘的快捷键完成操作. SendKeys库是专业的处理键盘事件的,所以这里需要用S ...
- python+selenium简易自动化框架,包含生成测试报告以及发送结果至Email
Selenium+python环境搭建见虫师的pdf文档,非常详尽 简易框架: 1.文件目录:
- 3分钟手把手带你搭建基于selenium的自动化框架
1 .什么是seleniumSelenium 是一个基于浏览器的自动化工具,它提供了一种跨平台.跨浏览器的端到端的web自动化解决方案.Selenium主要包括三部分:Selenium IDE.Sel ...
- 搭建selenium+python自动化环境
1.安装python,下载地址:http://python.org---安装版本3.5.1 ps:自带setuptools和pip工具 2.然后,用pip安装开发Web App需要的第三方库:异步框架 ...
- selenium+python自动化登录脚本
利用selenium+python写的一个关于登录的自动化脚本
- 【python-excel】Selenium+python自动化之读取Excel数据(xlrd)
Selenium2+python自动化之读取Excel数据(xlrd) 转载地址:http://www.cnblogs.com/lingzeng86/p/6793398.html ·········· ...
- selenium+python自动化102-登录页面滑动解锁(ActionChains)
前言 登录页面会遇到滑动解锁,滑动解锁的目的就是为了防止别人用代码登录(也就是为了防止你自动化登录),有些滑动解锁是需要去拼图这种会难一点. 有些直接拖到最最右侧就可以了,本篇讲下使用 seleniu ...
- python自动化框架(unnitest+selenium+htmlreport)
上一篇零零散散的写了一些python unnitest的一些知识,这里讲讲我在实际中使用到的自动化测试框架,算是上篇记录的补充!其实我觉得:什么框架都无所谓,关键是当如果用你的框架发现了bug,能尽量 ...
随机推荐
- 优先级:content –> width –> flex-basis (limted by max|min-width)
原文: https://www.jianshu.com/p/17b1b445ecd4 -------------------------------------------- 最近在学习Flex Bo ...
- webpack4.0打包优化策略整理小结
本文转载于:https://www.jb51.net/article/137449.htm 介绍了webpack4.0打包优化策略整理小结,分享给大家,具体如下: webapck4 新特性介绍-参考资 ...
- Python----常用的__doc__、__name__、__file__的使用
各自的作用: __doc__:获取到注释内容 __name__:获取到函数的名称 __file__:获取到当前的文件路径 示例代码: #!/usr/bin/env python # -*- codin ...
- CF922D Robot Vacuum Cleaner 贪心+排序
正确的贪心方法:按照比例排序. code: #include <bits/stdc++.h> #define N 200000 #define ll long long #define s ...
- C++基础--if/else和switch/case的区别
if和switch的区别: 一.语句的格式: if/else的写法格式如下: int nA, nB; scanf_s("%d", &nA); //输入整数并赋值给变量a s ...
- mac brew 使用教程
brew services list #查看系统通过 brew 安装的服务 brew services cleanup #清除已卸载无用的 ...
- trie树的应用;
链接:https://ac.nowcoder.com/acm/contest/920/B来源:牛客网 定义一张图的生成链是原图的一棵生成树,且这棵树退化成一条链.我们称一条生成链是原图的最小生成链,当 ...
- vxe-table 可编辑表格 行内编辑以及验证 element-UI集成
<vxe-table border show-overflow ref="xTable" ----------------------------------------- ...
- 十七、程序包管理之yum和编译安装
YUM Redhat二次发行版 Yellow Dog Linux,上使用的yum(Yellowdog Update Modifier),由yellow dog 研发 yum命令的工作原理 1.接收用户 ...
- jquery 页面input上传图后显示
<input type="file" id="otherfiles" name="otherfiles" class="up ...