全网最全,selenium自动化测试总结,测试进阶之路...


前言

使用selenium启动浏览器

可以在python中使用下面的代码启动一个Chrome浏览器,然后控制这个浏览器的行为或者读取数据。

from selenium import webdriver

# 启动Chrome浏览器,要求chromedriver驱动程序已经配置到环境变量
# 将驱动程序和当前脚本放在同一个文件夹也可以
driver = webdriver.Chrome()

# 手动指定驱动程序路径
driver = webdriver.Chrome(r'D:/python/tools/chromedriver.exe')

driver = webdriver.Ie()        # Internet Explorer浏览器
driver = webdriver.Edge()      # Edge浏览器
driver = webdriver.Opera()     # Opera浏览器
driver = webdriver.PhantomJS()   # PhantomJS

driver.get('http://xxxxxx.com')  # 打开指定路径的页面

启动的时候还可以设置启动参数,比如下面的代码实现启动时添加代理,并且忽略https证书校验。

from selenium import webdriver

# 创建chrome启动选项对象
options = webdriver.ChromeOptions()


options.add_argument("--proxy-server=127.0.0.1:16666")  # 设置代理
options.add_argument("---ignore-certificate-errors")  # 设置忽略https证书校验
options.add_experimental_option("excludeSwitches", ["enable-logging"])  # 启用日志

# 设置浏览器下载文件时保存的默认路径
prefs = {
    
    "download.default_directory": get_download_dir()}
options.add_experimental_option("prefs", prefs)
driver = webdriver.Chrome(options=options)

一些非常有用的启动选项,下面使用的options = webdriver.ChromeOptions():

options.add_argument("--proxy-server=127.0.0.1:16666")	#设置代理,可以结合mitmproxy进行抓包等
option.add_experimental_option('excludeSwitches', ['enable-automation'])	#设置绕过selenium检测
options.add_argument("---ignore-certificate-errors")	#设置忽略https证书校验
options.add_experimental_option("prefs", {
    
    "profile.managed_default_content_settings.images": 2})	#设置不请求图片模式加快页面加载速度
chrome_options.add_argument('--headless')	#设置无头浏览器

selenium页面加载等待和检测

使用selenium打开页面以后,还不能立刻操作,需要等到待处理页面元素加载完成,这时就需要检测和等待页面元素加载。

使用time.sleep()等待:

最简单的方法就是打开页面以后,使用time.sleep()强制等待一定时间,该方法只能设置一个固定时间等待,如果页面提前加载完成,则会空等阻塞。

from time import sleep
from selenium import webdriver

driver = webdriver.Chrome()
driver.get('www://baidu.com')
time.sleep(10)
print('load finish')

使用implicitly_wait设置最长等待时间:

另外还可以使用implicitly_wait设置最长等待时间,如果在给定时间内页面加载完成或者已经超时,才会执行下一步。

该方法会等到所有资源全部加载完成,也就是浏览器标签栏的loading图表不再转才会执行下一步。有可能页面元素已经加载完成,但是js或者图片等资源还未加载完成,此时还需要等待。

另需注意使用implicitly_wait只需设置一次,且对整个driver生命周期都起作用,凡是遇到页面正在加载都会阻塞。

from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(30)   # 设置最长等30秒
driver.get('http://baidu.com')
print(driver.current_url)

driver.get('http://baidu.com')
print(driver.current_url)

使用WebDriverWait设置等待条件:

使用WebDriverWait(selenium.webdriver.support.wait.WebDriverWait)能够更加精确灵活地设置等待时间,WebDriverWait可在设定时间内每隔一段时间检测是否满足某个条件,如果满足条件则进行下一步操作,如果超过设置时间还不满足,则抛出TimeoutException异常,其方法声明如下:

WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)

其中各参数含义如下:

driver:浏览器驱动
timeout:最长超时时间,默认以秒为单位
poll_frequency:检测的间隔(步长)时间,默认为0.5秒
ignored_exceptions:忽略的异常,即使在调用until()或until_not()的过程中抛出给定异常也不中断

WebDriverWait()一般配合until()或until_not()方法使用,表示等待阻塞直到返回值为True或者False,需要注意这两个方法的参数都需是可调用对象,即方法名称,可以使用expected_conditions模块中的方法或者自己封装的方法。

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

driver = webdriver.Chrome()
driver.get("http://baidu.com")

# 判断id为`input`的元素是否被加到了dom树里,并不代表该元素一定可见,如果定位到就返回WebElement
element = WebDriverWait(driver, 5, 0.5).until(expected_conditions.presence_of_element_located((By.ID, "s_btn_wr")))

# implicitly_wait和WebDriverWait都设置时,取二者中最大的等待时间
driver.implicitly_wait(5)

# 判断某个元素是否被添加到了dom里并且可见,可见代表元素可显示且宽和高都大于0
WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.ID, 'su')))

# 判断元素是否可见,如果可见就返回这个元素
WebDriverWait(driver,10).until(EC.visibility_of(driver.find_element(by=By.ID, value='kw')))

selenium元素定位和读取

查找元素
selenium提供了一系列api方便获取chrome中的元素,这些API都返回WebElement对象或其列表,如:

find_element_by_id(id): 查找匹配id的第一个元素
find_element_by_class_name(): 查找匹配class的第一个元素
find_elements_by_xpath(): 查找匹配xpath的所有元素
find_elements_by_css_selector(): 查找匹配css选择器的所有元素

其实可以看WebDriver类里面的实现源码,其核心实现都是调用两个基本函数:

find_element(self, by=By.ID, value=None): 查找匹配策略的第一个元素
find_elements(self, by=By.ID, value=None): 查找匹配策略的所有元素
其中by参数可以是ID, CSS_SELECTOR, CLASS_NAME, XPATH等。

下面举几个简单的例子:

通过xpath查询包含文本登录的第一个元素:

find_element_by_xpath("//*[contains(text(),'登录')]")

查询包含类名refresh的所有元素:

find_elements_by_class_name('refresh')

查询table表格的第二行:

find_element_by_css_selector('table tbody > tr:nth(2)')

dom元素交互
上面介绍的元素查找结果WebElement对象,常用的api有:

element.text: 返回元素的文本内容(包括所有后代节点的内容),注意如果元素display=none则返回为空字符串
element.screenshot_as_png: 元素的截图
element.send_keys(“input”): 元素输入框输入input字符串
element.get_attribute(‘data-v’): 获取data-v名称属性值,除了自定义节点属性,还可以获取如textContent等属性
element.is_displayed(): 判断元素是否用户可见
element.clear(): 清除元素文本
element.click(): 点击元素,如果元素不可点击会抛出ElementNotInteractableException异常
element.submit(): 模拟表单提交

查找元素失败处理:

如果找不到指定元素,则会抛出NoSuchElementException异常,而且需要注意,display=none的元素是可以获取到的,凡是在dom节点中的元素都可以获取到。

而且实际使用的时候要注意一些js代码动态创建的元素,可能需要轮询获取或者监控。
一个检查是否存在指定元素的方法如下:

def check_element_exists(xpath):
    try:
        driver.find_element_by_xpath(xpath)
    except NoSuchElementException:
        return False
    return True

selenium交互控制

ActionChains动作链:
webdriver通过ActionChains对象来模拟用户操作,该对象表示一个动作链路队列,所有操作会依次进入队列但不会立即执行,直到调用perform()方法时才会执行。其常用方法如下:

click(on_element=None): 单击鼠标左键
click_and_hold(on_element=None): 点击鼠标左键,不松开
context_click(on_element=None): 点击鼠标右键
double_click(on_element=None): 双击鼠标左键
send_keys(*keys_to_send): 发送某个键到当前焦点的元素
send_keys_to_element(element, *keys_to_send): 发送某个键到指定元素
key_down(value, element=None): 按下某个键盘上的键
key_up(value, element=None): 松开某个键
drag_and_drop(source, target): 拖拽到某个元素然后松开
drag_and_drop_by_offset(source, xoffset, yoffset): 拖拽到某个坐标然后松开
move_by_offset(xoffset, yoffset): 鼠标从当前位置移动到某个坐标
move_to_element(to_element): 鼠标移动到某个元素
move_to_element_with_offset(to_element, xoffset, yoffset): 移动到距某个元素(左上角坐标)多少距离的位置
perform(): 执行链中的所有动作
release(on_element=None): 在某个元素位置松开鼠标左键

模拟鼠标事件:

下面代码模拟鼠标移动,点击,拖拽等操作,注意操作时需要等待一定时间,否则页面还来不及渲染。

from time import sleep
from selenium import webdriver
# 引入 ActionChains 类
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Chrome()
driver.get("https://www.baidu.cn")
action_chains = ActionChains(driver)

target = driver.find_element_by_link_text("搜索")
# 移动鼠标到指定元素然后点击
action_chains.move_to_element(target).click(target).perform()
time.sleep(2)

# 也可以直接调用元素的点击方法
target.click()
time.sleep(2)

# 鼠标移动到(10, 50)坐标处
action_chains.move_by_offset(10, 50).perform()
time.sleep(2)

# 鼠标移动到距离元素target(10, 50)处
action_chains.move_to_element_with_offset(target, 10, 50).perform()
time.sleep(2)

# 鼠标拖拽,将一个元素拖动到另一个元素
dragger = driver.find_element_by_id('dragger')
action.drag_and_drop(dragger, target).perform()
time.sleep(2)

# 也可以使用点击 -> 移动来实现拖拽
action.click_and_hold(dragger).release(target).perform()
time.sleep(2)
action.click_and_hold(dragger).move_to_element(target).release().perform()

模拟键盘输入事件:

通过send_keys模拟键盘事件,常用有:

send_keys(Keys.BACK_SPACE): 删除键(BackSpace)
send_keys(Keys.SPACE): 空格键(Space)
send_keys(Keys.TAB): 制表键(Tab)
send_keys(Keys.ESCAPE): 回退键(Esc)
send_keys(Keys.ENTER): 回车键(Enter)
send_keys(Keys.F1): 键盘 F1
send_keys(Keys.CONTROL,'a'): 全选(Ctrl+A)
send_keys(Keys.CONTROL,'c'): 复制(Ctrl+C)
send_keys(Keys.CONTROL,'x'): 剪切(Ctrl+X)
send_keys(Keys.CONTROL,'v'): 粘贴(Ctrl+V)

示例:定位到输入框,然后输入内容

# 输入框输入内容
driver.find_element_by_id("kw").send_keys("NBA")

# 模拟回车删除多输入的一个字符a
driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)

警告框处理:

用于处理调用alert弹出的警告框。
driver.switch_to_alert(): 切换到警告框
text:返回alert/confirm/prompt中的文字信息,比如js调用alert(‘failed’)则会获取failed字符串
accept():接受现有警告框
dismiss():关闭现有警告框
send_keys(keysToSend):将文本发送至警告框

selenium浏览器控制

基本常用api

下面列出一些非常实用的浏览器控制api:

driver.current_url: 获取当前活动窗口的url
driver.switch_to_window("windowName"): 移动到指定的标签窗口
driver.switch_to_frame("frameName"): 移动到指定名称的iframe
driver.switch_to_default_content(): 移动到默认文本内容区
driver.maximize_window(): 将浏览器最大化显示
driver.set_window_size(480, 800): 设置浏览器宽480、高800显示
driver.forword(), driver.back(): 浏览器前进和后退
driver.refresh(): 刷新页面
driver.close(): 关闭当前标签页
driver.quiit(): 关闭整个浏览器
driver.save_screenshot('screen.png'): 保存页面截图
driver.maximize_window(): 将浏览器最大化显示
browser.execute_script('return document.readyState;'): 执行js脚本

selenium读取和加载cookie:

使用get_cookies和add_cookie可以实现将cookie缓存到本地,然后启动时加载,这样可以保留登录态。
实现如下:

import os
import json
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.baidu.cn")

# 读取所有cookie并保存到文件
cookies = driver.get_cookies()
cookie_save_path = 'cookie.json'
with open(cookie_save_path, 'w', encoding='utf-8') as file_handle:
    json.dump(cookies, file_handle, ensure_ascii=False, indent=4)

# 从文件读取cookie并加载到浏览器
with open(cookie_save_path, 'r', encoding='utf-8') as file_handle:
    cookies = json.load(file_handle)
    for cookie in cookies:
        driver.add_cookie(cookie)

selenium打开新的标签页窗口:

使用driver.get(url)会默认在第一个标签窗口打开指定连接,点击页面中的_blank的链接时也会打开一个新的标签窗口。

还可以用下面的方式手动打开一个指定页面的标签窗口,需要注意打开新窗口或者关闭以后,还需要手动调用switch_to.window切换当前活动的标签窗口,否则会抛出NoSuchWindowException异常。

from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.baidu.cn")

new_tab_url = 'https://www.baidu.c'
driver.execute_script(f'window.open("{
      
      new_tab_url}", "_blank");')
time.sleep(1)

# 注意:必须调用switch_to.window手动切换window,否则会找不到tab view
# 聚焦到新打开的tab页面,然后关闭
driver.switch_to.window(driver.window_handles[1])
time.sleep(2)
driver.close()   # 关闭当前窗口

# 手动回到原来的tab页面
driver.switch_to.window(driver.window_handles[0])
time.sleep(1)

除了使用execute_script外,还可以使用模拟打开新tab页按键的方式新建一个标签页窗口:

driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 't')
ActionChains(driver).key_down(Keys.CONTROL).send_keys('t').key_up(Keys.CONTROL).perform()

浏览器崩溃WebDriverException异常处理:

比如在Chrome中长时间运行一个页面会出现Out Of Memory内存不足的错误,此时WebDriver会抛出WebDriverException异常,基本所有api都会抛出这个异常,这个时候需要捕获并进行特殊处理。

处理方式是记录页面的一些基本信息,比如url,cookie等,并定期写入到文件中,如果检测到该异常,则重启浏览器并且加载url和cookie等数据。

下面是我整理的2023年最全的软件测试工程师学习知识架构体系图

一、Python编程入门到精通

请添加图片描述

二、接口自动化项目实战

请添加图片描述

三、Web自动化项目实战

请添加图片描述

四、App自动化项目实战

请添加图片描述

五、一线大厂简历

请添加图片描述

六、测试开发DevOps体系

请添加图片描述

七、常用自动化测试工具

请添加图片描述

八、JMeter性能测试

请添加图片描述

九、总结(尾部小惊喜)

不要因为困难而退缩,要勇往直前,坚持奋斗,只有付出努力,才能创造属于自己的辉煌。相信自己的能力,追逐梦想,每一次奋斗都是成长的机会。

困难并不可怕,只要你勇往直前,坚持奋斗,就能超越自我,创造属于自己的辉煌。相信自己的能力,不断努力,追求卓越,成功将会向你招手。不要放弃,因为奋斗是实现梦想的唯一途径。

不要被失败击倒,因为每一次的挫折都是成长的机会。坚持奋斗,用汗水浇灌梦想,只有不断努力,才能创造出属于自己的辉煌。相信自己的能力,勇往直前,成功就在不远处等待着你。

猜你喜欢

转载自blog.csdn.net/x2waiwai/article/details/131880071
今日推荐