2024最新最全面的Selenium 3.0 + Python自动化测试框架

文档说明

Selenium是一个用于Web应用程序自动化测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。

Selenium测试的主要功能包括:

测试与浏览器的兼容性:测试应用程序是否能很好的工作在不同的浏览器和操作系统之上。

测试系统功能:创建回归测试,检验软件功能和用户需求。

本文以Python语言为例,主要系统介绍Selenium3.0自动化测试框架的使用中的各种基础、常规操作。

通过学习和实践,达到能够在Python + Selenium的技术架构下进行Web自动化入门测试的目的。

Web自动化测试的技术选型

Web自动化测试工具种类繁多,选择标准应该从以下几个方面重点考虑:

开源免费

业界主流,发展趋势稳定上升

支持主流的浏览器(Chrome、 Firefox、IE等)

支持主流编程语言(Python、Java等)

Selenium的特点

开源免费

多浏览器支持:Chrome、Firefox、IE、Edge、Opera、Safari

多平台支持:Windows、Linux、Mac

多语言支持:Python、Java、Ruby、JavaScript、C#、C++

支持录制、回放和脚本生成(使用Selenium IDE)

支持分布式测试(使用Selenium Grid)

Selenium三剑客

通常所说的Selenium是对Selenium的总称,其中包含三个项目:

Selenium WebDriver,Selenium IDE,Selenium Grid

Selenium WebDriver是客户端API接口,测试人员通过调用这些接口,来访问浏览器驱动,浏览器驱动再访问浏览器。

Selenium IDE是一个浏览器插件,支持Chrome和Firefox浏览器,可以将手动测试过程记录下来生成自动化测试脚本,可以回放。对于初学者的学习脚本和回归测试很有帮助。

Selenium Grid适合分布式测试,例如电商平台的618、双11这种高并发的测试。可以再多台计算机上进行分布式扩容,并从一个中心点管理多个环境,从而轻松的多多种浏览器/OS的组合运行测试。

Selenium的前世今生

Selenium的命名

Selenium官网:www.seleniumhq.org

Selenium的命名比较有意思,ThoughtWorks的Jason Huggins在2004年发起了Selenium项目,当时的QTP mercury是主流的商业自化工具,是化学元素汞(俗称水银),而Selenium是开源自动化工具,是化学元素硒,硒可以对抗汞。

Selenium 1.0

用简单的公式:

Selenium 1.0 = Selenium IDE + Selenium Grid + Selenium RC

Selenium IDE

Selenium IDE是嵌入到Firefox浏览器中的一个插件,实现简单的浏览器操作的录制与回放功能。

Selenium Grid

Selenium Grid是一种自动化的测试辅助工具,Grid通过利用现有的计算机基础设施,能加快Web-App的功能测试。利用Grid可以很方便地实现在多台机器上和异构环境中运行测试用例。

Selenium RC

Selenium RC(Remote Control)是Selenium家族的核心部分。Selenium RC 支持多种不同语言编写的自动化测试脚本,通过Selenium RC的服务器作为代理服务器去访问应用,从而达到测试的目的。

Selenium RC分为Client Libraries和Selenium Server。Client Libraries库主要用于编写测试脚本,用来控制Selenium Server的库。Selenium Server负责控制浏览器行为。

Selenium1.0的核心是RC,它的工作原理是这样的:

在2006年的时候,Google的工程师Simon Stewart发起了WebDriver的项目;因为长期以来Google一直是Selenium的重度用户,但却被限制在有限的操作范围内。

Selenium RC 是在浏览器中运行JavaScript应用,使用浏览器内置的JavaScript翻译器来翻译和执行selenese命令(selenese是Selenium命令集合)。

WebDriver是通过原生浏览器支持或者浏览器扩展来直接控制浏览器。WebDriver针对各个浏览器而开发,取代了嵌入到被测Web应用中的JavaScript,与浏览器紧密集成,因此支持创建更高级的测试,避免了JavaScript安全模型导致的限制。除了来自浏览器厂商的支持之外,WebDriver还利用操作系统级的调用,模拟用户输入。

Selenium与WebDriver原是属于两个不同的项目,WebDriver的创建者Simon Stewart早在2009年8月的一份邮件中解释了项目合并的原因。

Selenium与WebDriver合并原因:为何把两个项目合并?部分原因是WebDriver解决了Selenium存在的缺点(例如能够绕过JavaScript沙箱,我们有出色的API),部分原因是Selenium解决了WebDriver存在的问题(例如支持广泛的浏览器),部分原因是因为Selenium的主要贡献者和我都觉得合并项目是为用户提供最优秀框架的最佳途径。

Selenium 2.0

因为Selenium和Webdriver的合并,所以,Selenium 2.0由此诞生。

简单用公式表示为:Selenium 2.0 = Selenium 1.0 + WebDriver

需要强调的是,在Selenium 2.0中主推的是WebDriver,可以将其看作Selenium RC的替代品。因为Selenium为了保持向下的兼容性,所以在Selenium 2.0中并没有彻底地抛弃Selenium RC。

Selenium2.0的核心是WebDriver。

Selenium 3.0

Selenium 3.0 = Selenium 2.0 - Selenium RC(Remote Control)

                      = Selenium IDE + Selenium Grid + WebDriver (Selenium三剑客)

Selenium 2.0 = Selenium 1.0 + WebDriver

Selenium 1.0 = Selenium IDE + Selenium Grid + Selenium RC

Selenium 3.0做了如下的更新:

1,去掉了RC

2,Selenium3.0只支持Java8版本以上。

3,Selenium3.0中的Firefox浏览器驱动独立了,以前装完selenium2就可以驱动Firefox浏览器了,现在和Chrome一样,必须下载和设置浏览器驱动。

4,MAC OS 集成Safari的浏览器驱动。默认在/usr/bin/safaridriver 目录下。

5,只支持IE 9.0版本以上。

Selenium 4.0

目前已经更新到4.X版本了,有新的特性以及更新了一些方法的使用。本文以3.0作为说明。

安装Selenium

先安装Python,再安装Selenium。

通过pip命令来安装Selenium:

浏览器驱动

为什么要下载浏览器驱动

Selenium升级到3.0之后,对不同的浏览器驱动进行了规范。如果想使用selenium驱动不同的浏览器,必须单独下载并设置不同的浏览器驱动。

常用浏览器驱动的官方下载地址:

selenium · PyPI

设置浏览器驱动

浏览器的驱动要下载和浏览器配套的版本。

将下载的浏览器驱动放到Python的安装目录下,并且配置系统环境变量:

配置系统环境变量路径:此电脑-->属性-->高级系统设置-->环境变量-->系统变量-->Path,将“C:\Python379”目录添加到Path的值中

测试浏览器驱动是否正常

IDE以Pycharm为例,创建 baidu.py文件,输入以下内容:

from selenium import webdriver

driver = webdriver.Chrome()

driver.get('https://www.baidu.com')

print(driver.title)

driver.quit()

若不报错,成功打印百度主页的title,说明浏览器驱动设置成功,可以继续进行接下来的操作了。

如报错,请根据报错提示检查和修复。

元素定位

Selenium定位方法

Selenium提供了8种定位方式。

id

name

class name

tag name

link text

partial link text

xpath

css selector

这8种定位方式在Python selenium中所对应的方法为:

find_element_by_id()

find_element_by_name()

find_element_by_class_name()

find_element_by_tag_name()

find_element_by_link_text()

find_element_by_partial_link_text()

find_element_by_xpath()

find_element_by_css_selector()

定位方法的用法

假如我们有一个Web页面,通过前端工具(如:Firebug 官网:https://getfirebug.com)查看到一个元素的属性是如下这样的:

<html>

<head>

<body link="#0000cc">

<a id="result_logo" href="/" οnmοusedοwn="return c({'fm':'tab','tab':'logo'})">

<form id="form" class="fm" name="f" action="/s">

<span class="soutu-btn"></span>

<input id="kw" class="s_ipt" name="wd" value="" maxlength="255" autocomplete="off">

如果我们的目的是要定位input标签的输入框。

通过id定位:

dr.find_element_by_id("kw")

通过name定位:

dr.find_element_by_name("wd")

通过class name定位:

dr.find_element_by_class_name("s_ipt")

通过tag name定位:

dr.find_element_by_tag_name("input")

通过xpath定位,xpath定位有N种写法,这里列几个常用写法:

dr.find_element_by_xpath("//*[@id='kw']")

dr.find_element_by_xpath("//*[@name='wd']")

dr.find_element_by_xpath("//input[@class='s_ipt']")

dr.find_element_by_xpath("/html/body/form/span/input")

dr.find_element_by_xpath("//span[@class='soutu-btn']/input")

dr.find_element_by_xpath("//form[@id='form']/span/input")

dr.find_element_by_xpath("//input[@id='kw' and @name='wd']")

通过css定位,css定位有N种写法,这里列几个常用写法:

dr.find_element_by_css_selector("#kw")

dr.find_element_by_css_selector("[name=wd]")

dr.find_element_by_css_selector(".s_ipt")

dr.find_element_by_css_selector("html > body > form > span > input")

dr.find_element_by_css_selector("span.soutu-btn> input#kw")

dr.find_element_by_css_selector("form#form > span > input")

页面上有一组文本链接:

<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>

<a class="mnav" href="http://www.hao123.com" name="tj_trhao123">hao123</a>

通过link text定位:

dr.find_element_by_link_text("新闻")

dr.find_element_by_link_text("hao123")

通过link text定位:

dr.find_element_by_partial_link_text("新")

dr.find_element_by_partial_link_text("hao")

dr.find_element_by_partial_link_text("123")

关于xpah和css的定位比较复杂,需要用到时可以单独学习,本文不展开:

XPath 语法

CSS 选择器参考手册

控制浏览器操作

控制浏览器窗口大小

有时候我们希望能以某种浏览器尺寸打开,让访问的页面在这种尺寸下运行。例如可以将浏览器设置成移动端大小(480* 800),然后访问移动站点,对其样式进行评估;WebDriver提供了set_window_size()方法来设置浏览器的大小。

from selenium import webdriver

import time

driver = webdriver.Chrome()

driver.get("http://m.baidu.com")

# 参数数字为像素点

print("设置浏览器宽480、高800显示")

driver.set_window_size(480, 800)

time.sleep(10)

driver.quit()

在PC端执行自动化测试脚本大多的情况下是希望浏览器在全屏幕模式下执行,可以使用maximize_window()方法使打开的浏览器全屏显示,其用法与set_window_size() 相同,它不需要参数。

from selenium import webdriver

import time

driver = webdriver.Chrome()

driver.get("https://www.baidu.com")

# 设置浏览器宽全屏显示,不需要参数

print("设置浏览器宽全屏显示")

driver.maximize_window()

time.sleep(10)

driver.quit()

控制浏览器后退、前进

在使用浏览器浏览网页时,浏览器提供了后退和前进按钮,可以方便地在浏览过的网页之间切换,WebDriver也提供了对应的back()和forward()方法来模拟后退和前进按钮。下面通过例子来演示这两个方法的使用。

from selenium import webdriver

driver = webdriver.Chrome()

driver.get('https://www.baidu.com')

# 访问百度首页

first_url = 'http://www.baidu.com'

print("now access %s" %(first_url))

driver.get(first_url)

print(driver.title)

# 访问新闻页面

second_url='http://news.baidu.com'

print("now access %s" %(second_url))

driver.get(second_url)

print(driver.title)

# 返回(后退)到百度首页

print("back to %s "%(first_url))

driver.back()

print(driver.title)

# 前进到新闻页

print("forward to %s"%(second_url))

driver.forward()

print(driver.title)

driver.quit()

为了看清脚本的执行过程,下面每操作一步都通过print()来打印当前的URL地址。

刷新页面

有时候需要手动刷新(F5) 页面,使用方法driver.refresh() ,刷新当前页面

WebDriver常用方法

点击和输入

定位元素只是第一步, 定位之后需要对这个元素进行操作, 或单击(按钮) 或输入(输入框) , 下面认识 WebDriver 中最常用的几个方法:

clear(): 清除文本。

send_keys (value): 模拟按键输入。

click(): 单击元素。

from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.baidu.com")

driver.find_element_by_id("kw").clear()

driver.find_element_by_id("kw").send_keys("selenium")

driver.find_element_by_id("su").click()

driver.quit()

提交

submit()

submit()方法用于提交表单。 例如, 在搜索框输入关键字之后的“回车” 操作, 就可以通过该方法模拟。

from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.baidu.com")

search_text = driver.find_element_by_id('kw')

search_text.send_keys('selenium')

search_text.submit()

driver.quit()

有时候 submit()可以与 click()方法互换来使用, submit()同样可以提交一个按钮, 但 submit()的应用范围远不及 click()广泛。

其他常用方法

size: 返回元素的尺寸。

text: 获取元素的文本。

get_attribute(name): 获得属性值。

is_displayed(): 设置该元素是否用户可见。

from selenium import webdriver

import time

driver = webdriver.Chrome()

driver.get("https://www.baidu.com")

# 获得输入框的尺寸

size = driver.find_element_by_id('kw').size

print(size)

# 返回百度页面底部备案信息

text = driver.find_element_by_class_name('s-bottom-layer-content').text

print(text)

# 返回元素的属性值, 可以是 id、 name、 type 或其他任意属性

attribute = driver.find_element_by_id("kw").get_attribute('type')

print(attribute)

# 返回元素的结果是否可见, 返回结果为 True 或 False

result = driver.find_element_by_id("kw").is_displayed()

print(result)

time.sleep(10)

driver.quit()

输出结果:

{'height': 44, 'width': 548}

设为首页关于百度About Baidu百度营销使用百度前必读意见反馈帮助中心京公网安备11000002000001号京ICP证030173号©2021 Baidu (京)-经营性-2017-0020

text

True

执行上面的程序并查看结果: size 方法用于获取百度输入框的宽、 高, text 方法用于获得百度底部的备案信息, get_attribute()用于获得百度输入的 type 属性的值, is_displayed()用于返回一个元素是否可见, 如果可见则返回 True, 否则返回 False。

鼠标事件

在 WebDriver 中, 将这些关于鼠标操作的方法封装在 ActionChains 类中提供。

ActionChains 类提供了鼠标操作的常用方法:

perform(): 执行所有 ActionChains 中存储的行为;

context_click(): 右击;

double_click(): 双击;

drag_and_drop(): 拖动;

move_to_element(): 鼠标悬停。

鼠标悬停操作

from selenium import webdriver

# 引入 ActionChains 类

from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Chrome()

driver.get("https://www.baidu.com")

# 定位到要悬停的元素

above = driver.find_element_by_link_text("更多")

# 对定位到的元素执行鼠标悬停操作

ActionChains(driver).move_to_element(above).perform()

说明:

from selenium.webdriver import ActionChains

导入提供鼠标操作的 ActionChains 类。

ActionChains(driver)

调用 ActionChains()类, 将浏览器驱动 driver 作为参数传入。

move_to_element(above)

context_click()方法用于模拟鼠标右键操作, 在调用时需要指定元素定位。

perform()

执行所有 ActionChains 中存储的行为, 可以理解成是对整个操作的提交动作。

键盘事件

Keys()类提供了键盘上几乎所有按键的方法。 前面了解到, send_keys()方法可以用来模拟键盘输入, 除此 之外, 我们还可以用它来输入键盘上的按键, 甚至是组合键, 如 Ctrl+A、 Ctrl+C 等。

from selenium import webdriver

# 引入 Keys 模块

from selenium.webdriver.common.keys import Keys

import time

driver = webdriver.Chrome()

driver.get("https://www.baidu.com")

# 输入框输入内容

driver.find_element_by_id("kw").send_keys("seleniumm")

time.sleep(2)

# 删除多输入的一个 m

driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)

time.sleep(2)

# 输入空格键+“教程”

driver.find_element_by_id("kw").send_keys(Keys.SPACE)

time.sleep(2)

driver.find_element_by_id("kw").send_keys("教程")

time.sleep(2)

# ctrl+a 全选输入框内容

driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'a')

time.sleep(2)

# ctrl+x 剪切输入框内容

driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'x')

time.sleep(2)

# ctrl+v 粘贴内容到输入框

driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'v')

time.sleep(2)

# 通过回车键来代替单击操作

driver.find_element_by_id("su").send_keys(Keys.ENTER)

time.sleep(10)

driver.quit()

演示代码为了能看清楚执行过程,可以加入sleep(2),正式测试代码不能加sleep等待方法。

上面的演示代码没有实际意义, 仅展示模拟键盘各种按键与组合键的用法。

说明:

from selenium.webdriver.common.keys import Keys

在使用键盘按键方法前需要先导入 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.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)

send_keys(Keys.F1) 键盘 F1

……

send_keys(Keys.F12) 键盘 F12

断言

不管是在做功能测试还是自动化测试,最后一步需要拿实际结果与预期进行比较。这个比较的称之为断言。

通常可以通过获取title 、URL和text等信息进行断言。text方法在前面已经讲过,它用于获取标签对之间的文本信息。 下面同样以百度为例,介绍如何获取这些信息。

from selenium import webdriver

from time import sleep

driver = webdriver.Firefox()

driver.get("https://www.baidu.com")

print('Before search================')

# 打印当前页面title

title = driver.title

print(title)

# 打印当前页面URL

now_url = driver.current_url

print(now_url)

driver.find_element_by_id("kw").send_keys("selenium")

driver.find_element_by_id("su").click()

sleep(1)

print('After search================')

# 再次打印当前页面title

title = driver.title

print(title)

# 打印当前页面URL

now_url = driver.current_url

print(now_url)

# 获取结果数目

sleep(3)

user = driver.find_element_by_class_name('nums').text

print(user)

sleep(10)

driver.quit()

脚本运行结果如下:

Before search================

百度一下,你就知道

https://www.baidu.com/

After search================

selenium_百度搜索

https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=selenium&fenlei=256&rsv_pq=f58b739f00005ced&rsv_t=dfc6adhvTMwlLK0URN0HpQmDI5YhaCf%2F%2ByTAk9xmtH9V8Vutx%2FSGErJI3DU&rqlang=cn&rsv_enter=0&rsv_dl=tb&rsv_sug3=8&rsv_btype=i&inputT=194&rsv_sug4=194

搜索工具

百度为您找到相关结果约75,500,000个

说明:

title:用于获得当前页面的标题。

current_url:用户获得当前页面的URL。

text:获取搜索条目的文本信息。

设置元素等待

WebDriver提供了两种类型的等待:显式等待和隐式等待。

显式等待

显式等待使WebDriver等待某个条件成立时继续执行,否则在达到最大时长时抛出超时异常(TimeoutException)。

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 as EC

driver = webdriver.Firefox()

driver.get("http://www.baidu.com")

element = WebDriverWait(driver, 5, 0.5).until(EC.presence_of_element_located((By.ID, "kw")))

element.send_keys('selenium')

driver.quit()

WebDriverWait类是由WebDirver 提供的等待方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常。具体格式如下:

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

driver :浏览器驱动。

timeout :最长超时时间,默认以秒为单位。

poll_frequency :检测的间隔(步长)时间,默认为0.5S。

ignored_exceptions :超时后的异常信息,默认情况下抛NoSuchElementException异常。

WebDriverWait()一般由until()或until_not()方法配合使用,下面是until()和until_not()方法的说明。

until(method, message=‘’)

调用该方法提供的驱动程序作为一个参数,直到返回值为True。

until_not(method, message=‘’)

调用该方法提供的驱动程序作为一个参数,直到返回值为False。

在本例中,通过as关键字将expected_conditions 重命名为EC,并调用presence_of_element_located()方法判断元素是否存在。

隐式等待

WebDriver提供了implicitly_wait()方法来实现隐式等待,默认设置为0。它的用法相对来说要简单得多。

from selenium import webdriver

from selenium.common.exceptions import NoSuchElementException

from time import ctime

driver = webdriver.Firefox()

# 设置隐式等待为10秒

driver.implicitly_wait(10)

driver.get("http://www.baidu.com")

try:

print(ctime())

driver.find_element_by_id("kw22").send_keys('selenium')

except NoSuchElementException as e:

print(e)

finally:

print(ctime())

driver.quit()

implicitly_wait() 默认参数的单位为秒,本例中设置等待时长为10秒。首先这10秒并非一个固定的等待时间,它并不影响脚本的执行速度。其次,它并不针对页面上的某一元素进行等待。当脚本执行到某个元素定位时,如果元素可以定位,则继续执行;如果元素定位不到,则它将以轮询的方式不断地判断元素是否被定位到。假设在第6秒定位到了元素则继续执行,若直到超出设置时长(10秒)还没有定位到元素,则抛出异常。

定位一组元素

WebDriver提供了8种用于定位一组元素的方法。

find_elements_by_id()

find_elements_by_name()

find_elements_by_class_name()

find_elements_by_tag_name()

find_elements_by_link_text()

find_elements_by_partial_link_text()

find_elements_by_xpath()

find_elements_by_css_selector()

定位一组元素的方法与定位单个元素的方法类似,唯一的区别是在单词element后面多了一个s表示复数。

接下来通过例子演示定位一组元素的使用:

from selenium import webdriver

from time import sleep

driver = webdriver.Chrome()

driver.get("https://www.baidu.com")

driver.find_element_by_id("kw").send_keys("selenium")

driver.find_element_by_id("su").click()

sleep(1)

# 定位一组元素

texts = driver.find_elements_by_xpath('//div/h3/a')

# 循环遍历出每一条搜索结果的标题

for t in texts:

print(t.text)

sleep(10)

driver.quit()

程序运行结果:

MeterSphere - 开源自动化测试平台

Selenium automates browsers. That's it!

Selenium(WEB自动化工具) - 百度百科

selenium中文网 | selenium安装、selenium使用、selenium...

Python+Selenium详解(超全)

Selenium Python 测试教程网

Python Selenium库的使用_凯耐的博客-CSDN博客_selenium

功能自动化测试工具——Selenium篇

selenium - 百度翻译

Selenium环境安装配置 - 环境配置 - 测试人社区

多表单切换

在Web应用中经常会遇到frame/iframe表单嵌套页面的应用,WebDriver只能在一个页面上对元素识别与定位,对于frame/iframe表单内嵌页面上的元素无法直接定位。需要通过switch_to.frame()方法将当前定位的主体切换为frame/iframe表单的内嵌页面中。

"""多表单切换"""

from selenium import webdriver

from time import sleep

class TestCase(object):

def __init__(self):

self.driver = webdriver.Chrome()

self.driver.get('http://sahitest.com/demo/framesTest.htm')

def test1(self):

top = self.driver.find_element_by_name('top')

self.driver.switch_to.frame(top)

self.driver.find_element_by_xpath('/html/body/table/tbody/tr/td[1]/a[1]').click()

self.driver.switch_to.default_content()

sleep(3)

second = self.driver.find_element_by_xpath('/html/frameset/frame[2]')

self.driver.switch_to.frame(second)

self.driver.find_element_by_xpath('/html/body/table/tbody/tr/td[1]/a[2]').click()

sleep(5)

self.driver.quit()

if __name__ == '__main__':

case = TestCase()

case.test1()

switch_to.frame(reference) :切换frame,reference是传入的参数,用来定位frame,可以传入id、name、index以及selenium的WebElement对象

switch_to_default_content() :返回主文档

switch_to_parent_frame() :返回父文档

多窗口切换

页面操作过程中有时候点击某个链接会弹出新的窗口,这时就需要主机切换到新打开的窗口上进行操作。WebDriver提# 多窗口切换

from selenium import webdriver

from time import sleep

driver = webdriver.Chrome()

driver.implicitly_wait(10)

driver.get("http://www.baidu.com")

# 获得百度搜索窗口句柄

search_windows = driver.current_window_handle

driver.find_element_by_link_text('登录').click()

driver.find_element_by_link_text("立即注册").click()

# 获得当前所有打开的窗口的句柄

all_handles = driver.window_handles

# 进入注册窗口

for handle in all_handles:

if handle != search_windows:

driver.switch_to.window(handle)

print('欢迎注册!')

sleep(3)

pass

driver.quit()供了switch_to.window()方法,可以实现在不同的窗口之间切换。

说明:

current_window_handle:获得当前窗口句柄。

window_handles:返回所有窗口的句柄到当前会话。

switch_to.window():用于切换到相应的窗口,与上一节的switch_to.frame()类似,前者用于不同窗口的切换,后者用于不同表单之间的切换。

警告框处理

WebDriver中处理JavaScript所生成的alert、confirm、prompt的具体做法是使用 switch_to.alert 方法定位到 alert/confirm/prompt,然后使用text/accept/dismiss/ send_keys等方法进行操作。

说明:

text:返回 alert/confirm/prompt 中的文字信息。

accept():接受现有警告框。

dismiss():解散现有警告框。

send_keys(keysToSend):发送文本至警告框。keysToSend:将文本发送至警告框。

例如,百度搜索设置弹出的窗口是不能通过前端工具对其进行定位的,这个时候就可以通过switch_to_alert()方法接受这个弹窗。

# 警告框处理

from selenium import webdriver

from selenium.webdriver.common.action_chains import ActionChains

from time import sleep

driver = webdriver.Chrome()

driver.implicitly_wait(10)

driver.get('http://www.baidu.com')

driver.maximize_window()

# 鼠标悬停至“设置”链接

link = driver.find_element_by_xpath('//span[@id="s-usersetting-top"]')

ActionChains(driver).move_to_element(link).perform()

# 打开搜索设置

sleep(2)

driver.find_element_by_xpath('//div[@class="s-user-setting-pfmenu"]/a[@class="setpref"]').click()

# 保存设置

driver.find_element_by_xpath('//div[@id="se-setting-7"]/a[@class="prefpanelgo setting-btn c-btn c-btn-primary"]').click()

sleep(2)

# 接受警告框

driver.switch_to.alert.accept()

driver.quit()通过switch_to_alert()方法获取当前页面上的警告框,并使用accept()方法接受警告框。

下拉框选择

WebDriver提供了Select工具类来处理下拉框:

"""下拉框选择"""

from selenium import webdriver

from time import sleep

import os

from selenium.webdriver.support.select import Select

class TestCase(object):

def __init__(self):

self.driver = webdriver.Chrome()

path = os.path.dirname(os.path.abspath(__file__))

file_path = 'file:///' + path + '/form.html'

self.driver.get(file_path)

def test_select(self):

se = self.driver.find_element_by_id('province')

select = Select(se)

select.select_by_index(0)

sleep(2)

select.select_by_value('sh')

sleep(2)

select.select_by_visible_text('西安')

sleep(2)

self.driver.quit()

if __name__ == '__main__':

case = TestCase()

case.test_select()

代码中的form表单的form.html代码如下:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

</head>

<body>

<form action="javascript:alert('test')">

provide:

<select name="province" id="province">

<option value="bj">北京</option>

<option value="xa">西安</option>

<option value="sh">上海</option>

</select>

</form>

</body>

</html>

说明:

Select类用于定位select标签。

Select_by_index() 根据索引选择。

select_by_value() 根据值选择。

select_by_visible_text()根据文本选择。

文件上传

对于通过input标签实现的上传功能,可以将其看作是一个输入框,即通过send_keys()指定本地文件路径的方式实现文件上传。

首先在Python工程同目录下创建upfile.html文件:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>upload_file</title>

</head>

<body>

<div class="row-fluid">

<div class="span6 well">

<h1>upload_file</h1>

<input type="file" name="file" />

</div>

</div>

</body>

</html>

通过浏览器打开upfile.html文件,功能如下:

接着通过send_keys()方法来实现文件上传。

"""文件上传"""

from selenium import webdriver

from time import sleep

import os

driver = webdriver.Chrome()

file_path = 'file:///' + os.path.abspath('upfile.html')

driver.get(file_path)

# 定位上传按钮,添加本地文件

driver.find_element_by_name('file').send_keys('C:\\Users\\pc\\PycharmProjects\\pythonProject1\\upload_file.txt')

sleep(3)

driver.quit()

cookie操作

因为基于真实cookie的测试是无法通过白盒和集成测试进行的。有时候我们需要验证浏览器中cookie是否正确,WebDriver提供了操作Cookie的相关方法,可以读取、添加和删除cookie信息。

WebDriver操作cookie的方法:

get_cookies(): 获得所有cookie信息。

get_cookie(name): 返回字典的key为“name”的cookie信息。

add_cookie(cookie_dict) : 添加cookie。“cookie_dict”指字典对象,必须有name 和value 值。

delete_cookie(name,optionsString):删除cookie信息。“name”是要删除的cookie的名称,“optionsString”是该cookie的选项,目前支持的选项包括“路径”,“域”。

delete_all_cookies(): 删除所有cookie信息。

举例:通过get_cookies()来获取当前浏览器的cookie信息。

from selenium import webdriver

driver = webdriver.Firefox()

driver.get("http://www.youdao.com")

# 获得cookie信息

cookie= driver.get_cookies()

# 将获得cookie的信息打印

print(cookie)

driver.quit()

从执行结果可以看出,cookie数据是以字典的形式进行存放的:

[{'domain': '.baidu.com', 'expiry': 1614657905, 'httpOnly': False, 'name': 'BA_HECTOR', 'path': '/', 'secure': False, 'value': '8t8k212h0ga500cg2h1g3rar10q'},

{'domain': '.baidu.com', 'httpOnly': False, 'name': 'H_PS_PSSID', 'path': '/', 'secure': False, 'value': '33515_33272_31660_33595_33570_33601_26350_22159'},

{'domain': 'www.baidu.com', 'expiry': 1614654305, 'httpOnly': False, 'name': 'BD_LAST_QID', 'path': '/', 'secure': False, 'value': '9538733699940937218'},

{'domain': '.baidu.com', 'expiry': 1646190304, 'httpOnly': False, 'name': 'BAIDUID', 'path': '/', 'secure': False, 'value': '7663FBCB3A34639C54E8F25076262EF7:FG=1'},

{'domain': '.baidu.com', 'expiry': 3762137951, 'httpOnly': False, 'name': 'BIDUPSID', 'path': '/', 'secure': False, 'value': '7663FBCB3A34639CA4A078B880E2933D'},

{'domain': '.baidu.com', 'expiry': 3762137951, 'httpOnly': False, 'name': 'PSTM', 'path': '/', 'secure': False, 'value': '1614654304'},

{'domain': 'www.baidu.com', 'expiry': 1615518305, 'httpOnly': False, 'name': 'BD_UPN', 'path': '/', 'secure': False, 'value': '12314753'},

{'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_HOME', 'path': '/', 'secure': False, 'value': '1'}

]

知道了cookie的存放形式,就可以按照这种形式向浏览器中写入cookie信息。

"""向浏览器添加cookie"""

from selenium import webdriver

driver = webdriver.Chrome()

driver.get("http://www.baidu.com")

# 向cookie的name 和value中添加会话信息

driver.add_cookie({'name': 'AAAAA', 'value': 'BBBBB'})

# 遍历cookies中的name 和value信息并打印,当然还有上面添加的信息

for cookie in driver.get_cookies():

print("%s -> %s" % (cookie['name'], cookie['value']))

driver.quit()

输出结果:

C:\Python379\python.exe C:/Users/pc/PycharmProjects/pythonProject1/add_cookie.py

AAAAA -> BBBBB

BA_HECTOR -> 0t8100052l802l6l281g3rbbn0r

H_PS_PSSID -> 33516_33638_33273_31254_33570

BD_LAST_QID -> 15048048474274682553

BAIDUID -> 3D16A792E75CDD10BFF718B4812751EE:FG=1

BIDUPSID -> 3D16A792E75CDD10F3EFD20DBFC21C54

PSTM -> 1614654838

BD_UPN -> 12314753

BD_HOME -> 1

Process finished with exit code 0从执行结果可以看到,第一条cookie信息是在脚本执行过程中通过add_cookie()方法添加的。通过遍历得到所有的cookie信息,从而找到key为“name”和“value”的特定cookie的value。

调用JavaScript代码

虽然WebDriver提供了操作浏览器的前进和后退方法,但对于浏览器滚动条并没有提供相应的操作方法。在这种情况下,就可以借助JavaScript来控制浏览器的滚动条。WebDriver提供了execute_script()方法来执行JavaScript代码。

"""调用js代码"""

from selenium import webdriver

from time import sleep

# 访问百度

from selenium.webdriver.common.keys import Keys

driver = webdriver.Chrome()

driver.get("http://www.baidu.com")

# 搜索

driver.find_element_by_id("kw").send_keys("测试")

driver.find_element_by_id('su').send_keys(Keys.ENTER)

sleep(2)

# 设置浏览器窗口大小

driver.set_window_size(500, 500)

# 通过javascript设置浏览器窗口的滚动条位置

js = "window.scrollTo(100,450);"

driver.execute_script(js)

sleep(10)

driver.quit()

通过Chrome浏览器打开百度进行搜索,并且提前通过set_window_size()方法将浏览器窗口设置为固定宽高显示,目的是让窗口出现水平和垂直滚动条。然后通过execute_script()方法执行JavaScripts代码来移动滚动条的位置。

窗口截图

自动化用例是由程序去执行的,因此有时候打印的错误信息并不十分明确。如果在脚本执行出错的时候能对当前窗口截图保存,那么通过图片就可以非常直观地看出出错的原因。WebDriver提供了截图函数get_screenshot_as_file()来截取当前窗口。

"""窗口截图"""

from selenium import webdriver

from time import sleep

from selenium.webdriver.common.keys import Keys

driver = webdriver.Chrome()

driver.get('http://www.baidu.com')

driver.find_element_by_id('kw').send_keys('selenium')

driver.find_element_by_id('su').send_keys(Keys.ENTER)

sleep(2)

# 截取当前窗口,并指定截图图片的保存位置

driver.get_screenshot_as_file("C:\\Users\\pc\\PycharmProjects\\pythonProject1\\baidu_img.png")

driver.quit()

脚本运行完成后打设置的截图保存的路径,就可以找到baidu_img.png图片文件了。

关闭浏览器

在前面的例子中我们一直使用quit()方法,其含义为退出相关的驱动程序和关闭所有窗口。除此之外,WebDriver还提供了close()方法,用来关闭当前窗口。多窗口的处理,在用例执行的过程中打开了多个窗口,我们想要关闭其中的某个窗口,这时就要用到close()方法进行关闭了。

close() 关闭单个窗口

quit() 关闭所有窗口

 这是我整理的《2024最新Python自动化测试全套教程》,以及配套的接口文档/项目实战【网盘资源】,需要的朋友可以下方视频的置顶评论获取。肯定会给你带来帮助和方向。

【已更新】B站讲的最详细的Python接口自动化测试实战教程全集(实战最新版)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/392675.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云计算学习——5G网络技术

系列文章目录 提示&#xff1a;仅用于个人学习&#xff0c;进行查漏补缺使用。 Day1 网络参考模型 Day2 网络综合布线与应用 Day3 IP地址 Day4 华为eNSP网络设备模拟器的基础安装及简单使用 Day5 交换机的基本原理与配置 Day6 路由器的原理与配置 Day7 网络层协议介绍一 Day8 …

Jpa-多表关联-OneToOne

Jpa-多表关联-OneToOne 准备JoinColumnOneToOne属性targetEntitycascade*PERSISTMERGEREMOVEREFRESH orphanRemovalfetchoptionalMappedBy* OneToOne在 hibernate中用于对表与表之间进行维护关联 准备 import com.alibaba.fastjson.JSON; import jakarta.persistence.*; impor…

AI8-文本检测

文本检测任务是找出图像或视频中的文字位置。不同于目标检测任务,目标检测不仅要解决定位问题,还要 解决目标分类问题。 文本在图像中的表现形式可以视为一种‘目标‘,通用的目标检测的方法也适用于文本检测,从任务本身上来 看: • 目标检测:给定图像或者视频,找出目…

本地部署 faster-whisper

本地部署 faster-whisper 1. 创建虚拟环境2. 安装依赖模块3. 创建 Web UI4. 启动 Web UI5. 访问 Web UI 1. 创建虚拟环境 conda create -n faster-whisper python3.11 -y conda activate faster-whisper2. 安装依赖模块 pip install torch2.2.2 torchvision0.17.2 torchaudio…

bilibili实习生一面0625

OSI七层模型 物理层&#xff1a;将帧中的比特传送到下一个节点&#xff08;比特&#xff09; 数据链路层&#xff1a;将数据包装成帧并传送到路径上下一个节点&#xff0c;将相邻节点间不可靠的物理链路变成可靠的逻辑链路&#xff08;帧&#xff09; 网络层&#xff1a;路由寻…

Qt 5.14安装(配置MSVC 2017)

Qt 5.14安装&#xff08;配置MSVC 2017&#xff09; 记录一下自己安装配置Qt的步骤。 我需要安装Qt&#xff0c;并使用MSVC编译&#xff0c;所以才写了这篇文章。 一、环境 操作系统&#xff1a;windows 11 &#xff08;64位&#xff09; Qt&#xff1a;Qt 5.14.2 vs&…

怎么读取FRM、MYD、MYI数据文件

一、介绍frm、MYD、MYI文件 在MySQL中&#xff0c;使用MyISAM存储引擎时&#xff0c;数据库表会被分割成几个不同的文件文件描述功能扩展名FRM 文件表结构定义文件存储表的结构信息&#xff0c;字段、索引等.FRMMYD 文件数据文件包含表的实际数据.MYD&#xff08;MYData&#x…

[米联客-安路飞龙DR1-FPSOC] UDP通信篇连载-04 IP层程序设计

软件版本&#xff1a;Anlogic -TD5.9.1-DR1_ES1.1 操作系统&#xff1a;WIN10 64bit 硬件平台&#xff1a;适用安路(Anlogic)FPGA 实验平台&#xff1a;米联客-MLK-L1-CZ06-DR1M90G开发板 板卡获取平台&#xff1a;https://milianke.tmall.com/ 登录“米联客”FPGA社区 ht…

学习笔记-MYSQL 事务

目录 一、什么是事务&#xff1f; 二、事务的四个特征&#xff08;ACID&#xff09;【面试常考项】 原子性&#xff08;Atomicity&#xff09; 一致性&#xff08;Consistency&#xff09; 隔离性&#xff08;Isolation&#xff09; 持久性&#xff08;Durability&#x…

Linux-理解shell

文章目录 5. 理解shell5.1 shell的类型5.2 交互shell和系统默认shell5.3 安装zsh shell程序5.4 shell的父子关系5.5 命令列表5.6 命令分组5.7 使用命令分组创建子shell5.8 子shell用法5.9 shell的非内建命令和内建命令5.9.1 非内建命令5.9.2 内建命令5.9.3 history和alias命令介…

AI9-文本识别

本章主要介绍文本识别算法的理论知识,包括背景介绍、算法分类和部分经典论文思路。 通过本章的学习,你可以掌握: 1. 文本识别的目标 2. 文本识别算法的分类 3. 各类算法的典型思想 1 背景介绍 文本识别是OCR(Optical Character Recognition)的一个子任务,其任务为识别一个…

基于 Redis 的分布式信号量 Spring Boot 集成 Redisson 使用 Semaphore 控制并发访问数量

目录 前言 pom yml Controller 演示 注意 前言 工作中开发过一个服务&#xff0c;这里记作A服务&#xff0c;主要功能是配置&#xff0c;部署以及调用云函数。其中配置云函数的功能里&#xff0c;有一个配置项是并发数&#xff0c;意思是同一时间最多能有多少个请求调用…

【MATLAB源码】数学建模基础教程(2)--层次分析法(评价类算法)

系列文章目录在最后面&#xff0c;各位同仁感兴趣可以看看&#xff01; 层次分析法 引言一、层次分析法的特点二、模型的建立求解过程 (1)问题的提出&#xff1a;实际问题的转化(2)建立层次结构模型(3)构造判断(成对比较)矩阵(4)一致性检验&#xff1a;三、层次分析法的优点与…

Codeforces Round 871 (Div. 4)(A~H)

比赛链接 Dashboard - Codeforces Round 871 (Div. 4) - Codeforces A. Love Story 找到与codeforces 有多少个不同的字符。 #include<bits/stdc.h> #define int long long #define TEST int T; cin >> T; while (T--) #define ios ios::sync_with_stdio(fals…

前端常用的性能优化方案

目录 性能分析工具lighthouseWebpack Bundle分析 开发阶段按需引入路由懒加载 打包阶段打包配置减少包体积配置压缩分包 资源预加载/预请求 部署阶段开启http2静态资源缓存gzip压缩 性能优化主要在三个阶段进行&#xff1a;开发阶段、开发结束后的打包阶段、项目部署上线阶段 首…

提升生产效率:APS高级计划排程系统在车间工序级排程的革命性应用

在制造业的数字化转型浪潮中&#xff0c;APS高级计划排程系统以凭借自身卓越的排程运算能力和应用灵活性&#xff0c;已经成为中大型制造业提升生产效率的关键工具。APS系统的介入&#xff0c;打通了传统ERP和MES等各类业务系统运营平台&#xff0c;并且通过产能均衡规划&#…

为什么我3d模型选择面选不到?---模大狮模型网

在展览3D模型设计行业中&#xff0c;设计师常常面临诸多技术挑战&#xff0c;其中之一是在模型编辑过程中遇到选择面的困难。这不仅影响了设计工作效率&#xff0c;还可能影响最终作品的质量和展示效果。本文将探讨在3D模型设计中为何会遇到“为什么我3D模型选择面选不到?”这…

【MySQL进阶篇】管理

1、系统数据库 MySQL数据库安装完成之后&#xff0c;自带以下四个数据库&#xff0c;具体作用如下&#xff1a; 数据库含义mysql存储MySQL服务器正常运行所需要的各种信息&#xff08;时区、主从、用户、权限等&#xff09;information_schema提供了访问数据库元数据的各种表…

实战OpenCV之环境安装与配置

OpenCV是什么 OpenCV&#xff0c;英文全称为Open Source Computer Vision Library&#xff0c;是一个开源的计算机视觉和机器学习软件库。它设计用于提供一系列功能强大的算法&#xff0c;以帮助开发者处理图像和视频数据&#xff0c;实现各种视觉任务&#xff0c;包括&#xf…

.NET内网实战:模拟Installer关闭Defender

01基本介绍 02编码实现 原理上通过Windows API函数将当前进程的权限提升至TrustedInstaller&#xff0c;从而实现了对Windows Defender服务的控制。通常可以利用Windows API中的OpenSCManager、OpenProcessToken、ImpersonateLoggedOnUser以及ControlService等函数协同工作&am…