自动化测试

web自动化基本代码

步骤:
1、导包
2、实例化浏览器对象
3、打开网页
4、时间轴观察效果
5、关闭网页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import time
from selenium import webdriver

# 定义chrome驱动路径
chrome_driver_path = r'E:\chromedriver-win64\chromedriver-win64\chromedriver.exe'
service = Service(chrome_driver_path)

# 创建 Chrome 驱动
driver = webdriver.Chrome(service=service)

# 打开百度
driver.get("http://localhost:8080")

# 时间轴观察效果
sleep(5)

# 关闭网页
driver.quit()

八大元素定位

1、为什么要使用元素定位?

计算机无法向人一样,所见即所得,因此需要通过元素定位来指定计算机所定位的元素来进行操作

2、定位工具:

1)、谷歌使用 F12 进入开发者工具

2)、右键点击检查进入开发者工具

3、定位元素是依赖于什么?

标签名、属性、层级、路径

定位方式:
1、id
2、name
3、class_name(使用的是class属性进行定位)
4、teg_name (标签名称)
5、link_text(定位超链接 a 标签)
6、partial_link_text(定位超链接 a 标签 包含关系)
7、xpath (路径)
8、css (元素选择器)

注意:这是 selenium 框架中提供的八大元素定位方法,只要能够定位目标元素,用哪一种都无所谓,最常用的是 id ,xpath,css

3.1 id定位方法

说明:通过元素的id属性定位,id一般情况下在当前页面中是唯一。

提示:元素必须要有id属性。

1
2
3
4
5
6
# 语法:
find_element(By.ID, id)

1、元素定位:首先调用find_element(By.ID, id)获得元素定位
2、调用send_keys来填写内容
3、通过⽬标元素的 id 属性值定位, 由于 id 值一般是唯一的,因此当元素存在 id 属性值时, 优先使用 id 方法定位元素

3.2 name定位方法

说明:通过元素的name属性来定位, name一般名称为重复

提示:元素必须要有name属性

1
2
3
4
5
6
# 语法:
find_element(By.NAME, name)

1、name方法:由于元素的 name 属性值可能存在重复, 必须确定其能够代表⽬标元素唯⼀性之后, ⽅可使⽤
2、当页⾯面内有多个元素的特征值是相同的时候, 定位元素的⽅法执⾏时,默认只会获取第⼀个符合要求的特征对应的元素
3、因此, 定位元素时需要尽量保证使⽤的特征值能够代表⽬标元素在当前⻚页⾯内的唯⼀性!否则定不了位,添加在第一个定位的位置

3.3 class_name 方法

说明:通过元素的class属性来定位,class属性一般为多个值。

提示:元素必须要有class属性

1
2
3
4
5
6
7
8
# 语法
find_element(By.CLASS_NAME, class_name)

注意:

1、方法名是class_name ,但是我们找的是class属性

2、如果元素的 class 属性值存在多个值, 在 class_name 方法使用时, 只能使⽤其中的任意⼀一个

3.4 tag_name 方法

说明:通过元素的标签名称来定位,标签名(查看元素时尖括号(<)紧挨着的单词或字母就是标签名) (标签名也就是元素名)

1
2
3
4
5
6
7
8
# 语法
find_element(By.TAG_NAME, 'tag_name')

注意:

tag_name 方法:由于存在大量标签,并且重复性更高,因此必须确定其能够代表目标元素唯一性之后,方可以使用;如果页面中存在多个相同标签,默认返回第一个标签元素。

注意:一般标签重复性过高,要精确定位,都不会选择tag_name !

说明:定位超链接标签

1
2
3
4
5
6
7
8
# 语法
driver.find_element(By.LINK_TEXT, 'link_text')

注意:

1、只能使用精准匹配(a标签的全部文本内容)

2、该⽅法只针对超链接元素(a 标签),并且需要输入超链接的全部⽂本信息

说明:定位超链接标签

1
2
3
4
5
6
7
8
# 语法
find_element(By.PARTIAL_LINK_TEXT, '模糊匹配')

注意:

1. 可以使用精准或模糊匹配,如果使用模糊匹配最好使用能代表唯一的关键词

2. 如果有多个值,默认返回第一个值

3.7 定位一组元素的方法

说明:执行结果返回的是列表类型,里面的数据是多个元素对象。

1
2
3
4
5
6
7
8
9
10
# 语法
driver.find_elements(By.ID/TAG_NAME, '')

注意:

1、我们可以获取列表下标获取对应的目标元素

2、其他元素定位方法也可以实行定义一组元素

3、使用标签名定位操作

总结:

1、id,name,class,都是依赖于元素这三个对应的属性,如果元素没有这个三个属性,定位方法不能使用;

2、link_text, partial_link_text: 只适合超链接定位

3、tag_name: 只能找页面唯一元素,或者 页面中多个相同元素中的第一个元素

3.8 xpath ☆

说明:Xpath策略有多种,无论使用哪一种策略(方法),定位的方法都是同一个,不同策略只决定方法的参数的写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 语法
find_element(By.XPATH, 'Xpath的策略')

注意:

3.8.1 获取路径策略
1、什么是Xpath定位:

基于元素的路径定位

2、Xpath常用的定位策略:

绝对路径:从最外层元素到指定元素之间所有经过元素层级的路径 ,绝对路径是以/html根节点开始,使用 / 来分割元素层级
语法:/html/body/div/fieldset/form/p[1]/input (可能会有多个p标签,所以也是用索引的方式定位,是从一开始以便读者看懂)
绝对路径对页⾯结构要求比较严格,不建议使⽤!!!!

相对路径:匹配任意层级的元素,不限制元素的位置 ,相对路径是以 // 开始, // 跟元素名称,不知元素名称可以使用*代替。
语法://input 或者 //*
推荐使用相对路径!!

3.8.2 利用元素属性策略

1、路径结合属性

该方法可以使用目标元素的任意一个属性和属性值(需要保证唯⼀性)

1
2
3
4
5
6
7
8
# 语法1://标签名[@属性名='属性值']
# 语法2://*[@属性名='属性值']

注意:

1、使用 XPath 策略, 需要在浏览器⼯具中根据策略语法, 组装策略值,验证后再放入代码中使用

2、⽬标元素的有些属性和属性值, 可能存在多个相同特征的元素, 需要注意唯一性

2、路径结合逻辑(多个属性)

解决的是单个属性和属性值无法定位元素唯一性的问题。

1
2
3
4
# 语法: //*[@属性1="属性值1" and @属性2="属性值2"]

注意:多个属性可有由 多个 and 链接,每一个属性前面都要有 @ 开头,可以根据需求使用更多属性值

3、层级和属性结合策略

目标元素⽆法直接定位, 可以考虑先定位其父层级或祖辈层级, 再获取目标元素

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
30
31
32
33
34
35
36
# 语法://*[@id='父级id属性值']/input    (⽗层级定位策略/目标元素定位策略)

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

# 实例化浏览器对象
driver = webdriver.Chrome()
# 打开网址url
driver.get('https://www.baidu.com/')

# 需求
# 1、相对路径
ele = driver.find_element(By.XPATH, '//*[@id="kw"]')
ele.send_keys('深圳')

# 2、绝对路径
driver.find_element(By.XPATH, '/html/body/div[1]/div[2]/div[5]/div[1]/div/form/span[1]/input').send_keys('易烊千玺')

# 3、路径结合属性 语法1://标签名[@属性名='属性值']
driver.find_element(By.XPATH, "//input[@id='kw']").send_keys('深圳')
# 语法2: //*[@属性名='属性值']
driver.find_element(By.XPATH, "//*[@id='kw']").send_keys('深圳')

# 4、路径结合逻辑(多个属性)
driver.find_element(By.XPATH, "//*[@id='kw' and @name ='wd']").send_keys('深圳')

# 5、层级和属性结合策略
driver.find_element(By.XPATH, "//*[@id='s_kw_wrap']/input").send_keys('深圳')

# 观察效果
sleep(3)

# 关闭网页
driver.quit()

3.8.3 xpath 扩展
1
2
3
4
5
6
1. //*[text()='文本信息'] # 定位文本值等于XXX的元素  
提示:一般适合 p标签,a标签
2. //*[contains(@属性,'属性值的部分内容')] # 定位属性包含xxx的元素 【重点】
提示:contains为关键字,不可更改。
3. //*[starts-with(@属性,'属性值的开头部分')] # 定位属性以xxx开头的元素
提示:starts-with为关键字不可更改

3.9 css定位 ☆

通过 css 的选择器语法定位元素

1、Selenium框架官方推荐使用 css ,因为定位效率高于xpath

2、 CSS一种标记语言,焦点:数据的样式。控制元素的显示样式,就必须先找到元素,在css标记语言中找元素使用css选择器;

3、css的选择策略也有很多,但是无论选择哪一种选择策略都是用的同一种定位方法

常用策略:
1、id 选择器
语法:#id属性值
2、class 选择器
语法:.class属性值(如果使⽤具有多个值的 class 属性,则需要传入全部的属性值 语法:[class=”全部属性值”])
3、属性选择器
语法1:[属性名=“属性值”]
语法2:标签名[属性名=“属性值”]
4、标签选择器
语法:标签名 如input,button
5、层级选择器
父子层级关系:父层级策略 > 子层级策略 (也可以使用空格连接上下层级策略)
祖辈后代层级关系:祖辈策略 后代策略
提示:>与空格的区别,大于号必须为子元素,空格则不用。

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
30
31
32
33
34
# 语法
find_element(By.CSS_SELECTOR, 'css策略')

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

# 实例化浏览器对象
driver = webdriver.Chrome()
# 打开网址url
driver.get('https://www.baidu.com/')

# 需求
# 语法id:#id属性值
driver.find_element(By.CSS_SELECTOR, '#kw').send_keys('易烊千玺')

# 语法class:.class属性值 如: '.talA'
# 语法class有多个属性值的时候:[class="全部属性值"]
driver.find_element(By.CSS_SELECTOR, '[class="s_ipt"]').send_keys('易烊千玺')

# 语法属性选择器
driver.find_element(By.CSS_SELECTOR, 'input[id="kw"]').send_keys('易烊千玺')
driver.find_element(By.CSS_SELECTOR, '[name="wd"]').send_keys('易烊千玺')

# 语法层级选择器
# 父层级策略 > 子层级策略
driver.find_element(By.CSS_SELECTOR, '#s_kw_wrap>input').send_keys('易烊千玺')
driver.find_element(By.CSS_SELECTOR, '#form input').send_keys('易烊千玺')

sleep(3)

# 关闭网页
driver.quit()

3.9.1 css的扩展方法 ☆
  1. [属性^=’开头的字母’] # 获取指定属性以指定字母开头的元素
  2. [属性$=’结束的字母’] # 获取指定属性以指定字母结束的元素
  3. [属性*=’包含的字母’] # 获取指定属性包含指定字母的元素
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 sleep
from selenium import webdriver
from selenium.webdriver.common.by import By

# 实例化浏览器对象
driver = webdriver.Chrome()
# 打开网址url
driver.get('https://www.baidu.com/')
# 需求
# 语法1:[属性^='开头的字母'] # 获取指定属性以指定字母开头的元素
driver.find_element(By.CSS_SELECTOR, "[class^='s_i']").send_keys('易烊千玺')

# 语法2:[属性$='结束的字母'] # 获取指定属性以指定字母结束的元素
driver.find_element(By.CSS_SELECTOR, "[class$='pt']").send_keys('易烊千玺')

# 语法3:[属性*='包含的字母'] # 获取指定属性包含指定字母的元素
driver.find_element(By.CSS_SELECTOR, "[autocomplete*='f']").send_keys('易烊千玺')

sleep(3)

# 关闭网页
driver.quit()

元素操作方法

方法:
1、.send_keys() # 输入方法
2、.click() # 点击方法
3、.clear() # 清空方法

注意:在输入方法之前一定要清空操作!!

浏览器操作方法

常用的浏览器操作系统API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 方法
1、driver.maximize_window() # 最大化浏览器
2、driver.set_window_size(w,h) # 设置浏览器大小 单位像素 【了解】
3、driver.set_window_position(x,y) # 设置浏览器位置 【了解】
4、driver.back() # 后退操作
5、driver.forward() # 前进操作
6、driver.refrensh() # 刷新操作
7、driver.close() # 关闭当前主窗口(主窗口:默认启动那个界面,就是主窗口)
8、driver.quit() # 关闭driver对象启动的全部页面
9、driver.title # 获取当前页面title信息
10、driver.current_url # 获取当前页面url信息

# 注意:driver.close() ,当前关闭的是主窗口,只有完成页面切换才可以关闭当前新的页面

提示:

1、driver.title 和 drivet.current_url是属性没有括号。应用场景:一般判断上不操作是否执行成功。

2、driver.maximize_window() 一般为前置代码放到获取driver地址后,进行浏览器窗口的最大化

3、driver.refresh() 向浏览器重新发出请求,刷新页面,在cookie 会用到

4、driver.close() 和 driver.quit() 的区别:

close():关闭当前主窗口

quit():关闭由driver对象启动的所有页面

如果只有一个窗口那么quit()和 close()没有区别。

获取元素信息操作

常用元素信息操作API

1
2
3
4
5
6
7
方法:
1、text 获取元素的文本; 如:driver.text
2、size 获取元素的大小: 如:driver.size
3、get_attribute 获取元素属性值;如:driver.get_attribute("id") ,传递的参数是元素的属性名
4、is_displayed 判断元素是否可见 如:element.is_displayed()
5、is_enabled 判断元素是否可用 如:element.is_enabled()
6、is_selected 判断元素是否被选中 如:element.is_selected()

鼠标操作 (需要实例化鼠标对象)

1、我们有了鼠标为什么还要使用鼠标操作??

为了满足丰富的html鼠标效果,必须使用对应的方法。

2、鼠标时间对应的方法在那个类中?

ActionChains类,实例化 鼠标对象

3、鼠标事件常用的操作 ☆

1
2
3
4
5
1、context_click(element) # 右击
2、double_click(element) #双击
3、double_and_drop(source, target) # 拖拽
4、move_to_element(element) # 悬停 【重点】
5、perform() # 执行以上事件的方法 【重点】

键盘操作(不需要实例化对象)☆

1、说明:键盘对应的方法在Keys类中

2、快捷键(这里只讲windows操作系统的快捷键):

CONTROL: Ctrl键

BACK_SPACE : 等价于 BACKSPACE (删除)

元素等待

1、为什么要设置元素等待

由于电脑配置或网络原因,在查找元素时,元素代码未在第一时间内被加载出来,而抛出未找到元素异常。

2、什么是元素等待

元素在第一次未找到时,元素等待设置的时长被激活,如果在设置的有效时长内找到元素,继续执行代码,如果超出设置的时长未找打元素,抛出未找到元素异常。

3、元素等待分类

隐式等待:针对全局元素生效

显示等待:稍微麻烦,暂不了解

隐式等待方法:

1
driver.implicitly_wait(30) # 一般情况下设置30秒

特色:

1
2
1. 针对所有元素生效。
2. 一般情况下为前置必写代码(1.获取浏览器驱动对象;2. 最大化浏览器;3. 设置隐式等待)

下拉框(需要实例化下拉框)

1、为什么单独使用下拉框?

1)、如果option选项没有value值的化,css定位或其他定位就不太方便。

2、使用Select类

1)、导包:from selenium.webdriver.support.select improt Select

2)、实例化下拉框:s = Select(element)

3)、调用方法:s.select_by_index()索引从0开始

3、Select类提供的方法

1)、select_by_index() # 通过索引定位

2)、select _by_value() # 通过value值

3)、select_by_visible_text() # 显示文本

八、弹出框

1、为什么要处理弹出框?

一旦出现弹出框,如果不进行处理,则后续操作不可实现

2、弹窗分类

系统弹窗:JS实现

自定义弹窗:前端代码封装

3、对话框的分类:

alert:警告框

confirm:确认框

prompt:提示框

4、如何处理

系统弹窗:上面的对话框处理方式都一样;

1
2
3
4
5
6
7
步骤:
1、需要切换到对话框
driver.switch_to.alert
2、处理对话框
alert.text # 获取文本
alert.accept() # 接受
alert.dismiss() # 拒接

自定义弹窗,由于可以鼠标右击检查选项获取元素信息,所以出现自行已弹窗的时候,直接定义目标元素,并进行移除操作即可。

九、滚动条

1、为什么要是用滚动条?

在一些特殊场景中,一些按钮是在页面最下角,需要使用滚动条拉到最底层。

2、操作步骤

Selenium框架中没有专门处理滚动条的方法,需要通过调用 Js 代码实现操作;

1)、第一步:设置操作滚动条操作语句:js_down=”window.scollTo(0,1000)”

0:为左边距—–》水平滚动条

1000: 为垂直滚动条

2)、第二步:调用执行js方法,将设置js语句传入方法中

方法:driver.execute_script(js_down)

十、切换frame表单 ☆

1、应用场景:

处于frame 中的元素,虽然可以获取元素信息,但是代码执行时无法定位元素,因此需要先切换到frame,再进行元素定位操作。

2、如何切换frame

方法:driver.switch_to.frame(“id/name/element”) 传入的是代表frame唯一的特征值

10.1 连续切换frame

说明:如果要连续切换frame必须要先回到默认页面,才能够实现下一个frame的切换

回到主页面的方法:driver.switch_to.default_content()

十一、多窗口的切换 ☆

1、为什么要切换多窗口

页面是存在多窗口的,但是selenium默认焦点只会在主窗口上的所有元素,不切换窗口,就不能操作除主窗口以外的窗口内元素。

2、如何切换

每个窗口都有唯一的一个句柄值,那么我们就可以通过句柄值来完成窗口的切换操作

方法:

1)、driver.current_window_handle (获取当前的句柄值)

2)、driver.window_handles ( 获取当前由driver启动所有窗口句柄)

3)、driver.switch_to.window(handle) —> 切换窗口

注意:这里的窗口切换也对应到了 close() 方法的作用,现在使用close()就是关闭当前页面,如果还想重新操作原始页面,务必完成窗口切换。

十二、截图操作

使用的方法:driver.get_screenshot_as_file(imgepath)

参数:imagepath:为图片要保存的目录地址及文件名称

注意:指定图片存放的路径,需要自己手动创建文件夹

十三、验证码

1、什么是验证码?

一种随机生成的信息(文字,数字,图片)

2、验证码的作用?

防止恶意请求

3、验证码的处理

这边讲的是cookie解决

4、使用cookie 登录

客户端登录账号后,将登录状态的想关 cookie 信息发给服务器保存,再发送去请求,携带cookie信息如果跟服务器保留的一致,则服务器认为客户端是登录状态。

5、这里实现自动登录的功能

1)、准备工作,在客户端登录的状态下,获取cookie字段

2、方法步骤:

1
2
3
4
5
1、整理cookie信息为字典数据,对应的是name和value,保存的一个变量中
2、调用方法添加cookie
driver.add_cookie(cookie变量)
# 3、刷新页面 -->发送cookie给服务器验证
driver.refresh()

最后:谢谢博主 http://t.csdnimg.cn/hdQpd