文章目录
前言
Selenium简介及Webdriver对浏览器的操作
一、selenium简介
1.Selenium是一个浏览器自动化操作框架。Selenium主要由三种工具组成:
-
SeleniumIDE:支持用户录制和回访测试。录制/回访模式存在局限性,对许多用户来说并不适合。
-
Selenium WebDriver:提供了各种语言环境的API来支持更多控制权和编写符合标准软件开发实践的应用程序。
-
SeleniumGrid:使用Selenium API控制分布在一系列机器上的浏览器实例,支持并发运行更多测试。
2.webdriver工作原理:
编写的代码(客户端),webdriver启动的浏览器绑定在特定的端口(服务端),客户端通过ComandExector发送http请求给服务端,服务端通过WebService将其翻译称浏览器能读懂的脚本传递给浏览器执行,执行完成后,浏览器将结果返回给WebService,WebService再把返回的结果处理后,返回给客户端。
二、常用的元素相对定位方式(绝对定位直接通过浏览器F12copy即可)
1.xpath
符号说明:
'/':从根节点选取
'//':从匹配的选择的当前节点选择文档中的节点,不考虑位置
'.':选取当前节点
'..':选取当前节点的父节点
'@':选取元素属性
-
通过id,name,class,title,tag等类型定位:
//*[@id="su"] ,//*[@name="wd"],//*[@class="wrapper_new"],...
-
通过子元素定位置父元素,在定位父元素的其他子元素(定位元素无过多属性):
//*[@class="wrapper_new"]/../a
-
通过父元素定位具体的子元素(存在多个相同的子元素):
//*[@id="lg"]/img[2]
-
通过text关键字定位:
//span[text()="按图片搜索"]
-
通过contains关键字,以包含的内容模糊匹配定位:
//i[contains(@title,'清')], //span[contains(text(),'片搜')], //i[contains(@class,'_new')]
-
通过starts-with关键字,以开始的内容模糊匹配定位:
//span[starts-with(text(),'按图')],//*[starts-with(@class,'wrapper_')]
-
通过ends-with关键字,以结束的内容模糊匹配(此关键字浏览器可能不适用):
//span[ends-with(text(),'图搜索')]
-
以上定位只是展示定位方法,并非最佳定位,可在百度首页练习
2.css selector(定位速度优于xpath)
符号说明:
'.':表示类的属性
'#':表示id属性
'[属性=属性值]':[name="username"]
'span:nth-child(2)':父元素的第二个span元素
'>':儿子元素
'+':相邻的弟弟元素
- 通过id,name,title等类型定位:
#su, [name="wd"], [title="清空"]
- 通过class定位(可使用父亲类属性值+空格+儿子类的属性值):
.s_btn_wr .s_btn
- 父亲多个相同的子元素的定位方式:
span i:nth-child(3)(父亲的第三个儿子=父亲的第一个i标签元素)
span span:nth-child(1) (父亲的第一个儿子=父亲的第一个span标签)
span span:first-child (父亲的第一个span标签元素)
span span:last-child (父亲的最后一个span标签元素)
- 相邻元素定位方式(+):
#s_is_result_css +textarea //此种方式用的少
- 子元素定位方式(>):
.quickdelete-wrap>input //此种方式用的少
- 以上定位只是展示定位方法,并非最佳定位,可在百度首页练习
3.其他定位方式(前面两种定位方式可解决大部分定位):
三、web控件的交互
1.基本交互
- 点击元素:click()
self.driver.find_element(By.CSS_SELECTOR, '#su').click()
- 输入文本:send_keys(text)
self.driver.find_element(By.CSS_SELECTOR,'#kw').send_keys('selenium')
- 上传文件:send_keys(path)
self.find(By.CSS_SELECTOR, '.upload-pic').send_keys( r'F:\python_programe\facetest\02_控件交互_selenium\微信图片_20220227233805.png')
- 选择下拉框:select_by_value(select_by_value(value));select_by_index(index)
from selenium.webdriver.support.select import Select
result = 'Select(self.driver.find_element(By.XPATH,'/html/body/div/select'))'
# 用value选择下拉框
result.select_by_value('css')
# 用index选择下拉框
result.select_by_index(2)
# 所选内容打印
content = result.all_selected_options
for i in content:
print(i.text)
- 清除文本:clear()
self.driver.find_element(By.CSS_SELECTOR, '#su').clear()
- 获取网址:get(url)
self.driver.get('http://www.baidu.com')
- 获取浏览器名称:name
self.driver.name
- 获取当前页面的title: title
self.driver.title
- 获取当前页面的url:current_url
self.driver.current_url
- 浏览器窗口最大化:maximize_window()
self.driver.maximize_window()
- 浏览器窗口最小化(selenium4支持):minimize_window()
self.driver.minimize_window()
- 浏览器前进:forward()
selfl.driver.forward()
- 浏览器后退:back()
self.driver.back()
- 浏览器刷新:refresh()
self.driver.refresh()
- 浏览器截图:save_screenshot(path)
self.save_screenshot('test.png')
- 关闭当前页面:close()
self.driver.close()
- 关闭浏览器:quit()
self.driver.quit()
- 获取元素属性:get_attribute(‘value’)
self.driver.find_element(By.CSS_SELECTOR, '#kw').get_attribute('value')
- 获取元素位置:location
self.driver.find_element(By.CSS_SELECTOR, '#kw').location
- 获取元素大小:size
self.driver.find_element(By.CSS_SELECTOR, '#kw').size
- 获取当前网页源代码:page_source
self.driver.page_source
- 获取标签中的文本:get_attribute(‘innerHTML’)
self.driver.find_element(By.CSS_SELECTOR, '.soutu-hover-tip').get_attribute('innerHTML')
2.等待方式(页面的渲染跟不上代码执行的速度)
- 隐式等待:mplicitly_wait(time)
设置一个等待时间,轮询查找(默认0.5秒)元素是否出现,超出等待时间抛出异常
self.driver.implicitly_wait(5)
- 显示等待:WebDriverWait().until(expected_conditions.expected_conditions.element_to_be_clickable())
定义是否满足一定的条件(轮询查找-默认0.5秒),满足则执行后续的操作,不满足则继续等待直至超过设置的最长等待时间
WebDriverWait(self.driver, 5).until(expected_conditions.element_to_be_clickable((By.CSS_SELECTOR, "#kw")))
- 强制等待: sleep(time)
线性休眠一段时间(一般隐式等待与显示等待不起作用,才会用到)
sleep(5)
3.模拟键盘
- 模拟键盘全选
from selenium.webdriver.common.keys import Keys
element_1 = self.driver.find_element(By.CSS_SELECTOR, '#kw')
element_1.send_keys("selenium4.0")
# 通过控制鼠标输入control+a,进行全选
element_1.send_keys(Keys.CONTROL, 'a')
- 模拟键盘复制
element_1.send_keys(Keys.CONTROL, 'c')
- 模拟键盘粘贴
element_1.send_keys(Keys.CONTROL, 'v')
- 模拟键盘回车
element_1.send_keys(Keys.ENTER)
4.模拟鼠标
from selenium.webdriver import ActionChains
element_1 = self.driver.find_element(By.XPATH, '//*[@value="dbl click me"]')
element_2 = self.driver.find_element(By.XPATH, '//*[@value="click me"]')
element_3 = self.driver.find_element(By.XPATH, '//*[@value="right click me"]')
action = ActionChains(self.driver)
- 鼠标单击
action.click(element_2).perform()
- 鼠标双击
action.double_click(element_1).perform()
- 鼠标右击
action.context_click(element_3).perform()
- 滚动窗口
action = TouchActions(self.driver)
action.scroll_from_element(element_1, x, y).perform()
5.窗口处理
- 查看当前窗口句柄
self.driver.current_window_handle
- 查看所有窗口列表
self.driver.window_handles
- 切换窗口
self.driver.switch_to_window(self.driver.window_handles[index])
6.网页frame处理
- 切换frame
self.driver.switch_to.frame(name)
self.driver.switch_to.frame(id)
self.driver.switch_to.frame(WebElement)
self.driver.switch_to.frame(index)
- 返回父级frame
self.driver.switch_to.parent_frame()
- 从frame中切回主文档
self.driver.switch_to.default_content()
7.弹窗处理
- alert弹框、prompt弹框
# 切换至alert_iframe
alert = self.driver.switch_to.alert
# 查看弹窗内容
alert.text
# 确认alert
alert.accept()
# 取消alert
alert.dismiss()
- confirm弹框
# 切换至alert_iframe
alert = self.driver.switch_to.alert
# 查看弹窗内容
alert.text
# 弹框中输入内容
alert.send_keys(text)
# 确认alert
alert.accept()
# 取消alert
alert.dismiss()
8.js脚本执行
- 执行js脚本,获取元素定位,并改变内容
self.driver.execute_script("c=document.getElementById('train_date'),c.value='2022-02-28'")
四、浏览器参数设置
- 设置复用浏览器模式(调试模式)
cmd: chrome --remote-debugging-port=9222
opt.debugger_address = "127.0.0.1:9222
- 设置隐藏浏览器运行
opt.add_argument("--headless")
- 给予root执行权限
# opt.add_argument("--no-sandbox")
- 隐藏自动化测试软件的控制提示
opt.add_experimental_option('excludeSwitches', ['enable-automation'])
- 浏览器不加载图片
opt.add_argument('blink-settings=imagesEnabled=false')
五、PO模式的基本原则(理解)
- 封装页面的功能
- 封装细节,只提供接口或者方法名
- 封装的操作细节不使用断言,断言放在单独的testcase模块
- 方法return到新打开的页面
- 只为页面中重要的元素进行PO设计
- 相同的行为产生不同的结果,可以封装不同的结果
- 一般设计时分为三层:对象库层+逻辑层+业务数据层
- 按照页面划分,把每个页面可能涉及到的步骤写下来 pageObject包
- 把页面的步骤组合在一起形成一个业务 pageAction包
- 测试用例的书写,case层,跟单元测试框架结合使用,断言,参数化,报告 case包
六、PO模式的优势
- PO提供了一种业务流程与页面元素操作分离的模式,这使得测试代码变得更加清晰
- 页面对象与用例分离,使得我们更好的复用对象
- 可复用的页面方法代码会变得更加优化
- 更加有效的命名方式使得我们更加清晰的知道方法所操作的UI元素
- 简而言之:
通过对界面元素的封装减少冗余代码,同时在后期维护中,若元素定位发生变化, 只需要调整页面元素封装的代码,业务代码和测试代码被分开,降低耦合性,提高测试用例的可维护性、可读性。
总结
selenium的介绍与webdriver的使用,工作中遇到更好的方法,会继续更新,继续学习