Python3-Selenium开启自动化测试

一、Selenium简介

Selenium是一款适用于Web应用程序的便携式软件测试框架。 Selenium为编写测试提供了一个回放工具,无需学习测试脚本语言。它还提供了一种测试领域特定的语言,用于编写包括C#,Groovy,Java,Perl,PHP,Python,Ruby和Scala等多种流行编程语言的测试。

Selenium官网地址

环境配置:

系统:windows10 浏览器:Chrome 70.0.3538.110 Python: 3.7.0 Selenium: 3.141.0


二、Selenium的安装与测试

2.1 Selenium安装

使用Python可直接利用pip进行安装selenium > pip install selenium

2.2 浏览器驱动driver安装

2.2.1 浏览器驱动driver的下载

注意:driver的下载需要注意对应浏览器的版本

2.2.2 浏览器驱动driver的安装

下载下来的zip文件解压至python安装目录中,可以放在: C:中,但是推荐放置在scripts目录中:C:

完成以上工作,我们就可以进行测试使用selenium驱动浏览器了。

2.3 测试驱动浏览器

1
2
3
4
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.quit() # 使用quit()关闭了chrome并结束了此次测试,如果是close()只是关闭chrome,后台仍在进行。

看起来正常驱动浏览器并打开了网页,这样我们就完成了selenium自动化测试的准备工作~!

完成环境的安装并测试之后,我们对Selenium有了一定的了解,接下来我们继续驱动浏览器做一些基本操作。 ****** ### 三、窗口尺寸设置、网页截图、刷新、前进和后退 #### 3.1 窗口尺寸设置 在测试过程中,我们可能会要求打开浏览器的窗口处于最大化或者设置为某一特定尺寸的大小,所以我们使用selenium驱动浏览器时设定窗口大小.

1
2
3
4
5
6
7
8
9
10
11
12
from selenium import webdriver

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

size = driver.get_window_size() # 获取窗口尺寸

driver.set_window_size(800,600) # 设置窗口尺寸

driver.minimize_window() # 最小化窗口

driver.maximize_window() # 最大化窗口
#### 3.2 网页截图
1
driver.get_screenshot_as_file(u'D:\\xxx.png')  # 前缀u解决编码问题

3.3 刷新、前进和后退

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from selenium import webdriver
import time
driver.get("https://www.baidu.com")
time.sleep(3)
driver.get("https://www.google.com")
time.sleep(3)

# 进行后退、前进操作
driver.back() # 后退
time.sleep(3)
driver.forward() # 前进
time.sleep(3)
driver.refresh() # 对网页进行刷新

driver.quit()

四、定位元素

selenium提供了多种方式进行定位元素:find_element_by_*

1
2
3
4
5
6
7
8
find_element_by_id
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
当然也可以一次定位多个元素:find_elements_by_*
1
2
3
4
5
6
7
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
因为id是唯一的,所以一次定位多个元素是没有办法通过id进行定位的。 ****** ### 五、对定位到的元素进行操作 我们通过find_element_by_xpath等一系列定位元素的方法获取到网页元素(文本框、按钮等)后,我们可以通过一些函数来对元素进行操作。 #### 5.1 输入和点击
1
2
3
4
5
driver.find_element_by_xpath('').clear() # 清空文本框内容
driver.find_element_by_xpath('').send_keys() # 向文本框中输入内容
driver.find_element_by_xpath('').click() # 鼠标单击操作
driver.find_element_by_xpath('').submit() # 对信息进行提交,相当于回车
# submit()要求提交对象是一个表单,click()更强调事件的独立性

5.2 获取元素属性

通过定位元素位置后,就可以获得元素的诸多属性信息,当然是源代码中元素属性存在的情况下。

1
2
3
4
5
6
7
8
9
10
11
12
13
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("http://qzmvc1.top/")

a1 = driver.find_element_by_xpath('//*[@id="post-进击数据挖掘十大算法-四-C4-5决策树"]/div/header/h1/a')
print(a1)
print(a1.get_attribute('href'))
print(a1.text)
print(a1.tag_name)
print(a1.size)

driver.quit()

在上述代码中,依次通过 .get_attribute(‘href’)element.textelement.tag_nameelement.size获得了属性值href、元素文本内容、元素标签名、元素尺寸这些常用的方法。 ****** ### 六、键盘和鼠标模拟 #### 6.1 键盘事件

1
2
3
4
5
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

# 示例
driver.find_element_by_xpath('xxx').send_keys(Keys.BACK_SPACE) # 利用backspace键删除字符串最后一位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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

6.2 鼠标事件

ActionChains是一种自动执行低级别交互的方法,例如鼠标移动,鼠标按钮操作,按键和上下文菜单交互。这对于执行更复杂的操作非常有用,例如悬停和拖放。 + 在ActionChains对象上调用操作方法时,操作将存储在ActionChains对象的队列中。 + 当调用perform()时,事件将按它们排队的顺序触发

ActionChains可以用于链式或者可以将操作逐个排队,然后执行。

无论哪种方式,动作都按照它们被调用的顺序执行,一个在另一个之后执行。

这里还是以代码展示部分功能吧: ###### 方法一:可以写一长串

1
2
3
4
5
from selenium.webdriver.common.action_chains import ActionChains

menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")
ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()
###### 方法二:可以分几步写
1
2
3
4
5
6
menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")
actions = ActionChains(driver)
actions.move_to_element(menu)
actions.click(hidden_submenu)
actions.perform()
其他操作如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
click(on_element=None) ——单击鼠标左键

click_and_hold(on_element=None) ——点击鼠标左键,不松开

context_click(on_element=None) ——点击鼠标右键

double_click(on_element=None) ——双击鼠标左键

drag_and_drop(source, target) ——拖拽到某个元素然后松开

drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某个坐标然后松开

key_down(value, element=None) ——按下某个键盘上的键

key_up(value, element=None) ——松开某个键

move_by_offset(xoffset, yoffset) ——鼠标从当前位置移动到某个坐标

move_to_element(to_element) ——鼠标移动到某个元素

move_to_element_with_offset(to_element, xoffset, yoffset) ——移动到距某个元素(左上角坐标)多少距离的位置

perform() ——执行链中的所有动作

release(on_element=None) ——在某个元素位置松开鼠标左键

send_keys(*keys_to_send) ——发送某个键到当前焦点的元素

send_keys_to_element(element, *keys_to_send) ——发送某个键到指定元素
****** ### 七、下拉框和弹窗 #### 7.1 下拉框 ##### 7.1.1 首先导入Select模块:
1
2
from selenium import webdriver
from selenium.webdriver.support.select import Select
##### 7.1.2 Select提供了三种选择某一项的方法
1
2
3
1 select_by_index          # 通过索引定位
2 select_by_value # 通过value值定位
3 select_by_visible_text # 通过文本值定位
>注意事项: > >index索引是从“0”开始; > >value是option标签的一个属性值,并不是显示在下拉框中的值; > >visible_text是在option标签中间的值,是显示在下拉框的值;

7.1.3 Select提供了三种返回options信息的方法
1
2
3
1 options                  # 返回select元素所有的options
2 all_selected_options # 返回select元素中所有已选中的选项
3 first_selected_options # 返回select元素中选中的第一个选项

注意事项:

这三种方法的作用是查看已选中的元素是否是自己希望选择的:

options:提供所有选项的元素列表;

all_selected_options:提供所有被选中选项的元素列表;

first_selected_option:提供第一个被选中的选项元素;

7.1.4 Select提供了四种取消选中项的方法
1
2
3
4
1 deselect_all             # 取消全部的已选择项
2 deselect_by_index # 取消已选中的索引项
3 deselect_by_value # 取消已选中的value值
4 deselect_by_visible_text # 取消已选中的文本值

注意事项:

在日常的web测试中,会经常遇到某些下拉框选项已经被默认选中,这种时候就需要用到这里所说的四种方法

7.1.5 代码示例
1
2
3
4
5
6
7
8
9
from selenium import webdriver
from selenium.webdriver.support.select import Select

# 根据索引选择
Select(driver.find_element_by_name("xxx")).select_by_index("xxx")
# 根据value值选择
Select(driver.find_element_by_name("xxx")).select_by_value("xxx")
# 根据文本值选择
Select(driver.find_element_by_name("xxx")).select_by_visible_text("xxx")

7.2 弹窗

在完成某些操作时会弹出对话框来提示,主要分为”警告消息框”,“确认消息框”,“提示消息对话”三种类型的对话框。

1.警告消息框(alert)   警告消息框提供了一个”确定”按钮让用户关闭该消息框,并且该消息框是模式对话框,也就是说用户必须先关闭该消息框然后才能继续进行操作。

2.确认消息框(confirm)   确认消息框向用户提示一个”是与否”问题,用户可以根据选择”确定”按钮和”取消”按钮。

3.提示消息对话(prompt)   提示消息框提供了一个文本字段,用户可以在此字段输入一个答案来响应您的提示。该消息框有一个”确定”按钮和一个”取消”按钮。选择”确认”会响应对应的提示信息,选择”取消”会关闭对话框。

selenium 提供switch_to.alert()方法定位到 alert/confirm/prompt对话框。使用 text/accept/dismiss/send_keys 进行操作,这里注意的是send_keys只能对prompt进行操作。

1
2
3
4
5
6
7
8
9
10
switch_to.alert()   #定位弹出对话
text    #获取对话框文本值
accept() #相当于点击"确认"
dismiss() #相当于点击"取消"
send_keys() # 输入值,只能对prompt使用。

alert = driver.switch_to.alert()
alert.text
alert.accept()
alert.dismiss()

八、等待方式

在webdriver只有两种类型等待方式,显式等待和隐式等待,之前是在程序运行过程中使用time模块中的sleep进行代码的休眠进行强制等待,是显式等待中的一种极端情况。 #### 8.1 显式等待 显式等待是你在代码中定义等待一定条件发生后再进一步执行你的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from time import ctime
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.Chrome()
driver.get('https://www.baidu.com')

try:
print(ctime())
element = WebDriverWait(dr, 10).until(
EC.presence_of_element_located((By.ID, "kw"))
)
# WebDriverWait(driver=self.driver, timeout=300, poll_frequency=0.5, ignored_exceptions=None)
# driver:浏览器驱动
# timeout:最长超时等待时间
# poll_frequency:检测的时间间隔,默认为500ms
# ignore_exception:超时后抛出的异常信息,默认情况下抛出 NoSuchElementException 异常
print("我已找到")
finally:
print(ctime())
driver.quit()
以上代码执行后就发现,整段代码执行速度非常快,即使我在WebDriverWait中设置10秒,也不会等待10秒的情况,因为在不到一秒内,已经完成了加载并定位id为“kw”的元素。

通过WebDriverWait 和 ExpectedCondition 组合使用,让我们的代码执行只需要等待需要的时长,而不是固定的时长,这样最大限度的节省时间。

此外ExpectedCondition类中提供了很多预期条件判断方法,省去了再创建包的功夫:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
title_is:判断当前页面的title是否等于预期
title_contains:判断当前页面的title是否包含预期字符串
presence_of_element_located:判断某个元素是否被加到了dom树里,并不代表该元素一定可见
visibility_of_element_located:判断某个元素是否可见. 可见代表元素非隐藏,并且元素的宽和高都不等于0
visibility_of:跟上面的方法做一样的事情,只是上面的方法要传入locator,这个方法直接传定位到的element就好了
presence_of_all_elements_located:判断是否至少有1个元素存在于dom树中。举个例子,如果页面上有n个元素的class都是'column-md-3',那么只要有1个元素存在,这个方法就返回True
text_to_be_present_in_element:判断某个元素中的text是否 包含 了预期的字符串
text_to_be_present_in_element_value:判断某个元素中的value属性是否包含了预期的字符串
frame_to_be_available_and_switch_to_it:判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False
invisibility_of_element_located:判断某个元素中是否不存在于dom树或不可见
element_to_be_clickable - it is Displayed and Enabled:判断某个元素中是否可见并且是enable的,这样的话才叫clickable
staleness_of:等某个元素从dom树中移除,注意,这个方法也是返回True或False
element_to_be_selected:判断某个元素是否被选中了,一般用在下拉列表
element_located_to_be_selected
element_selection_state_to_be:判断某个元素的选中状态是否符合预期
element_located_selection_state_to_be:跟上面的方法作用一样,只是上面的方法传入定位到的element,而这个方法传入locator
alert_is_present:判断页面上是否存在alert

8.2 隐式等待

隐式等待,就是在创建driver时,为浏览器对象创建一个等待时间,这个方法是得不到某个元素就等待一段时间,直到拿到某个元素位置。

1
driver.implicity_wait(10)
implicity_wait()默认参数的单位为妙,本例中设置等待时长为10秒,首先这10秒并非一个固定的等待时间,它并不影响脚本的执行速度。其次,它并不针对页面上的某一元素进行等待。当脚本执行到某个元素定位是,如果元素可以定位,则继续执行,如果元素定位不到,则它将以轮询的方式不断地判断元素是否被定位到。假设在第六秒定位到了元素则继续执行,若直到超出设置的时长10秒还没有定位到元素,则抛出异常。 ****** ### 九、iframe切换
1
2
driver.switch_to.frame('')                  # 选择iframe
driver.switch_to.default_content() # 回到主页面
说明:switch_to_frame接受的参数是iframe的id或者name属性,如果没有,则可以通过find_element_by_tag_name(‘iframe’)找到iframe,然后作为参数定位。 ****** 参考链接:https://www.cnblogs.com/lvzb86/