UI-自动化测试:Selenium+Python+Chrome

一、 环境配置

本文主要应用的环境配置:
Python v3.6 以上版本,python官网地址:https://www.python.org/
Selenium 最新的版本即可,安装方式:
(1) windows 系统,通过cmd 命令行安装:pip install selenium
(2) mac os 系统,通过终端,命令安装:pip install selenium
pycharm 最新社区版本即可,官网地址:https://pycharm-community-edition.en.softonic.com/
chrome 谷歌浏览器当前电脑配置的即可,若无用最新的版本即可
chromedriver 根据浏览器版本进行下载,地址:http://npm.taobao.org/mirrors/chromedriver/,如图:
在这里插入图片描述
下载好的chromedriver需要放到python根目录下,如图:
在这里插入图片描述

二、 selenium基础知识

  1. 启动浏览器
    (1)启动浏览器引入webdriver,selenium webdriiver(selenium 2.0) 是与selenium RC(selenium 1.0) 一样提供web自动化的各种语言调用接口。同时相比selenium RC ,webdriver的编程接口更加容易直观易懂,更加的简练,而驱动原理上面也出现了一些变化,webdriver驱动浏览器是通过浏览器的web driver进行驱动浏览器,而不是通过注入Javascript 进行驱动浏览器,驱动原理如图:
    在这里插入图片描述
    (2)浏览器启动的三种方式
    第一种启动方式程序,如代码:
# 引入selenium中的webdriver包
from selenium import webdriver

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

运行效果如图:
在这里插入图片描述

可以看到浏览器顶部有一行【chrome 正受到自动化测试软件的控制】悬浮栏,如图所示,这个悬浮栏大多数情况下,不会影响正常测试的进行,但是某些特殊情况下,会影响到元素定位的准确性,因此为了去掉这个悬浮栏,引入第二种打开浏览器的方式
在这里插入图片描述
第二种打开浏览器方式,通过控制浏览器内容的一些参数来设置浏览器启动的状况,如代码:

# 第二种浏览器启动方式
# 先创建一个浏览器参数对象
opts = webdriver.ChromeOptions()
# 最新的chrome浏览器去掉【chrome 正受自动化程序控制】固定参数
opts.add_experimental_option("excludeSwitches",["enable-automation"])
# 在使用与第一种启动浏览器相同的方法,真正启动浏览器,注意在方法中需要给参数chrome_options赋值,否则设置的浏览条件不生效
driver = webdriver.Chrome(chrome_options=opts)
driver.get('http://www.baidu.com')

在这里插入图片描述
上述两种打开浏览器的方式在有界面的系统上面运行还OK,但是若是到一些无界面的系统上面运行,就会报错,针对这种情况,便有了第三种启动浏览器的方式,无界面运行程序,如代码:

# 第三种浏览器启动方式
opts = webdriver.ChromeOptions()
# 添加启动浏览器时候的命--headless,该命令作用是控制有无界面显示
opts.add_argument('--headless')
# 注意:无界面浏览器是没有分辨率的,因此,一定要设置一下分辨率,否则会出现一些匪夷所思的问题
opts.add_argument('window-size=1920,1080')
driver = webdriver.Chrome(chrome_options=opts)
driver.get('http://www.baidu.com')
# 为了演示,增加了获取当前网页页签title的操作
print(driver.title)
# quit()方法为关闭浏览器
driver.quit()

运行效果如图:
在这里插入图片描述
(3)浏览器设置的常用参数

名称作用
–no-sandbox解决DevToolsActivePort文件不存在的报错
window-size=1920x3000设置浏览器分辨率
----disable-gpu谷歌文档提到需要加上这个属性来规避bug
–hide-scrollbars隐藏滚动条,应对一些特殊页面
blink-settings=imagesEnabled=false不加载图片,提升运行速度
–headless–headless无界面模式
excludeSwitches",[“enable-automation”]去掉【chrome 正受自动化程序控制】
  1. 页面元素定位基础
方法一方法二
find_element_by_idBy.ID
find_element_by_class_nameBy.CLASS_NAME
find_element_by_link_textBy.LINK_TEXT
find_element_by_partial_link_textBy.PARTIAL_LINK_TEXT
find_element_by_nameBy.NAME
find_element_by_tag_nameBy.TAG_NAME
find_element_by_xpathBy.XPATH
find_element_by_css_selectorBy.CSS_SELECTOR

以上为元素定位的8种基础定位方法,下面对其用法进行介绍,以百度网页定位搜索框为例:
在这里插入图片描述
由上图,可以看到百度搜索框对应的id =’kw’,class=’s_ipt’,name=’wd’,标签为input,因此若是想定位该输入框,可以通过第一组定位方式:
第一组:id、class_name、name、tag_name

opts = webdriver.ChromeOptions()
# 最新的chrome浏览器去掉【chrome 正受自动化程序控制】固定参数
opts.add_experimental_option("excludeSwitches",["enable-automation"])
# 在使用与第一种启动浏览器相同的方法,真正启动浏览器,注意在方法中需要给参数chrome_options赋值,否则设置的浏览条件不生效
driver = webdriver.Chrome(chrome_options=opts)
driver.get('http://www.baidu.com')
driver.find_element_by_id('kw').send_keys('通过ID定位输入框')

通过ID定位结果如下:
在这里插入图片描述
通过class_name\name定位,代码如下:

driver.find_element_by_class_name('s_ipt').send_keys('通过CLASS定位输入框')
driver.find_element_by_name('wd')..send_keys('通过NAME定位输入框')

结果同上图面ID定位的检索结果,就不在多说,第一组里唯一没有提到的是tag_name,这个用法局限性比较大, 需要网页标签具有独特性,这个时候才会应用该方法进行定位。
第二组:LINK_TEXT和PARTIAL_LINK_TEXT
从这两个方法名称不能看出来,定位的都是超文本连接,那么区别在哪里那,请看代码:

driver.find_element_by_link_text('视频').click()
driver.find_element_by_partial_link_text('视').click()

可以看出来,link_text 定位超文本链接是用的文本全称,而partial_link_text定位超文本连接用的是超文本链接文本的简称。
第三组:xpath、css_selector
这两个方法,是元素定位的万能定位方法,两个方法定位效果区别不大,不过从定位速度上面来看css_selector定位速度会高于xpath定位速度,这个会在后续ui自动化性能上面去讲这个事情,不在本文进行赘述,定位代码如下:

driver.find_element_by_xpath('//div[@id="kw"]').send_keys('通过XPATH定位输入框')
driver.find_element_by_css_selector('#kw').send_keys('通过CSS SELECTOR定位输入框')
  1. 页面元素定位高级
    (1)switch_to.window
    该方法主要应用于浏览器多窗口元素定位上,目的是让自动化程序可以知道要定位哪个出口下的程序
    不应用switch_to.window方法,看下方代码执行的效果:
opts = webdriver.ChromeOptions()
opts.add_experimental_option("excludeSwitches",["enable-automation"])
driver = webdriver.Chrome(chrome_options=opts)
driver.get('http://www.baidu.com')
driver.find_element_by_link_text('视频').click()
print(driver.current_url)

结果如图:
在这里插入图片描述
应用switch_to.window方法,看下发代码执行效果

opts = webdriver.ChromeOptions()
opts.add_experimental_option("excludeSwitches",["enable-automation"])
driver = webdriver.Chrome(chrome_options=opts)
driver.get('http://www.baidu.com')
driver.find_element_by_link_text('视频').click()
# 获取当前浏览器全部的handle
windowHandles = driver.window_handles
print('windowHandles:', windowHandles)
# 选择第二个窗口
driver.switch_to.window(windowHandles[1])
print(driver.current_url)
driver.quit()

结果如图:
在这里插入图片描述
可以看出,应用switch_to.window与不应用获取到页面的url是不一样的,其次,打印了window_handles所获取到的数据,可以看出,获取到的浏览器窗口其实是以LIST形式返回的,wow!!!LIST形式,嘿嘿嘿,岂不是我们可以做很多的事情了。
(2)switch_to.frame
在这里插入图片描述
这个网易邮箱登陆定位,不简单,有门道的,请看图:
在这里插入图片描述
本文就不在这里绕弯子了,直接说了,遇到iframe内嵌框架的这种,是无法直接定位到iframe下面的元素的,需要先定位iframe在定位iframe下的元素,如代码:

opts = webdriver.ChromeOptions()
opts.add_experimental_option("excludeSwitches",["enable-automation"])
driver = webdriver.Chrome(chrome_options=opts)

# 浏览器最大化
driver.maximize_window()
driver.get('https://mail.126.com/')
time.sleep(3)
frameElement = driver.find_element_by_xpath('//div[@id="loginDiv"]/iframe')
# 选择到iframe 标签下
driver.switch_to.frame(frame_reference=frameElement)
driver.find_element_by_name('email').send_keys('123')
  1. 常见事件处理
方法名作用
click()点击事件
send_key()输入事件
current_url当前页面url
title当前页面的title
text当前元素对应的文本
get_attribute(name=’’)获取当前元素下的属性
quit()退出浏览器
close()关闭当前窗口
  1. 鼠标事件与键盘事件

为了更好的模仿人对浏览器的操作行为,webdriver中同样提供了鼠标事件与键盘事件
(1)鼠标事件
使用鼠标事件需要引入链式操作模块

from selenium.webdriver.common.action_chains import ActionChains
ActionChains.move_to_element()  # 鼠标悬疑事件
ActionChains.move_by_offset()  # 鼠标移动到指定坐标
ActionChains.drag_and_drop_by_offset()  # 鼠标拖拽XXX到指定坐标
ActionChains.context_click() # 鼠标右键
ActionChains.double_click()  # 鼠标左键双击

以鼠标悬疑到百度搜索框照相机按钮上为例,如图:
在这里插入图片描述

上代码:

opts = webdriver.ChromeOptions()
opts.add_experimental_option('excludeSwitches', ['enable-automation'])
driver = webdriver.Chrome(options=opts)
driver.maximize_window()
driver.implicitly_wait(10)
driver.get('http://www.baidu.com')
time.sleep(1)
ele = driver.find_element(By.CLASS_NAME, 'soutu-btn')
time.sleep(1)
ActionChains(driver).move_to_element(ele).perform()
time.sleep(1)
eleText = driver.find_element_by_class_name('soutu-hover-tip')
print(eleText.text)
driver.quit()

代码执行效果应当如截图效果一致,不过不妨自己实验一下,不用鼠标悬浮获取【按图片搜索】文案
(2)键盘事件

from selenium.webdriver.common.keys import Keys

driver.find_element_by_name('name').send_keys(Keys.ENTER)  # 回车
driver.find_element_by_name('name').send_keys(Keys.CONTROL, 'a')  # ctrl+a
driver.find_element_by_name('name').send_keys(Keys.CONTROL, 'c')  # ctrl+c
driver.find_element_by_name('name').send_keys(Keys.CONTROL, 'v')  # ctrl+v
driver.find_element_by_name('name').send_keys(Keys.CONTROL, 'x')  # ctrl+x
driver.find_element_by_name('name').send_keys(Keys.BACKSPACE)  # 删除
driver.find_element_by_name('name').send_keys(Keys.SPACE)  # 空格

以百度输入框删除内部为例
上代码:

opts = webdriver.ChromeOptions()
opts.add_experimental_option("excludeSwitches",["enable-automation"])
driver = webdriver.Chrome(chrome_options=opts)
driver.maximize_window()
driver.get('http://www.baidu.com')
driver.find_element_by_id('kw').send_keys('123456')
time.sleep(3)
driver.find_element_by_id('kw').send_keys(Keys.BACKSPACE)
  1. 隐式等待、显式等待与强制介绍
    time.sleep(),是强制等待,需要等待足够的时间后,才会执行该行代码后面的程序
    implicitly_wait(),是隐式等待,隐式等待方法是一个全局的等待方法,设置的时间不宜过长也不宜过短,同时隐式等待与强制等待的区别在于,不需要等足够的时间才执行代码,而是在设置时间内,执行事件的语句发现需要的元素出现了,便会停止等待,执行后续的代码
    WebDriverWait(),是显示等待,显示等待与隐式等待的区别在于寻找元素的方式上,隐式等待是不断的刷新页面且当前页面的元素这次全部出现后,寻找对应的元素,不存在继续执行该过程,若是出现了,则停止,而显示等待同样会按照一个固定的频次刷新当前页面上的元素,但是无需本次全部的元素加载完成,便会寻找该对应的元素,从这个角度来看,显示等待寻找元素要快于隐式等待,所以在提高UI自动化测试性能的时候,要尽可能的应用显示等待,而显式等待的时间,不宜超过隐式等待的时间。

三、完整selenium+python+chrome例子

百度搜索126邮箱,并完成126邮箱登陆为例,具体效果请自行复制代码尝试

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.wait import WebDriverWait as wt
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By
import time

def driverMethod():

    opts = webdriver.ChromeOptions()
    opts.add_experimental_option('excludeSwitches', ['enable-automation'])
    driver = webdriver.Chrome(chrome_options=opts)
    # 隐式等待
    driver.implicitly_wait(20)
    # 浏览器最大化
    driver.maximize_window()
    return driver


driver = driverMethod()
driver.get('http://www.baidu.com')
driver.find_element_by_id('kw').send_keys('126邮箱', Keys.ENTER)
ele = wt(timeout=10, driver=driver).until(ec.visibility_of_element_located((By.XPATH, "//div[@id='1']/h3/a")))
ele.click()
windows = driver.window_handles
driver.switch_to.window(windows[1])
eleframe = driver.find_element_by_xpath('//div[@id="loginDiv"]/iframe')
driver.switch_to.frame(frame_reference=eleframe)
driver.find_element_by_name('email').send_keys('123456')
driver.find_element_by_name('password').send_keys('123456')
driver.find_element_by_id('dologin').click()
time.sleep(3)
driver.quit()

备注:下一篇原创准备介绍unittest框架在UI自动化中的应用以及用例依赖的设计方法,感兴趣的朋友可以关注一下我,避免错过…

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值