selenium之WebDriver API

自动化只要掌握四步操作:获取元素,操作元素,获取返回结果,断言(返回结果与期望结果是否一致),最后自动出测试报告,元素定位在这四个环节中是至关重要的,如果说按学习精力分配的话,元素定位占70%;操作元素10%,获取返回结果10%;断言10%。如果一个页面上的元素不能被定位到,那后面的操作就无法继续了。而WebDriver 属于Selenium体系设计出来操作浏览器的一套API,它支持多种语言,Selenium WebDriver只是python的一个第三方框架,也就是说是一个实现web自动化的第三方框架。

一、从如何定位元素开始

1、元素定位:find_element_by_id()

from selenium import webdriver
d = webdriver.Chrome()
d.get('http://www.baidu.com')
d.maximize_window()
"""
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""
# 通过id定位百度搜索框并输入python
d.find_element_by_id('kw').send_keys('python')

2、元素定位:find_element_by_name()

     说明:如果这里运行后报错,说明这个搜索框的name属性不是唯一的,无法通过name属性直接定位到输入框

from selenium import webdriver
d = webdriver.Chrome()
d.get('http://www.baidu.com')
d.maximize_window()
"""
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""
# 通过name定位百度搜索框并输入python
d.find_element_by_name('wd').send_keys('python')

3、元素定位:find_element_by_class_name()

from selenium import webdriver
d = webdriver.Chrome()
d.get('http://www.baidu.com')
d.maximize_window()
"""
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""
# 通过class_name定位百度搜索框并输入python
d.find_element_by_class_name('s_ipt').send_keys('python')

4、元素定位:find_element_by_tag_name()

  1.从上面定位到的元素属性中,可以看到每个元素都有tag(标签)属性,如搜索框的标签属性,就是最前面的input

  2.很明显,在一个页面中,相同的标签有很多,所以一般不用标签来定位。仅供参考和理解,运行肯定报错

from selenium import webdriver
d = webdriver.Chrome()
d.get('http://www.baidu.com')
d.maximize_window()
"""
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""
# 通过tag_name定位百度搜索框并输入python
d.find_element_by_tag_name('input').send_keys('python')

5、元素定位:find_element_by_link_text()

from selenium import webdriver
d = webdriver.Chrome()
d.get('http://www.baidu.com')
d.maximize_window()
"""
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""
# 通过link_text定位百度搜索框并输入python
d.find_element_by_link_text('登录').click()

6、元素定位:find_element_by_partial_link_text()

 1.有时候一个超链接它的字符串可能比较长,如果输入全称的话,会显示很长,这时候可以用一模糊匹配方式,截取其中一部分字符串就可以了

 2.如“hao123”,只需输入“ao123”也可以定位到

from selenium import webdriver
d = webdriver.Chrome()
d.get('http://www.baidu.com')
d.maximize_window()
"""
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""
# 通过partial_link_text定位百度搜索框并输入python
d.find_element_by_partial_link_text('ao123').click()

7、元素定位:find_element_by_xpath()

    以上定位方式都是通过元素的某个属性来定位的,如果一个元素它既没有id、name、class属性也不是超链接,这么办呢?或者说它的属性很多重复的。这个时候就可以用       xpath解决

from selenium import webdriver
d = webdriver.Chrome()
d.get('http://www.baidu.com')
d.maximize_window()
"""
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""
d.find_element_by_xpath('//*[@id="kw"]').send_keys('selenium')

8、元素定位:find_element_by_css_selector()

总结:

selenium的webdriver提供了八种基本的元素定位方法,前面六种是通过元素的属性来直接定位的,后面的xpath和css定位更加灵活,需要重点掌握其中一个。

二、WebDriver API

1、控制浏览器的简单方法

 

---恢复内容结束---

自动化只要掌握四步操作:获取元素,操作元素,获取返回结果,断言(返回结果与期望结果是否一致),最后自动出测试报告,元素定位在这四个环节中是至关重要的,如果说按学习精力分配的话,元素定位占70%;操作元素10%,获取返回结果10%;断言10%。如果一个页面上的元素不能被定位到,那后面的操作就无法继续了。而WebDriver 属于Selenium体系设计出来操作浏览器的一套API,它支持多种语言,Selenium WebDriver只是python的一个第三方框架,也就是说是一个实现web自动化的第三方框架。

一、从如何定位元素开始

1、元素定位:find_element_by_id()

from selenium import webdriver
d = webdriver.Chrome()
d.get('http://www.baidu.com')
d.maximize_window()
"""
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""
# 通过id定位百度搜索框并输入python
d.find_element_by_id('kw').send_keys('python')

2、元素定位:find_element_by_name()

     说明:如果这里运行后报错,说明这个搜索框的name属性不是唯一的,无法通过name属性直接定位到输入框

from selenium import webdriver
d = webdriver.Chrome()
d.get('http://www.baidu.com')
d.maximize_window()
"""
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""
# 通过name定位百度搜索框并输入python
d.find_element_by_name('wd').send_keys('python')

3、元素定位:find_element_by_class_name()

from selenium import webdriver
d = webdriver.Chrome()
d.get('http://www.baidu.com')
d.maximize_window()
"""
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""
# 通过class_name定位百度搜索框并输入python
d.find_element_by_class_name('s_ipt').send_keys('python')

4、元素定位:find_element_by_tag_name()

  1.从上面定位到的元素属性中,可以看到每个元素都有tag(标签)属性,如搜索框的标签属性,就是最前面的input

  2.很明显,在一个页面中,相同的标签有很多,所以一般不用标签来定位。仅供参考和理解,运行肯定报错

from selenium import webdriver
d = webdriver.Chrome()
d.get('http://www.baidu.com')
d.maximize_window()
"""
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""
# 通过tag_name定位百度搜索框并输入python
d.find_element_by_tag_name('input').send_keys('python')

5、元素定位:find_element_by_link_text()

from selenium import webdriver
d = webdriver.Chrome()
d.get('http://www.baidu.com')
d.maximize_window()
"""
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""
# 通过link_text定位百度搜索框并输入python
d.find_element_by_link_text('登录').click()

6、元素定位:find_element_by_partial_link_text()

 1.有时候一个超链接它的字符串可能比较长,如果输入全称的话,会显示很长,这时候可以用一模糊匹配方式,截取其中一部分字符串就可以了

 2.如“hao123”,只需输入“ao123”也可以定位到

from selenium import webdriver
d = webdriver.Chrome()
d.get('http://www.baidu.com')
d.maximize_window()
"""
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""
# 通过partial_link_text定位百度搜索框并输入python
d.find_element_by_partial_link_text('ao123').click()

7、元素定位:find_element_by_xpath()

    以上定位方式都是通过元素的某个属性来定位的,如果一个元素它既没有id、name、class属性也不是超链接,这么办呢?或者说它的属性很多重复的。这个时候就可以用       xpath解决

from selenium import webdriver
d = webdriver.Chrome()
d.get('http://www.baidu.com')
d.maximize_window()
"""
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""
d.find_element_by_xpath('//*[@id="kw"]').send_keys('selenium')

8、元素定位:find_element_by_css_selector()

总结:

selenium的webdriver提供了八种基本的元素定位方法,前面六种是通过元素的属性来直接定位的,后面的xpath和css定位更加灵活,需要重点掌握其中一个。

二、WebDriver API

1、鼠标常用方法

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
d = webdriver.Chrome()
d.get('http://www.baidu.com')
el = d.find_element_by_link_text('设置')
"""
ACtionChains()提供的方法:
perform() 执行所有的ActionChains中存储的行为
context_click() 右击
double_click() 双击
drag_and_drop(el,el2) 拖动,从el拖动到el2
move_to_element() 鼠标悬停
"""
# el.click()
# 鼠标悬停ActionChains(d).move_to_element(el).perform()

2、键盘常用属性方法

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
"""
键盘操作被封装到类keys中
"""
d = webdriver.Chrome()
d.get('http://www.baidu.com')
d.find_element_by_id('kw').send_keys('selenuimm')
time.sleep(2)

# 删除多输入的一个m
d.find_element_by_id('kw').send_keys(Keys.BACK_SPACE)
time.sleep(2)

# 输入空格键+python
d.find_element_by_id('kw').send_keys(Keys.BACK_SPACE)
d.find_element_by_id('kw').send_keys('python')
time.sleep(2)

# ctrl+a 全选输入框内容
d.find_element_by_id('kw').send_keys(Keys.CONTROL,'a')
time.sleep(2)

# ctrl+x 剪切输入框内容
d.find_element_by_id('kw').send_keys(Keys.CONTROL,'x')
time.sleep(2)

# ctrl+v 粘贴输入框内容
d.find_element_by_id('kw').send_keys(Keys.CONTROL,'v')
time.sleep(2)

# ctrl+v 粘贴输入框内容
d.find_element_by_id('su').send_keys(Keys.ENTER)
time.sleep(2)

3、webelement基本方法

from selenium import webdriver
"""
size 返回元素的尺寸
text 获取元素的文本
get_attribute(name) 获得属性值
is_displayed() 设置该元素是否是用户可见
"""
# 获得输入框的尺寸
size = d.find_element_by_id('kw').size
print("size:",size)

# 返回百度页面底部备案信息
text = d.find_element_by_id('cp').text
print("text:",text)

# 返回元素的属性值,可以是id、name、type、或其他属性
attr = d.find_element_by_id('kw').get_attribute('type')
print('attr:',attr)
# 返回元素的结果是否可见,返回结果为True或者False
res = d.find_element_by_id('kw').is_displayed()
print("res:",res)

4、获取验证信息

from selenium import webdriver
import time

d = webdriver.Chrome()
d.get('http://www.baidu.com')
"""
写自动化测试用例的时候,用来做断言(验证)
三类验证信息
url
title
text
"""
# 搜索之前
title = d.title
print("title:",title)
url = d.current_url
print('url:',url)

d.find_element_by_id('kw').send_keys('selenium')
d.find_element_by_id('su').click()
time.sleep(2)

# 搜索之后
title = d.title
print("title:",title)
url = d.current_url
print('url:',url)

# 断言
if title == 'selenium_百度搜索':
    print('test case pass')
else:
    print('test case error')

5、设置元素等待

 1.显示等待

import time
from selenium.webdriver.common.by import By # 元素定位
from selenium.webdriver.support.ui import WebDriverWait # 等待
from selenium.webdriver.support import expected_conditions as EC # 条件判断
from selenium import webdriver
"""
显式等待:针对某个元素等待
隐式等待:针对当前页面中的所有元素等待
"""
# 方式一
d = webdriver.Chrome()
d.get('http://www.baidu.com')
# 5是5秒钟,0.5是检测的频率
ele = WebDriverWait(d, 5, 0.5).until(
    EC.presence_of_element_located((By.ID,'kw'))
    )
ele.send_keys('selenium')
d.quit()
from selenium import webdriver
"""
显式等待:针对某个元素等待
隐式等待:针对当前页面中的所有元素等待
"""
# 方式二
d = webdriver.Chrome()
d.get('http://www.baidu.com')
print(time.ctime())

for i in range(10):
    try:
        global el
        el = d.find_element_by_id('kw')
        if el.is_displayed():
            break
    except:
        pass
    time.sleep(1)
else:
    print('time out')
el.send_keys('python')
# d.close()
print(time.ctime())

 2.隐式等待

from selenium.webdriver.support.ui import WebDriverWait # 等待
from selenium import webdriver
# 隐式等待
d = webdriver.Chrome()
# 默认10秒的等待
d.implicitly_wait(10)
d.get('http://www.baidu.com')
input_ = d.find_element_by_id('kw')
input_.send_keys('selenium')

6、定位一组元素

from selenium import webdriver

d = webdriver.Chrome()
d.get('http://www.baidu.com')
"""
定位一组元素:在之前8中定位之前element加s
d.find_elements_by_class_name()
d.find_elements_by_name()
d.find_elements_by_id()
d.find_elements_by_link_text()
d.find_elements_by_xpath()
d.find_elements_by_tag_name()
d.find_elements_by_css_selector()
d.find_elements_by_partial_link_text()
"""

 7、多表单切换

 在web 应用中经常会出现frame 嵌套的应用,假设页面上有A、B 两个frame,其中B 在A 内,那么定位B 中的内容则需要先到A,然后再到B。

  switch_to_frame 方法可以把当前定位的主体切换了frame 里。怎么理解这句话呢?我们可以从frame
  的实质去理解。frame 中实际上是嵌入了另一个页面,而webdriver 每次只能在一个页面识别,因此才需要
  用switch_to.frame 方法去获取frame 中嵌入的页面,对那个页面里的元素进行定位。

   switch_to_frame 的参数问题。官方说name 是可以的,但是经过实验发现id 也可以。所以只要frame
   中id 和name,那么处理起来是比较容易的。如果frame 没有这两个属性的话,你可以直接手动添加。

   注:switch_to_frame() 方法在使用的时候被横线划掉,说明不建议使用

   selenium 提供了 switch_to.frame() 方法来切 frame / iframe

   以163邮箱登录为例:

from selenium import webdriver
import time
d = webdriver.Chrome()
d.get('https://mail.163.com/')

d.implicitly_wait(10)
ele = d.find_element_by_id("x-URS-iframe") # 先定位到这个iframe页面
d.switch_to.frame(ele) # 然后切换到这个iframe页面
d.find_element_by_name('email').clear()
d.find_element_by_name('email').send_keys('xxxxxx')

d.find_element_by_name('password').clear()
d.find_element_by_name('password').send_keys('xxxxxxx')

d.find_element_by_id('dologin').click()
time.sleep(3)
d.close()

8、多窗口的切换

from selenium import webdriver
d = webdriver.Chrome()

d.implicitly_wait(10)
d.get('http://www.baidu.com')

# 获得百度搜索窗口句柄
search_window = d.current_window_handle
print(search_window)

d.find_element_by_link_text('登录').click()
d.find_element_by_class_name('tang-pass-footerBar')
d.find_element_by_link_text('立即注册').click()

# 获得当前所有打开的窗口句柄
all_handles = d.window_handles

# 进入注册窗口
for handle in all_handles:
    if handle != search_window:
        d.switch_to.window(handle)
        c_handle = d.current_window_handle # 当前页句柄
        print('now register window!')

        d.find_element_by_id('TANGRAM__PSP_3__userName').send_keys('xxxxxx')
        d.find_element_by_id('TANGRAM__PSP_3__phone').send_keys('1233323423')
View Code

 9、警告窗处理

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
"""
text:返回 alert/confirm/prompt中的文字信息
accept():接受现有警告框 
dismiss():解散现有警告框
send_keys(KeysToSend):发送文本至警告框
KeysToSend:将文本发送至警告框
"""
driver = webdriver.Chrome()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
# 鼠标悬停到设置
obj = driver.find_element_by_link_text("设置")
ActionChains(driver).move_to_element(obj).perform()
# 点击搜索设置
driver.find_element_by_link_text("搜索设置").click()
# 点击保存设置
driver.find_element_by_class_name("prefpanelgo").click()
time.sleep(3)
# 接受警告框
res = driver.switch_to.alert().text
print(res)
View Code

10、上传文件

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('http://sahitest.com/demo/php/fileUpload.htm')
upload = driver.find_element_by_id('file')
upload.send_keys('d:\\baidu.py')  # send_keys
print(upload.get_attribute('value') ) # check value

driver.quit()
View Code

11、控制浏览器滚动条

from selenium import webdriver
import time
#访问百度
driver=webdriver.Chrome()
driver.get("http://www.baidu.com")
#搜索
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(3)
#将页面滚动条拖到底部
js="var q=document.documentElement.scrollTop=10000"
driver.execute_script(js)
time.sleep(3)
#将滚动条移动到页面的顶部
js_="var q=document.documentElement.scrollTop=0"
driver.execute_script(js_)
time.sleep(3)
driver.quit()
View Code

12、验证码

对于web 应用来说,大部分的系统在用户登录时都要求用户输入验证码,验证码的类型的很多,有字
母数字的,有汉字的,甚至还要用户输入一条算术题的答案的,对于系统来说使用验证码可以有效果的防
止采用机器猜测方法对口令的刺探,在一定程度上增加了安全性。但对于测试人员来说,不管是进行性能
测试还是自动化测试都是一个棘手的问题

去掉验证码
这是最简单的方法,对于开发人员来说,只是把验证码的相关代码注释掉即可,如果是在测试环境,
这样做可省去了测试人员不少麻烦,如果自动化脚本是要在正式环境跑,这样就给系统带来了一定的风险。

设置万能码
去掉验证码的主要是安全问题,为了应对在线系统的安全性威胁,可以在修改程序时不取消验证码,
而是程序中留一个“后门”---设置一个“万能验证码”,只要用户输入这个“万能验证码”,程序就认为验
证通过,否则按照原先的验证方式进行验证。

验证码识别技术

例如可以通过Python-tesseract 来识别图片验证码,Python-tesseract 是光学字符识别Tesseract OCR 引

擎的Python 封装类。能够读取任何常规的图片文件(JPG, GIF ,PNG , TIFF 等)。不过,目前市面上的验证码
形式繁多,目前任何一种验证码识别技术,识别率都不是100% 。

记录cookie

通过向浏览器中添加cookie 可以绕过登录的验证码,这是比较有意思的一种解决方案。我们可以在
用户登录之前,通过add_cookie()方法将用户名密码写入浏览器cookie ,再次访问系统登录链接将自
动登录

使用cookie 进行登录最大的难点是如何获得用户名密码的name ,如果找到不到name 的名字,就没
办法向value 中输用户名、密码信息。

13、webdriver 原理

1. WebDriver 启动目标浏览器,并绑定到指定端口。该启动的浏览器实例,做为web driver 的remote
server。

2. Client 端通过CommandExcuter 发送HTTPRequest 给remote server 的侦听端口(通信协议: the
webriver wire protocol)

3. Remote server 需要依赖原生的浏览器组件(如:IEDriverServer.exe、chromedriver.exe),来转
化转化浏览器的native 调用。

猜你喜欢

转载自www.cnblogs.com/crazyforever/p/9186141.html