Selenium基础

Selenium(1)环境搭建

一、selenium介绍

selenium主要用于web应用程序的自动化测试,还支持所有基于web的管理任务自动化。

selenium经历了2个版本,selenium1.0和selenium2.0;selenium不是一个单独的工具,而是由一些插件、类库构成,每个组成部分都有其特点和应用场景。

selenium2.0由以下组件构成:

selenium2.0 = selenium1.0 + Webdriver

Webdirver:通过原生浏览器支持或扩展来直接控制浏览器,针对各个浏览器开发,与浏览器紧密集成,支持创建更高级的测试,其还可以利用操作系统级的调用,模拟用户输入;

selenium IDE:嵌入到Firefox浏览器中的一个插件,实现简单的浏览器操作录制与回放功能,主要用于快速创建BUG及重现脚本,可转化为多种语言;

selenium Gird:测试辅助工具,利用现有的计算机基础设施,实现多台计算上和异构环境中运行测试用例;

selenium RC:selenium的核心组件,支持多种不同语言编写自动化测试脚本,通过其服务器作为代理服务器去访问应用,达到测试的目的;

             Client Libraries:Client Libraries库主要用于编写测试脚本,用来控制Selenium Server的库;

             Selenium Server:负责控制浏览器行为;

                              Selenium Core(一个JavaScript函数集合):被嵌入到浏览器中,通过它实现用程序对浏览器进行操作;

                              Launcher:用于启动浏览器,把Core加载到浏览器页面当中,并把浏览器代理设置为Selenium Server的HTTP Proxy

 

二、环境搭建

1、安装python

登录Python官网,找到download,选择与自身平台(Windows/Linux)相符的版本下载(建议3.5+),然后安装即可;

注意:安装时选择安装界面的“Add Python 3.x to PATH”进行勾选,避免再次配置环境变量;

安装完成后通过Windows命令提示符CMD输入“python”,查看是否安装成功,如下图所示:

如上图所示,则证明安装成功;

 

2、安装setuptools与pip

setuptools是PEAK(Python enterprise Application Kit)的一个副项目,是python的distutilsde的增强工具,可以更方便创建和发布python包,特别是对其他包有依赖的情况;

pip是一个安装和管理python包的工具,通过pip来安装python包将变得很简单,省去了繁琐的过程,pip的安装依赖于setuptools,安装pip之前需要先安装setuptools;

注意:python目前不支持setuptools,因此需要使用distribute;

setuptools与pip的下载地址如下:

setuptools:https://pypi.python.org/pypi/setuptools

pip:https://pypi.org/project/pip/

注意: 最新版的python安装包中已经集成了pip,可以在安装目录下的script路径下查看是否有pip.exe或pip3.exe文件,如果有,则cmd命令行中输入pip进行验证;

如上图所示,则证明已经安装pip;

 

3、安装selenium

完成上面2个步骤之后,可以通过cmd命令直接安装selenium包,如下图所示:

注意:安装时如果只输入包名,则默认安装当前库中的最新版本,如果想安装自己需要的版本,则需要在包名后面加上版本号,比如:

pip install selenium==2.48.0

 

4、下载浏览器驱动

前面说过,selenium支持多种浏览器,所以只需要下载对应的浏览器驱动,将解压得到的exe文件放到python的安装目录下即可;

各个浏览器驱动下载地址:https://www.seleniumhq.org/download/

 

5、调试

打开一款python编译器,输入下面的代码,运行,查看是否成功调用浏览器运行,如果运行成功,则说明已成功搭建好自动化开发环境;

 

Selenium(2)WebDriver简介及元素定位

一、WebDriver原理

1、关于WebDriver

设计模式:按照Server-Client的经典设计模式设计;

Server端:即Remote Server(远程服务器),可以是任意的浏览器,当脚本启动浏览器时,该浏览器就是Remote Server,它的职责是等待Client发送请求并做出响应;

Client端:简单来说就是我们的测试代码,测试代码中的一些行为是以HTTP请求的方式发送给被测试浏览器——Remote Server,Remote Server接受请求,执行相应操作,

         并在Response中返回执行状态、返回值等信息;

 

2、WebDriver工作流程

①WebDriver启动目标浏览器,并绑定至指定端口,启动的浏览器实例将作为WebDriver的Remote Server;

②Client端通过CommandExcuter发送HTTPRequest给Remote Server的侦听端口(通信协议:the webdriver wire protocol);

③Remote Server需要依赖原生的浏览器组件(比如:chromedriver.exe)来转化浏览器的native调用;

 

3、WebDriver.log

python提供了logging模块给运行中的应用,提供了一个标准的信息输出接口。它提供了basicConfig方法用于基本信息的定义,开启debug模块,

就可以捕捉到Client端向Server端发送的请求,例子如下:

1 # coding=utf-8
 2 # 导入logging模块,捕捉Client发送的请求
 3 from selenium import webdriver
 4 import logging
 5 from selenium import webdriver
 6 from selenium.webdriver.support.select import Select # select类
 7 from selenium.webdriver.common.by import By #By类:定位元素
 8 
 9 logging.basicConfig(level=logging.DEBUG)
10 driver = webdriver.Chrome("F:\安装工具\python\chromedriver.exe")
11 driver.get("www.baidu.com")
12 
13 driver.find_element_by_id("kw").send_keys("selenium")
14 driver.find_element_by_id("su").click()
15 driver.quit() 

二、WebDriver定位方法

WebDriver是基于selenium设计的操作浏览器的一套API,针对多种编程语言都实现了这套API,站在python角度来说,WebDriver是python的一个用于实现Web自动化的第三方库。

1、WebDriver定位方法

WebDriver定位方法提供了八种元素定位方法,所对应的方法、特性分别是:

 

2、XPath和CSS的类似功能对比

 

3、用By定位元素

针对前面介绍的8种定位方法,WebDriver还提供另一种方法,即:统一调用find_element()方法,通过By来声明定位方法,并且传入对应定位方法的定位参数,例子如下:

find.element()方法只用于定位元素,它需要两个参数,第一个参数是定位的类型,由By提供,第二个参数是定位的具体方式,在使用By之前需要将By类导入;

# 导入By类的包
from selenium.webdriver.common.by import By
find.element(by.id,"kw")
find.element(by.name,"wd")
find.element(by.class_name,"s_ipt")
find.element(by.tag_name,"input")
find.element(by.link_text,"新闻")
find.element(by.partial_link_text,"")
find.element(by.xpath,"//*[@class='bg s_btn'")
find.element(by.css_selector,"span.bg s_btn_wr>input#su")

4、定位一组元素

上面提到的8种定位方法,都是针对单个元素定位的,webdriver还提供了与之对应的8种用于定位一组元素的方法。其一般应用于以下场景:

①批量操作元素,例如勾选页面上所有的复选框;

②先获取一组元素,再从这组元素中过滤出需要操作的元素;

定位一组元素的方法与定位单个元素的用法相似,唯一的区别是在element后面多一个s表示复数,具体如下:

# webdriver提供的定位一组元素方法
id                    find_elements_by_id()
Name                  find_elements_by_name()
class_name            find_elements_by_class_name()
tag Name              find_elements_by_tag_name()          
link text             find_elements_by_link_text()
partial link text     find_elements_by_partial_link_text()
xpath                 find_elements_by_xpath()
css selector          find_elements_by_css_selector()

获取一组元素中某个元素的几个方法:

len():用来计算元素的个数,通过print()打印出计算的结果;

pos()或pop(-1):默认获取一组元素的最后一个元素,并返回该元素的值;

pop(0):默认获取一组元素的第一个元素,并返回该元素的值;

pop(1):默认获取一组元素的第二个元素,并返回该元素的值;

......

 

三、WebElement接口常用方法

通常需要与页面交互的方法都由WebElement接口提供,包括上面提到的8种定位方法,下面介绍常用的几种方法:

submit():用于提交表单,例如搜索框输入关键字之后的“回车”操作,例如:

# 提交表单
from select import webdriver
driver = webdriver.Chrome("安装工具\python\chromedriver.exe")
driver.get("http://www.baidu.com")
driver.find_element_by_id("kw").send_keys("imyalost")
# 提交输入框中的内容
driver.find_element_by_id("imyalost").submit()
driver.quit()

注意:有时候submit()方法和click()方法可以互用,但submit()的应用范围不及click()广泛;

clear():清除文本;

send_keys(*value):模拟按键输入;

click():单击元素;

size:返回元素的尺寸;

text:获取元素的文本;

get.attribute(name):获得属性值;

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

# webelement接口常用方法
from selenium import webdriver
driver = webdriver.Chrome("安装工具\python\chromedriver.exe")
driver.get("http://www.baidu.com")
# 获得输入尺寸
size = driver.find_element_by_id("kw").size
print("size")
# 返回百度页面底部备案信息
text = driver.find_element_by_id("cp").text
print("text")
# 返回元素的属性值,可以是id、name、type或其他属性
attribute = driver.find_element_by_id("kw").get_attribute("type")
print("attribute")
# 返回元素结果是否可见,返回结果为True或Flase
result = driver.find_element_by_id("kw").is_displayed()
print("result")

 

Selenium(3)浏览器及鼠标,键盘事件

一、控制浏览器

webdriver主要提供操作页面上各种元素的方法,但它也提供操作浏览器的一些方法,例如控制浏览器大小、前进和后退等。

1、控制浏览器窗口大小

# 控制浏览器大小
from selenium import webdriver
driver = webdriver.Chrome("安装工具\python\chromedriver.exe")
driver.get("http://www.baidu.com")
# 参数数字为像素点
print("设置浏览器宽480、高800显示")
driver.set_window_size(480,800)

2、全屏显示

webdriver提供了maximize_window()方法使打开的浏览器全屏显示,其用法与set_window_size()相同。

3、控制浏览器前进、后退

现在的浏览器在浏览网页时都提供了前进和后退功能,webdriver也提供了对应的forward()和back()方法,来模拟前进和后退按钮:

# 控制浏览器前进、后退
from selenium import webdriver
driver = webdriver.Chrome("安装工具\python\chromedriver.exe")
# 访问百度首页
first_url='http://www.baidu.com''
print("now access %s "%(first_url))
driver.get(first_url)
# 访问新闻页面
second_url='http://www.news.baidu.com'
print("now access % s "%(second_url)")
driver.get("second_url")
# 后退到百度首页
print("back to %s "%(first_url)")
driver.back()
# 前进到新闻页
print("forward to %s "%(second_url)")
driver.forward()

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

now access http://www.baidu.com

now access http://news.baidu.com

back to http://www.baidu.com

froward to http://news.baidu.com

4、模拟浏览器前刷新

一般我们刷新页面都是通过F5或者页面上的刷新按钮,webdriver也提供了刷新方法refresh(),用来模拟页面刷新:

......

# 刷新当前页面

driver.refresh()

......

 

二、鼠标事件

在webelement接口提供的方法中,可以通过click()来模拟鼠标单击操作,但实际上鼠标交互方式很多,例如:右击、悬停、鼠标拖动等功能;

webdriver提供了ActionChains类,封装了鼠标操作的常用方法:

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

context_click():鼠标右击

double_click():鼠标双击

drag_and_drop():鼠标拖动

move_to_element():鼠标悬停

1、鼠标右击操作

# 鼠标右击操作
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome("安装工具\python\chromedriver.exe")
driver.get("http://www.baidu.com")
# 定位到要右击的元素
right_click = driver.find_element_by_id("KW")
# 对定位到的元素执行鼠标右击操作
ActionChains(driver).context_click(right_click).perform()
...

2、鼠标悬停

鼠标悬停弹出下拉菜单也是一个十分常见的功能设计,move_to_element()方法可以模拟鼠标悬停动作,其用法与context_click()相同;

1 # 鼠标悬停
2 ...
3 above = driver.find_element_by_id("id")
4 ActionChains(driver).move_to_element(above).perform()
5 ... 

3、鼠标双击操作

double_click()方法用于模拟鼠标双击操作;

1 # 鼠标双击操作
2 ...
3 double_click = driver.find_element_by_id("id")
4 ActionChains(driver).double_click(double_click).perform()
5 ...

4、鼠标拖放操作

drag_and_drop(source,target)在源元素上按住鼠标左键,然后移动到目标元素上释放;

source:鼠标拖动的源元素

target:鼠标释放的目标元素

# 定位元素的位置
...
element = driver.find_element_by_id("id")
# 定位元素要移动到的目标位置
target = driver.find_element_by_id("xx")
# 执行元素的拖放操作
ActionChains(driver).drag_and_drop(element,target).perform()
...

三、键盘事件

Keys()类提供了键盘上几乎所有的按键方法,send_keys()不见可以模拟键盘输入,还可以用来输入键盘上的按键,甚至是组合键,例子如下:

# 模拟键盘事件
from selenium import webdriver
# 引入keys模块
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome("安装工具\python\chromedriver.exe")
driver.get("http://www.baidu.com")
# 输入框输入内容
driver.find_element_by_id("kw").send_keys("selenium")
# 输入“教程”
driver.find_element_by_id("kw").send_keys("教程")
# 删除“教程”
driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)
...

以下为常用的键盘操作:

# 常用的键盘操作
send_keys(Keys.BACK_SPACE)
send_keys(Keys.SPACE)
send_keys(Keys.TAB)
send_keys(Keys.ESCAPE)
send_keys(Keys.ENTER)
send_keys(Keys.CONTROL,'a')
send_keys(Keys.CONTROL,'c')
send_keys(Keys.CONTROL,'v')
send_keys(Keys.CONTROL,'x')
send_keys(Keys.F1)
...
send_keys(Keys.F12)

以上为webdriver的控制浏览器操作以及模拟键盘、鼠标操作的常用方法,当然具体在实际使用过程中,还需要结合实际的业务场景,灵活运用

 

Selenium(4)断言

在编写自动化测试脚本时,为了使“机器”去自动辨识test case的执行结果是True还是False,一般都需要在用例执行过程中获取一些信息,来判断用例的执行时成功还是失败。

判断成功失败与否,就涉及到断言。webdriver的断言使用有三种模式:操作(action)、辅助(accessors)、断言(assertion)。

 

1、操作(action)

模拟用户与Web应用程序的交互,一般用于操作应用程序的状态;

如点击链接,选择选项的方式进行工作;如果一个动作执行失败,或是有错误,当前的测试将会停止执行。

常见命令如下:

open(打开页面)

click(点击)

clickAndWait(点击并等待)

type(文本类型)

select(选择下拉菜单)

selectWindow(选择弹出窗口)

pause(等待指定时间,以毫秒为单位,即要睡眠的时间)

setSpeed(设定执行速度。以毫秒延迟间隔长度。默认没有延迟,即为0)

setTimeout(指定等待动作完成的等待时间。默认为30秒,需要等待的动作包括了OPEN 和WAITFOR)

goBack(模拟用户点击其浏览器上的“back”按钮)

close(模拟用户点击弹出窗体或表单标题栏上的”关闭”按钮)

 

2、辅助(accessors)

辅助工具,用于检查应用程序的状态并将结果存储到变量中;

如:storeElementPresent(locator,variableName)

其中参数locator表示元素定位器,variableName用于存储结果的变量名;

即将locator定位到的状态存储到variableName变量中,如果该元素出现返回true,否则返回false,可同断言一同使用。

 

3、断言(assertion)

验证应用程序的状态是否同所期望的一致。

常见的断言包括:验证页面内容,如标题是否为X或当前位置是否正确,或是验证该复选框是否被勾选。

常用断言如下:

assertLocation(判断当前是在正确的页面)

assertTitle(检查当前页面的title是否正确)

assertValue(检查input的值, checkbox或radio,有值为”on”无为”off”)

assertSelected(检查select的下拉菜单中选中是否正确)

assertSelectedOptions(检查下拉菜单中的选项的是否正确)

assertText(检查指定元素的文本)

assertTextPresent(检查在当前给用户显示的页面上是否有出现指定的文本)

assertTextNotPresent(检查在当前给用户显示的页面上是否没有出现指定的文本)

assertAttribute(检查当前指定元素的属性的值)

assertTable(检查table里的某个cell中的值)

assertEditable(检查指定的input是否可以编辑)

assertNotEditable(检查指定的input是否不可以编辑)

assertAlert(检查是否有产生带指定message的alert对话框)

waitForElementPresent (等待检验某元素的存在,为真时,则执行)

使用断言的注意点:

①不要使用断言作为公共方法的参数检查,公共方法的参数永远都要执行;

②断言语句不可以有任何边界效应,不要使用断言语句去修改变量和改变方法的返回值;

 

Selenium(5)解决页面元素display:none的方法

在UI自动化测试中,有时候会遇到页面元素无法定位的问题,包括xpath等方法都无法定位,是因为前端元素被设置为不可见导致。

 

1、具体问题

常见的页面元素不可见导致的不可定位,都是由于下面的问题:

通过查看相关文档,可以看出display:none方法是设置元素不可见,这就是导致为什么通过定位页面元素无法定位的原因。

 

2、解决方案

对于这种问题,可以通过JavaScript修改页面元素属性来将元素置位可见,然后通过id、classname等方法去定位,示例代码如下(针对上图所示):

js = "document.getElementById(\"txtPassword\").style.display='block';"
# 调用js脚本
driver.execute_script(js)
sleep(3)
driver.find_element_by_id("txtPassword").send_keys("123456")

代码解析:

首先通过selenium封装好的方法document去找到display元素,document提供以下方法来定位display元素:

getElementById():返回对指定ID第一个对象的引用

getElementsByName() :返回带有指定名称的对象集合

getElementsByTagName():返回带有指定标签名的对象集合

上面我定义了一个js变量,然后通过getElementById()方法去引用display元素,修改none属性为block属性(作为块级元素显示),然后通过selenium自带的execute_script方法执行脚本。

最后,当元素属性置为可见时,可以通过ID去定位元素。

 

其实还有一个解决方案:让前端修改display:none为block就好了,但这样的话,带来的变化和安全风险又是需要考虑的问题。一个问题的解决总是伴随着新的问题,核裂变了解一下?

想起今天和同行聊天时说起的分裂BUG的话题,对话如下:

大佬N:核裂变的原理是通过中子撞击原子核产生多个新的原子核,原子核是已有的BUG,中子是修改BUG加上的代码,分裂之后这个bug消失了,取而代之的是更多的原子核(BUG)。。。

我:引起一个BUG的原因可能是多个,修改一段代码可能造成多个BUG,就像用新技术解决旧问题而带来的新问题一个意思。。。

 

自动化本身最大的挑战还是变化,因此从分层测试角度结合公司项目具体情况,考虑解决问题的方法,才是最好的选择。

 

Selenium(6)利用Select模块处理下拉框

在利用selenium进行UI自动化测试过程中,经常会遇到下拉框选项,这篇博客,就介绍下如何利用selenium的Select模块来对标准select下拉框进行操作。。。

 

首先导入Select模块:

1 # coding=utf-8
2 from selenium import webdriver
3 from selenium.webdriver.support.select import Select

感兴趣的可以将鼠标指向Select,然后按住Ctrl鼠标单击,查看Select模块的源码,是如何定义封装Select的各个方法的。

1、Select提供了三种选择某一项的方法

1 select_by_index          # 通过索引定位
2 select_by_value          # 通过value值定位
3 select_by_visible_text   # 通过文本值定位

注意事项:

index索引是从“0”开始;

value是option标签的一个属性值,并不是显示在下拉框中的值;

visible_text是在option标签中间的值,是显示在下拉框的值;

 

2、Select提供了三种返回options信息的方法

1 options                  # 返回select元素所有的options
2 all_selected_options     # 返回select元素中所有已选中的选项
3 first_selected_options   # 返回select元素中选中的第一个选项

注意事项:

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

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

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

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

 

3、Select提供了四种取消选中项的方法

1 deselect_all             # 取消全部的已选择项
2 deselect_by_index        # 取消已选中的索引项
3 deselect_by_value        # 取消已选中的value值
4 deselect_by_visible_text # 取消已选中的文本值

注意事项:

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

 

下面以实际的代码来做个示例,被测试网页与源码截图如下:

比如要选择3线,那么三种选择方法示例代码如下:

# coding=utf-8
from selenium import webdriver
from selenium.webdriver.support.select import Select
from time import sleep

# 登录
driver = webdriver.Chrome()
......

# 根据索引选择
Select(driver.find_element_by_name("storeDeclare.cityLine")).select_by_index("3")
# 根据value值选择
Select(driver.find_element_by_name("storeDeclare.cityLine")).select_by_value("3线")
# 根据文本值选择
Select(driver.find_element_by_name("storeDeclare.cityLine")).select_by_visible_text("3线")
sleep(5)
driver.quit()

以上就是关于selenium的Select模块提供的几种方法的用法,示例代码只是示例,具体实践还需要结合实际的工作需要来进行

 

Selenium(7)三种等待方式

UI自动化测试,大多都是通过定位页面元素来模拟实际的生产场景操作。但在编写自动化测试脚本中,经常出现元素定位不到的情况,究其原因,无非两种情况:1、有frame;2、没有设置等待。

因为代码运行速度和浏览器加载渲染速度,不是一个量级,所以导致了这种情况发生。webdriver提供了3种类型的等待:显式等待、隐式等待、强制等待。

 

1、显示等待

定义:等待某个条件成立时继续执行,否则在达到最大时长时抛出异常(TimeoutException);

WebDriverWait类是由webdriver提供的等待方法,配合该类提供的until()和until_not()方法一起使用,就可以根据判断条件而灵活进行等待,格式如下:
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
driver:浏览器驱动
timeout:最长超时时间
poll_frequency:检测间隔时间,默认0.5s
ignored_exceptions:超时后的异常信息,默认情况抛出NoSuchElementException异常
WebDriverWait()一般由until()或until_not方法配合使用,下面是这两种方法的说明:
until(method,message=''):调用该方法提供的驱动程序作为一个参数,直到返回值为True;
until_not(method,message=''):调用该方法提供的驱动程序作为一个参数,直到返回值为Flase;

示例代码如下:

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
 
driver = webdriver.Chrome("F:\安装工具\python\chromedriver.exe")
driver.implicitly_wait(10)
driver.get('http://www.cnblogs.com/imyalost/')
locator = (By.LINK_TEXT, '老_张')
 
try:
    WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(locator))
    print(driver.find_element_by_link_text('老_张').get_attribute('href'))
finally:
    driver.close()

代码解析:

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

上面的例子中,同时使用了隐性等待和显性等待,但是需要注意的是:等待的最长时间取两者之中的最大值;

expected_conditions类提供的预期条件判断方法如下:
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 : 判断某个元素中是否可见并且是enable的,这样的话才叫clickable
staleness_of : 等某个元素从dom树中移除,注意,这个方法也是返回True或False
element_to_be_selected : 判断某个元素是否被选中了,一般用在下拉列表
element_selection_state_to_be : 判断某个元素的选中状态是否符合预期
element_located_selection_state_to_be : 跟上面的方法作用一样,只是上面的方法传入定位到的element,而这个方法传入locator
alert_is_present : 判断页面上是否存在alert

2、隐式等待

定义:通过设定的时长等待页面元素加载完成,再执行下面的代码,如果超过设定时间还未加载完成,则继续执行下面的代码(注意:在设定时间内加载完成则立即执行下面的代码);

隐式等待的方法为:implicitly_wait,示例代码如下:

# coding = utf-8
from selenium import webdriver
 
driver = webdriver.Chrome("F:\安装工具\python\chromedriver.exe")
driver.implicitly_wait(10) # 隐性等待,最长等10秒
driver.get('http://www.cnblogs.com/imyalost/')
 
print(driver.current_url)
driver.quit()

代码解析:

本例中,设置的等待时长为10秒,但这10秒并非一个固定时间,并不影响脚本执行速度;其次,隐式等待对整个driver的周期都起作用,因此只需要设置一次即可。

 

3、强制等待

即sleep()方法,由python中的time模块提供,强制让代码等待xxx时间,无论前面的代码是否执行完成或者还未完成,都必须等待设定的时间。

示例代码如下:

# coding = utf-8
from selenium import webdriver
from time import sleep
 
driver = webdriver.Chrome("F:\安装工具\python\chromedriver.exe")
driver.get('http://www.cnblogs.com/imyalost/')

sleep(5)
 
print(driver.current_url)
driver.quit()

代码解析:

本例中,设置强制等待时间为5秒,5秒之后,打印获取到的当前页面的url,然后关闭窗口。

这种强制等待的方法,在debug时候很有用,不过建议慎用这种方法,因为太死板,严重影响程序执行速度!

 

以上三种等待方法,在具体的场景中需要根据情况选择合适的方法,灵活运用。。。

 

Selenium(8)Html测试报告

自动化测试过程中,获得用例的执行结果后,需要有具象化、简洁明了的测试结果,比如:用例执行时间、失败用例数、失败的原因等,这时候,就需要用到测试报告。

HTML测试报告是python语言自带的单元测试框架,其扩展的HTMLTestRunner模块可用于生成易于使用的HTML测试报告。

 

1、HTMLTestRunner下载

下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html

下载完成后,将下载的文件保存到C盘的\Python35\Lib目录下(可以通过如下命令获取python安装目录):

①进入cmd命令行

②输入python

③输入import sys

④输入print(sys.path)

C:\Users\dell>python
Python 3.5.1 (v3.5.1:37a07cee5969, Dec  6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> print(sys.path)
['', 'C:\\Users\\dell\\AppData\\Local\\Programs\\Python\\Python35\\python35.zip', 'C:\\Users\\dell\\AppData\\Local\\Programs\\Python\\Python35\\DLLs',
  'C:\\Users\\dell\\AppData\\Local\\Programs\\Python\\Python35\\lib', 'C:\\Users\\dell\\AppData\\Local\\Programs\\Python\\Python35', 'C:\\Users\\dell\\
  AppData\\Local\\Programs\\Python\\Python35\\lib\\site-packages']

 

2、修改HTMLTestRunner文件

因为HTMLTestRunner是基于python2开发的,为了使其支持python3的环境,需要对其中的部分内容进行修改,修改后的内容如下:

# HTMLTestRunner修改内容
# 第94行
import io
# 第539行
self.outputBuffer = io.StringIO()
# 第631行
print(sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime))
# 第642行
if not cls in rmap:
# 第766行
uo = o
# 第772行
ue = e

3、python文件执行与调用

①python文件的后缀为.py

②py文件既可以用来执行,就像一小段程序,也可以用来作为模块被导入

③在python中导入模块一般用import

代码如下:

from selenium import webdriver
import unittest
import time

class MyTest(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver,Chrome("F:\安装工具\python\chromedriver.exe")
        self.driver.maximize_window()
        self.driver.implicitly.wait(10)
        self.base_url = "http://www.baidu.com"

    def test_baidu(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_id("kw").clear()
        driver.find_element_by_id("kw").send_key("unittest")
        driver.find_element_by_id("su").click()
        time.sleep(2)
        title = assertEqual(title,"unittest_百度搜索")

    def tearDown(self):
        self.driver.quit()

if __name__ == "__main__":
    unittest.main()

 

4、HTMLTestRunner测试报告

以上面的test_baidu.py文件为例子,生成HTMLTestRunner测试报告,代码如下:

from selenium import webdriver
import unittest
from HTMLTestRunner import HTMLTestRunner

class Baidu(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome("F:\安装工具\python\chromedriver.exe")
        self.driver.implicitly_wait(10)
        self.base_url = "http://www.baidu.com/"

    def test_baidu_search(self):
        driver = self.driver
        driver.get(self.base_url)
        driver.find_element_by_id("kw").send_key("HTMLTestRunner")
        driver.find_element_by_id("su").click()

    def tearDown(self):
        self.driver.quit()


if __name__ == "__main__":
    baidu = Baidu("test_baidu_search")
    testunit = unittest.TestSuite()
    testunit.addTest(baidu)

    # 定义报告存放路径
    fp = open('./result.html', 'wb')
    # 定义测试报告
    runner = HTMLTestRunner(stream=fp,
                        title='百度搜索测试报告',
                        description= '用例执行情况:')
    runner.run(testunit) #运行测试用例
    fp.close() #关闭报告文件

代码简析:

①将HTMLTestRunner模块用import导入

②通过open()方法以二进制写模式打开当前目录下的result.html,如果没有则自动创建该文件

③调用HTMLTestRunner模块下的HTMLTestRunner类,stream指定测试报告文件,title用于定义测试报告的标题,description用于定义测试报告的副标题

④通过HTMLTestRunner的run方法运行测试套件中所组装的测试用例,最后通过close()关闭测试报告文件

 

Selenium(8)集成测试报告

随着软件不断迭代功能越来越多,对应的测试用例也会呈指数增长。一个实现几十个功能的项目,对应的用例可能有上百个甚至更多,如果全部集成在一个文件中,那么这个文件就很臃肿且维护麻烦。

一个很好的方法就是将这些用例按照功能类型进行拆分,分散到不同测试文件中,即一个项目,对应多个分支。

 

一、分拆后的实现代码

1、testbaidu.py

from selenium import webdriver
import unittest
import time

class MyTest(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome("F:\安装工具\python\chromedriver.exe")
        self.driver.maximize_window()
        self.driver.implicitly.wait(10)
        self.base_url = "http://www.baidu.com"

    def test_baidu(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_id("kw").clear()
        driver.find_element_by_id("kw").send_key("unittest")
        driver.find_element_by_id("su").click()
        time.sleep(2)
        title = assertEqual(title,"unittest_百度搜索")

    def tearDown(self):
        self.driver.quit()

 

2、testyoudao.py

from selenium import webdriver
import unittest
import time

class Mytest(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome("F:\安装工具\python\chromedriver.exe")
        self.driver.maximize_window()
        self.driver.implicitly_wait(10)
        self.base_url = "http://www.youdao.com"
    
    def test_youdao(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_id("query").clear()
        driver.find_element_by_id("query").send.keys("webdriver")
        driver.find_element_by_id("qb").click()
        time.sleep(2)
        title = driver.title
        self.assertEqual(title, "webdriver - 有道搜索")

    def tearDown(self):
        self.driver.close()

 

二、创建用于执行所有用例的ALL_HTMLtest.py文件

1、ALL_HTMLtest.py

# coding=utf-8
import unittest
import time
from HTMLTestRunner import HTMLTestRunner

# 加载用例testbaidu,testyoudao
import testbaidu
import testyoudao

# 将测试用例添加到测试集中
suite = unittest.TestSuite()

suite.addTest(testbaidu.MyTest("test_baidu"))
suite.addTest(testyoudao.Mytest("test_youdao"))

if __name__ == '__main__':
    # 执行测试
    runner = unittest.TextTestRunner()
    runner.run(suite)

 

拆分带来的好处显而易见,可以根据不同功能创建不同的测试文件,甚至不同的目录,还可以将不同的小功能划分为不同的测试类,在类下编写测试用例,整体结构更加清晰。

但依然存在缺陷(当用例达到成百上千条时,在ALL_HTMLtest.py中addTest()添加测试用例就变得很麻烦)。。。

 

2、TestLoader类

unittest单元测试框架提供了TestLoader类,该类负责根据各种标准加载测试用例,并将它们返回给测试套件。

unittest提供了可以共享的defaultTestLoader类,可以使用其子类和方法创建实例,discover()方法就是其中之一。

discover(start_dir, pattern='test*.py', top_level_dir=None)

找到指定目录下的所有测试模块,并递归查找子目录下的测试模块,只有匹配到文件名才能被加载,如果启动的不是顶层目录,则顶层目录必须单独指定。

start_dir:要测试的模块名或测试用例目录;

pattern='test*.py':表示用例文件名的匹配原则,下面的例子中匹配文件名为以“test”开头的“.py”文件,星号“*”表示任意多个字符;

top_level_dir=None:测试模块的顶层目录,如果没有顶层目录,默认为None;

# coding=utf_8
import unittest
from unittest import defaultTestLoader
# 定义测试用例的目录为当前目录
test_dir = './'
discover = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py') 

if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(discover)

 

三、集成测试报告

HTMLTestRunner目前只针对单个测试文件生成测试报告,因此需要对上面的代码进行修改,修改后内容如下:
# coding=utf_8
import unittest
import time
from unittest import defaultTestLoader
from HTMLTestRunner import HTMLTestRunner

# 定义测试用例的目录为当前目录
test_dir = './report'
discover = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py') 

if __name__ == '__main__':
    now = time.strftime("%Y-%m-%d %H_%M_%S")
    filename = test_dir + '/' + now + 'result.html'
    fp = open(filename, 'wb')
    runner = HTMLTestRunner(stream=fp,title='集成测试报告demo',description= '用例执行情况:')
    runner.run(discover)
    fp.close()

 

执行后,结果如下:

 

 

转载: https://www.cnblogs.com/imyalost

转载于:https://www.cnblogs.com/anhao521/p/10955493.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值