selenium

介绍

Selenium 是一个用于 Web 应用程序测试的工具。它提供了一个 API,让开发者可以使用多种编程语言来编写测试脚本,从而模拟用户在浏览器中的操作。Selenium 可以用来测试 Web 应用程序的功能、性能和兼容性等方面。它支持多种浏览器,包括 Chrome、Firefox、Safari 和 Edge 等。Selenium 的主要优点是它可以在不同的操作系统和浏览器上运行测试脚本,并且可以自动化执行测试用例,从而提高测试效率和准确性。

原理

Selenium 的原理是通过模拟用户在浏览器中的操作,来测试 Web 应用程序的功能。Selenium 提供了一个 WebDriver API,让开发者可以使用多种编程语言来编写测试脚本。测试脚本可以发送 HTTP 请求、填写表单、点击按钮、滚动页面等操作,就像用户在浏览器中手动操作一样。Selenium 会将这些操作转化为浏览器可以理解的指令,并在浏览器中执行。在执行测试脚本的过程中,Selenium 会记录浏览器的状态和响应,并将它们与预期的结果进行比较。如果结果与预期不符,测试脚本就会失败,并生成相应的错误报告。简单来说:python调用selenium,selenium调用浏览器驱动,浏览器驱动控制浏览器。

总结:

  1. 自动化程序调用Selenium 客户端库函数(比如点击按钮元素)
  2. 客户端库会发送Selenium 命令给浏览器的驱动程序
  3. 浏览器驱动程序接收到命令后 ,驱动浏览器去执行命令
  4. 浏览器执行命令
  5. 浏览器驱动程序获取命令执行的结果,返回给我们自动化程序
  6. 自动化程序对返回结果进行处理

环境安装

  • 安装selenium
 pip install selenium==4.3.0
  • 安装浏览器驱动,chrome示例:

    1. 需要下载 Chrome 浏览器驱动程序,官方网站https://sites.google.com/chromium.org/driver/
    2. 需要将 Chrome 浏览器的可执行文件(chrome.exe)的路径添加到系统的环境变量 PATH 中
    3. cmd中验证 Chrome 浏览器驱动是否已经安装成功
chromedriver --version

验证环境

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.implicitly_wait(10)
driver.get('www.baidu.com')
driver.maximize_window()
# 点击百度一下
driver.find_element(By.ID, 'su').click()
driver.quit()

元素定位

  • WebElement对象

    find_element()系列:用于定位单个的页面元素,返回一个 WebElement 类型的对象
    find_elements()系列:用于定位一组页面元素,获取到的是一组列表,返回一个 WebElement 类型的对象, 如果没有符合条件的元素, 返回空列表, 如果没有符合条件的元素, 抛出 NoSuchElementException 异常

  • 元素定位方式
    8大定位方式,id 、class、text、tag、link 、partial link 、xpath、css,常用的id、text、xpath、class、link

    • find_element(By.ID,‘XX’) 最为方便且唯一,但有可能不存在,也可能动态生成。
    • find_element(By.NAME,‘xx’) 定位到的标签不一定是唯一的。
    • find_element_by(By.CLASS_NAME,‘xx’) 可能受JS影响动态变化,不一定是唯一的。
    • find_element(By.TAG_NAME,‘xx’) 标签名定位,定位到的标签不一定是唯一的。# 选择标签(搜索按钮),执行点击操作
    • find_element(By.LINK_TEXT,‘XX’) 根据链接文本全匹配进行精确定位。
    • find_element(By.PARTIAL_LINK_TEXT,‘XX’) 根据链接文本模糊匹配进行定位。
      link表示包含有属性href的标签元素,如:linktext可以通过LINK_TEXT进行定位。
    • find_element(By.XPATH,‘XX’) xpath表达式来完成定位,可以准确定位任何元素。
    • find_element(By.CSS_SELECTOR,‘XX’) css选择器来完成定位,可以准确定位任何元素,但需要熟练掌握css选择器

元素的可见性

driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
driver.implicitly_wait(10)
el = driver.find_element(By.ID, "su")
print(el.is_displayed()) # 元素是否可见
print(el.is_enabled()) # 按钮是否启用
print(el.is_selected()) # 复选框是否选中了

Frame里面元素定位

先切换至driver.switch_to.frame里面,再进行定位,完成操作再driver.switch_to.default_content()跳出来

# 创建一个浏览器驱动对象
driver = webdriver.Chrome()
# 跳转到利url页面
driver.get('https://www.126.com/')
# 先跳转到iframe
driver.switch_to.frame(driver.find_element(By.XPATH, "//iframe[starts-with(@id,'x-URS-iframe')]"))
driver.find_element(By.NAME, "email").send_keys("123")
# 跳出iframe
driver.switch_to.default_content()
# 跳出iframe后可操作iframe之外的元素
value = driver.find_element(By.LINK_TEXT, "注册VIP").text
print(value)

多窗口,打开一个新的窗口链接

1)首先获取所有窗口的句柄hand = driver.window_handles
2)切换至最后一个窗口driver.switch_to.window(hand[-1])
3)再操作页面元素

# 打开新的窗口
driver.find_element(By.XPATH, "//*[@id='s-hotsearch-wrapper']/div/a[1]/div").click()
# 获取全部窗口的句柄,hand是一个list
hand = driver.window_handles
# 跳转到最后一个窗口,即新打开的页面
driver.switch_to.window(hand[-1])

alert弹窗

切换至driver.switch_to.alert,再操作accept、dismiss、text

alert = driver.switch_to.alert
alert.accept()
alert.dismiss()
alert.send_keys('')
value = alert.text
print(value)

当前元素高亮显示

这个其实就是利用javaScript去修改当前元素的边框样式来到达高亮显示的效果

不可输入的disable属性去掉

execute_script(X)执行JS代码,X代表要执行的JS代码

	# 某输入框不可以输入,使用js将disable属性去掉,就可以直接输入了
	driver = webdriver.Chrome()
    driver.get('https://www.baidu.com')
    driver.implicitly_wait(10)
    #  document.getElementById('myElementId')---JavaScript 中用于获取文档元素后移除disable属性
    driver.execute_script("document.getElementById('').removeAttribute('disable')")
	# JavaScript 中用于获取文档元素后改变元素style,display = None的情况可以定位
	driver.excute_script("document.getElementById('').style.display=''")

浏览器操作

# 浏览器前进一页
driver.navigate().forward();
# 浏览器后退
driver.navigate().back();
# 浏览器刷新
driver.navigate().refresh();

获取页面内容

title页面标题
page_source 页面源码
current_url页面连接
text标签内文本

from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
driver = webdriver.Chrome()
driver.get("http://www.csdn.net")
# 获取标题
title = driver.title
print(title)
# 获取源代码
source_code = driver.page_source
print(source_code)
# 获取页面链接
url = driver.current_url
print(url)
# 获取标签内文本
text = driver.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div[2]/div/div/button/span').text
print(text)
# 关闭页面
browser.quit()

调整浏览器窗口尺寸

maximize_window()窗口最大化。
minimize_window()窗口最小化。
set_window_size(width,height)调整窗口到指定尺寸。

获取标签元素的属性值(复选框)

get_attribute(“XX”)获取标签属性值,XX为标签属性名。

type_value = driver.find_elements(By.TAG_NAME, 'input')
# 通过type属性的值来定位元素,并进行选取
for type_value in tag_input:
    # 输出input标签的name属性的值:
    print(type_value.get_attribute("name"))
    # 对复选框进行选取操作
    if type_value.get_attribute("type") == "checkbox":
        type_value.click()
        time.sleep(2)

下拉列表

Select("XX)判断标签元素XX是否为下拉列表元素,是返回Select对象,不是报错
select_by_value(“XX”)通过下拉列表value属性的值XX选择选项
select_by_visible_text(“XX”)通过下拉列表文本内容XX选择选项
select_by_index(N)或options[N].click()通过下拉列表索引号N选则选项,从0 开始
options下拉列表内options标签

# 定位下拉列表标签,并创建下拉列表对象
select = Select(driver.find_element(By.TAG_NAME, "select"))
# 通过value属性选择选项
select.select_by_value("Python")
sleep(2)
# 通过文本内容选择选项
select.select_by_visible_text("C++")
sleep(2)
# 通过选项索引号选择选项
select.select_by_index(0)  # 等同于 select.options[0].click()
sleep(2)
# 通过options属性循环选取
for i in select.options:
    i.click()
    sleep(2)

鼠标操作

move_to_element(X)鼠标悬停,X代表定位到的标签
double_click(X)双击
context_click(X)右击

from time import sleep
# 导入selenium包
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
# 启动并打开指定页面
driver = webdriver.Chrome()
driver.get("https://www.csdn.net")
sleep(2)
# 创建ActionChains对象
action = ActionChains(driver)
# 定位标签并将鼠标移入,并呈现移入结果
tag = driver.find_element(By.XPATH, '//div/a[@class="btn-write-new"]')
# perform() 执行所有存储在ActionChains()类中的行为,做最终的提交
action.move_to_element(tag).perform()
sleep(3)
tag = driver.find_element(By.CSS_SELECTOR, '.blog-nav-box')
action.move_to_element(tag).perform()
sleep(2)
driver.find_element(By.LINK_TEXT, "数学").click()
# 关闭浏览器
sleep(2)
browser.quit()

键盘操作

全选、剪切、粘贴、回退一格

from selenium.webdriver import ActionChains, Keys

input_text = driver.find_element(By.XPATH, '//*[@id="toolbar-search-input"]')
input_text.send_keys("selenium")
# 全选
input_text.send_keys(Keys.CONTROL, "a")  
 # 剪切
input_text.send_keys(Keys.CONTROL, 'x') 
# 粘贴
input_text.send_keys(Keys.CONTROL, 'v') 
# 回退一格
input_text.send_keys(Keys.BACK_SPACE)  

浏览器窗口截图

# 代表文件保存地址及文件名、格式。只写文件名保存至当前路径,若写路径,则路径必须存在。
browser.get_screenshot_as_file("csdn.png")

元素等待

sleep()强制等待 始得线程强制处于睡眠状态
driver.implicitly_wait()隐形等待 ,设置的时全局等待,调用一次就够了
webdriverwait()显性等待 等待方式expected_conditions 特定的元素都设置自己的等待方式进行等待

常用显示等待
解决隐式等待无法解决的问题:元素可以找到,使用点击等操作,出现报错。可能会导致脚本执行速度整体变慢
原因:页面元素加载是异步加载过程,通常 xml 会先加载完成,相应的元素属性后加载元素存在与否是由 xml 决定,元素的交互是由属性决定隐式等待只关注元素能不能找到,不关注元素能否点击或者进行其他的交互

显示等待用到的两个类——WebDriverWait、expected_conditions
WebDriverWait的用法
方法说明: WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
参数说明:
● driver:浏览器驱动。
● timeout:最长超时时间,默认以秒为单位
● poll_frequency:检测的间隔步长,默认是0.5s
● ignored_exceptions:超时后的抛出的异常信息,默认抛出NoSuchElementException异常
WebDriverWait的until()和until_not()方法
方法说明:
● until( method, message=‘’) :当某元素出现或什么条件成立则继续执行
● until_not(method, message=‘’) :当mou元素消失或什么条件不成立则继续执行。
参数说明:
● method:在等待时期,每隔一段时间(init中的poll_frequency)调用这个传入的方法,知道返回值不是False。
● message:如果超时,抛出TimeoutException,将message传入异常
expected_conditions 类
● presence_of_element_located:判断元素是否被加载到dom树里,并不代表元素一定可被定位
用法:WebDriverWait().until(expected_conditions.presence_of_element_located(元素对象))
● visibility_of_element_located:判断某个元素是否可见,可见代表元素非隐藏,并且元素的宽和高都不等于0.
用法:WebDriverWait().until(expected_conditions.visibility_of_element_located(locator))
● element_to_be_clickable:判断每个元素是否可点击
用法:WebDriverWait().until(expected_conditions.element_to_be_clickable(locator))
示例1
visibility_of_element_located判断某个元素是否可见. 可见代表元素非隐藏,并且元素的宽和高都不等于0

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions


class Test001:
    def test_001(self):
        driver = webdriver.Edge()
        driver.implicitly_wait(10)
        driver.get('https://www.baidu.com/')
        driver.maximize_window()
        # 元组,元素定位方式和定位值
        kw_el = (By.ID, 'kw')
        # 使用显示等待,用visibility_of_element_located去判断元素是否加载好得到一个webelement对象
        WebDriverWait(driver, 10).until(expected_conditions.visibility_of_element_located(kw_el))
        # 百度搜索框输入“selenium”
        driver.find_element(*kw_el).send_keys('selenium')
        driver.quit()

示例2
until中使用lambda表达式来进行查询元素

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
        
class Test001:
    def test_case001(self):
        driver = webdriver.Edge()
        driver.implicitly_wait(10)
        driver.get('https://www.baidu.com/')
        driver.maximize_window()
        # 搜索框输入“selenium”
        kw_el = (By.ID, 'kw')
        WebDriverWait(driver, 10).until(lambda x: x.find_element(*kw_el))
        driver.find_element(*kw_el).send_keys('selenium')
        driver.quit()

PO设计模式

简单来说就是用class去表示被测页面。在class中定义页面上的元素和一些该页面上专属的方法。

按照Po模式搭建自动化框架
搭建框架使用的技术是selenium + pytest 。

将框架分为层:
common层(公共层:basepage[基础操作封装]、my_logger[日志分装])、conf(配置层:ini文件、yaml文件)
report(日志输出层)、
pageobject(页面对象)、
pagelocators(页面定位)、
testcases(测试用例)、
testdatas(测试数据)

POM主要有以下优点:

  1. 把web ui对象从测试脚本分离,业务代码和测试脚本分离。
  2. 每一个页面对应一个页面类,页面的元素写到这个页面类中。
  3. 页面类主要包括该页面的元素定位,和这些元素相关的业务操作代码封装的方法。
  4. 代码复用,从而减少测试脚本代码量。
  5. 层次清晰,同时支持多个编写自动化脚本开发,例如每个人写哪几个页面,不影响他人。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值