面试准备——(三)Selenium面试题总结

1、Selenium基本知识

1. 什么是Selenium?

Selenium是浏览器自动化工具,主要用来Web的自动化测试,以及基于Web的任务管理自动化。它支持的语言有:python、Java、ruby、JavaScript等,而且几乎能在主流的浏览器上运行。css

Selenium2.0、Selenium3.0主要由三大部分组成:SeleniumIDE、Selenium WebDriver、Selenoium Grid。html

  • Selenium IDE录制和回放脚本,能够模拟用户对页面的真实操做,区别于其余工具:是经过拦截http请求
    • 通常只把录制脚本看成一个辅助功能,由于一个UI节点的细微变化,均可能致使自动化测试工具没法识别,当测试项目项目大时,定位、更新十分困难。
    • 其次,录制的脚本有时候人工难以理解。
  • Selenium Grid实如今多台机器上、和异构环境中并行执行测试用例。并行执行不只节省时间,并且能够同时在不一样的浏览器、平台上运行自动化测试脚本。
  • Selenium Web Driver:针对各个浏览器而开发,经过原生浏览器支持或者扩展(Chrome webDrive、FireFox WebDriver)直接控制浏览器

    VS Selenium RC(Selenium1.0):在浏览器中运行javaScript,使用浏览器内置的JavaScript来翻译和执行selensejava

Web Driver原理python

webDriver是按照client/server模式设计的。client是咱们的测试脚本,发送请求;server就是打开的浏览器,用来接收client的请求并做出响应。web

具体的工做流程:ajax

  1. webDriver打开浏览器并绑定到指定端口。启动的浏览器做为远程服务器remote server
  2. client经过CommandExecuter发送http请求给远程服务器的侦听端口(the wire protocal)
  3. 远程服务器根据原生的浏览器组件来转化为浏览器的本地(native)调用

web Driver用到的协议设计模式

  1. 打开浏览器时:HTTP协议
  2. client端发送http请求到远程服务器的侦听端口:the wire protocol

其中:浏览器

  • 有线协议:指的是从点到点获取数据的方式,是应用层的协议。
  • HTTP协议:是用于从服务器传输超文本标记语言HTML到客户端的通讯协议。是一个应用层协议,由请求/响应构成,是一个标准的客户/服务器模式。是一个无状态的协议。(无状态:对事务没有记忆能力,不会保存此次传输的信息——节约内存)

2. Selenium的特色有:

  • 支持录制和回放(Selenium IDE)
  • 经过WebDriver,直接控制浏览器,而不是经过拦截HTTP请求,实现真正模仿了用户的操做;同时使用WebDriver可以灵活的获取页面元素(WebDriver),而且提供执行JS的接口
  • 可以分布式运行在不一样机器和异构环境中(不一样浏览器)

 

3. Selenium的内部运行机制?如何可以跨浏览器使用?——WebDriver原理(&RC原理)

1)RC原理安全

在Selenium1.0中,是经过Selenium RC服务器做为代理服务器去访问应用从而达到测试的目的。ruby

Selenium RC分为三个部分,Launcher、HttpProxy、Core。

  • Launcher用于启动浏览器,把Selenium Core加载到浏览器中,而且把浏览器的代理设置为Selenium Server的Http Proxy。
  • Core是一堆JavaScript的集合,因此本质至关于运行这些JavaScript函数来实现对Html页面的操做。——这也是为何能够运行在几乎全部主流的浏览器上。

然而直接运行JavaScript会有极大的安全漏洞,因此会受到“同源限制”,在这个基础上,Selenium2.0引入了WebDriver。

2)Web Driver原理

webDriver是按照client/server模式设计的。client是咱们的测试脚本,发送请求;server就是打开的浏览器,用来接收client的请求并做出响应。

具体的工做流程:

  1. webDriver打开浏览器并绑定到指定端口。启动的浏览器做为远程服务器remote server
  2. client经过CommandExecuter发送http请求给远程服务器的侦听端口(the wire protocal)
  3. 远程服务器根据原生的浏览器组件来转化为浏览器的本地(native)调用

因此web Driver用到的协议

  1. 打开浏览器时:HTTP协议
  2. client端发送http请求到远程服务器的侦听端口:the wire protocol

其中:

  • 有线协议:指的是从点到点获取数据的方式,是应用层的协议。
  • HTTP协议:是用于从服务器传输超文本标记语言HTML到客户端的通讯协议。是一个应用层协议,由请求/响应构成,是一个标准的客户/服务器模式。是一个无状态的协议。(无状态:对事务没有记忆能力,不会保存此次传输的信息——节约内存)

4. 如何提升selenium脚本的执行速度?

1)优化测试用例。

  • 尽量不用sleep、减小使用implicityWait,而使用WebDriverWait/FluentWait,这样能够优化等待时间
  • 减小没必要要的操做步骤。

2)使用Selenium grid,经过testNG实现并发执行。 

说到这里,在编写测试用例的时候,必定要实现松耦合,而后再服务器容许的状况下,尽可能设置多线程实现并发运行。

3)设置等待时间、中断页面加载。若是页面加载内容太多,咱们能够查看一下加载缓慢的缘由,在不影响测试的状况下,能够设置超时时间,中断页面加载。

 

5. 提升自动化脚本稳定性——减小误报

1. 误报问题。咱们一旦测试用例没有经过,则没法完成每日自动构建,可是其实这些测试用例是正确,也不存在BUG。

2. 主要的缘由页面尚未加载完成,咱们就开始进行元素定位。

3. 解决方法重试机制。利用递归封装了一个等待元素的方法。其中,设置最大等待时间为1s,轮询时间为50ms,这个方法会不断轮询,直到方法执行成功或者超过设置的最大等待时间。在咱们最好的一次实践中,咱们把一个测试用例的误报率从10%下降到0,而且执行时间从原先的45秒下降到33秒。

 

6. 如何设计高质量自动化脚本

1. 使用四层结构实现业务逻辑、脚本、数据分离。

2. 使用PO设计模式,将一个页面用到的元素和操做步骤封装在一个页面类中。若是一个元素定位发生了改变,咱们只用修改这个页面的元素属性

3. 对于页面类的方法,咱们尽可能从客户的正向逻辑去分析,方法中是一个独立场景,例如:登陆到退出,并且不要想着把全部的步骤都封装在一个方法中。

4. 测试用例设计中,减小测试用例之间的耦合度。

 

7. 你以为自动化测试最大的缺陷是什么?

1. 一旦项目发生变化,测试用例就须要改进,工做量大。

2. 验证的范围有限,操做更加复杂,好比说简单的一个验证验证码,若是是人工识别很快就能够输入,可是自动化测试中会增添不少困难。那么这个时候速度也不如人工。

3. 不稳定

4. 可靠性不强

5. 成本与收益

 

2、元素定位

1. ElementNotVisible

1. selenium中hidden或者是display = none的元素是否能够定位到?——用Js修改display = block

1)区分:display= none VS hidden

共同点:都把网页中的元素给隐藏起来了;在selenium中没法直接定位

区别:none:不为隐藏的对象保留其物理空间 看不见/摸不着

   hidden仍占有空间 看不见/摸得着

1. 处理 display:none

页面主要经过"dislay:none"来控制整个下拉框不见。若是直接操做:

from selenium.webdriver.support.ui import WebDriverWait
from selenium import webdriver
from selenium.webdriver.support.select import Select
import os

driver = webdriver.Firefox(executable_path="/Users/lesley/Downloads/geckodriver")
file_path = 'file:///' + os.path.abspath('test.html')
driver.get(file_path)

select = driver.find_elements('select')
Select(select).select_by_value('volvo')
WebDriverWait()

driver.quit()

报错:ElementNotVisible

咱们能够通过JavaScript来修改display的值

js = 'document.querySelectortAll('select')[0]'.style.display='block';'

select = driver.find_element_by_tag_name('select')
Select(select).select_by_value('Opel')

document.querySelectAll('select'):选择全部的select;[0]表示第几个

style.display='block':修改display=block,表示可见

 

2. NoSuchElementException

首先,判断一个元素是否显示:is_displayed()

1. Frame/IFrame缘由定位不到元素——switch_to_iframe

frame是指:页面中嵌入另外一个页面,而webdriver每次只能在一个页面识别,所以须要先定位到相应的frame,对那个页面里的元素进行定位。

此时,有两种方式:

1. iframe存在id 或者name。

首先用switch_to_frame('x-URS-iframe')定位到这个iframe,而后再定位这个iframe中的元素

driver=webdriver.Firefox()
driver.get(r'http://www.126.com/')
driver.switch_to_frame('x-URS-iframe')  #需先跳转到iframe框架
username=driver.find_element_by_name('email')
username.clear()

2.  iframe不存在name/id。

先定位到iframe,再swith_to_frame

#先定位到iframe
elementIframe= driver.find_element_by_class_name('APP-editor-iframe')
#再将定位对象传给switch_to_frame()方法
driver.switch_to_frame(elementIframe) 

若是完成操做后,能够经过switch_to_parent_content()方法跳出当前iframe,或者还能够经过switch_to_default_content()方法跳回最外层的页面。

 

2. 页面没有加载出来,就对页面中元素进行操做。

——设置等待时间直到元素出现(WebDriveWait(driver,10).until(lambda x:x.find_elemetn_by_id('someId').is_displayed)

获取页面加载状态

document.readyState

例如:当Selenium点击一个按钮打开一个弹窗,弹窗尚未打开的时候,咱们就要使用弹窗上一个按钮。

——>解决:设置等待最大等待时间

1)sleep():设置固定休眠时间

2)implicity_wait():是webDriver提供的一个超时等待,隐的等待一个元素被发现,或者一个命令完成

3)WebDriverWait():一样也是WebDriver提供的方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,若是超出指定时间检测不到则抛出异常。

WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)

# driver:WebDriver的驱动程序
# timeout:最长超时时间,默认以秒为单位
# poll_frequency:休眠时间的间隔时间
# ignore_exception():超时后的异常信息,默认状况下抛出NoSuchElementException

一般与until()或者until_not()方法配合使用

until(method, message="")
# 调用该方法提供的驱动程序做为一个参数,直到返回值不为FALSE

until_not(method, message="")
# 调用该方法提供的驱动程序做为一个参数,直到返回值为FALSE

 举例:

 1 from selenium.webdriver.support.ui import WebDriverWait
 2 
 3 from selenium import webdriver
 4 import time
 5 
 6 driver = webdriver.Firefox(executable_path="/Users/lesley/Downloads/geckodriver")
 7 driver.get("https://www.baidu.com/")
 8 
 9 # 添加WebDriverWait
10 element = WebDriverWait(driver, 10).until(lambda driver:driver.find_element_by_id("kw"))
11 is_disappeared = WebDriverWait(driver, 5).until_not(lambda x: x.find_element_by_id("someId").is_displayed())
12 element.send_keys("sbw")
13 
14 # 添加智能等待
15 driver.implicitly_wait(5)
16 driver.find_element_by_id("su").click()
17 
18 # 添加固定时间等待
19 time.sleep(5)
20 
21 driver.quit()

4)WaitFor:配合setTimeout,设置最大等待时间,而后轮询查看是否在指定时间内找到该元素。

1 def waitfor(getter, timeout=3, interval=0.5, *args):
 2     starttime = datetime.datetime.now()
 3     while True:
 4         if getter(args):
 5             return
 6         else:
 7             runtime = datetime.datetime.now() - starttime
 8             print runtime
 9             if runtime.seconds >= timeout:
10                 raise Exception
11             time.sleep(interval)
12     
13 current_value = 1    
14 def testgetval(args):
15     wanted_value = args[0]
16     global current_value
17     current_value += 1
18     print '%d, %d' % (wanted_value, current_value)
19     return current_value > wanted_value    
20         
21 if __name__ == '__main__':
22     waitfor(testgetval, 1, 0.3, 2)
23     print '======================='
24     waitfor(testgetval, 1, 0.3, 8)

 

3. 动态ID没法定位元素——1)直接使用Xpath相对路径;2)根据部分元素定位

如何判断是动态ID?

简单,通常看到元素属性里有拼接一串数字的,就颇有多是动态的。想要分辨,刷新一下浏览器再看该元素,属性值中的数字串改变了,便是动态属性了。

<div id="btn-attention_2030295">...</div>

方式(一)根据相对路径

http://blog.csdn.net/huilan_same/article/details/52541680

方式(二)根据部分元素属性定位

driver.find_element_by_xpath("//div[contains(@id, 'btn-attention')]")
driver.find_element_by_xpath("//div[starts-with(@id, 'btn-attention')]")
driver.find_element_by_xpath("//div[ends-with(@id, 'btn-attention')]")  # 这个须要结尾是‘btn-attention’

 

4. 二次定位,如弹出登录框

——层级定位

# 点击打开菜单栏
driver.find_element_by_xpath("//*[@id='sidebar-collapse']/i").click();

# 点击菜单块
driver.find_element_by_xpath("//*[@id='sidebar']/div[1]/ul/li[2]/a").click();

# 点击“待办中心”
driver.find_element_by_linkText("待办案件").click();

 

5. 有两个属性相同的元素,可是其中一个是不可见的。——找到符合这个属性且style属性中display=none的元素

driver.find_element_by_xpath("//span[contains(@id, 'sbw')] and not(contains[@style, 'display:none'])")

 

6. Xpath描述错误

1)经过属性定位元素

find_element_by_xpath("//标签名[@属性='属性值']")

例如:

# id属性:
driver.find_element_by_xpath("//input[@id='kw']")

# class属性:
driver.find_element_by_xpath("//input[@class='s_ipt']")

# name属性:
driver.find_element_by_xpath("//input[@name='wd']")

# maxlength属性:
driver.find_element_by_xpath("//input[@maxlength='255']")

2)经过标签名

driver.find_elment_by_xpath('//input')

3)父子定位元素

查找有父亲元素的标签名为span,它的全部标签名叫input的子元素

driver.find_element_by_xpath("//span/input") 

4)经过元素内容

例如:

<p id="jgwab">
    <i class="c-icon-jgwablogo"></i>
    京公网安备11000002000001号
</p>

则咱们能够定位:

# 根据text()
driver.find_elment_by_xpath('//p[contains(text(), '京公网')]')

# 根据class
driver.find_elment_By_xpath('//p[contains(@class, '京公网')]')

5. 组合定位元素

//父元素标签名/标签名的属性值:指的是span下的input标签下class属性为s_ipt的元素

driver.find_element_by_xpath("//span/input[@class='s_ipt']")

6. 多个属性组合定位

指的是input标签下id属性为kw且name属性为wd的元素

driver.find_element_by_xpath("//input[@class='s_ipt' and @name='wd']")

指的是p标签下内容包含“京公网”且id属性为jgwab的元素

find_element_by_xpath("//p[contains(text(),'京公网') and @id='jgwab']") 

 

3、常见控件使用

1. link、button

element.click()

2. Textbox

element.send_keys('test')

3. Upload

element.send_keys('D\test.txt')

4. Mouse Event——ActionChains()

#双击
ActionChains(driver).double_click(element).perform()

#右击
ActionChains(driver).context_click(element).perform()

#拖动
ActionChains(driver).drag_and_drop(element).perform()

#悬停
ActionChains(driver).move_to_element(element).perform()

5. DropDown:

1)<Select>标签的下拉菜单

from selenium.webdriver.support.ui import Select

Select(driver.find_element_by_id('gender')).select_by_value('2')
Select(driver.find_element_by_id('gender')).select_by_index(1)
Select(driver.find_element_by_id('gender')).select_by_visible_text('Male')

2)非<select>标签——层级定位

Dropdown1 = driver.find_element_by_id(‘id’) #先定位到dropdown

Dropdown1.find_element_by_id(“li2_input_2”) #再定位到dropdown中的值

 3)使用js实现:

 

6. Alert

driver.switch_to_alert().accept() # 接收弹窗
driver.switch_to_alert().dismiss() # 取消弹窗

# 获取弹窗的文本消息
Message = driver.switch_to_alert().text

7. Window

driver.refresh() # 刷新

driver.back() # 后退

driver.forward() # 前进

driver.maximize_window() # 最大化

driver.set_window_size(100,200) # 设置窗口大小

driver.switch_to.window(searchwindow)

8. frame

driver.switch_to.frame(ReferenceFrame)

driver.switch_to.parent_frame()  # frame须要一级一级切

driver.switch_to.default_content() # 返回最外层

 

4、等待

1. 显示等待——WebDriverWait()

:等到某个条件成立时继续执行。每隔一段时间检测,超出最大时间则抛出异常

is_disappeared = WebDriverWait(driver, 5).until_not(lambda x: x.find_element_by_id("someId").is_displayed())

 

2.  隐式等待——implicitly_wait()

隐式等待中的时间并不是一个固定的等待时间,它并不影响脚本的执行速度。好比进行某元素的定位时,若是元素能够定位就继续执行,若是目前定位不到就以轮询的方式持续判断该元素是否被定位到,若是超过规定的时间还没定位到就抛出异常。

driver.implicitly_wait(20)

 

3. 强制等待——sleep()

from time import sleep
sleep(5)

 

 5、测试模型

 

3. selenium中如何保证操做元素的成功率?也就是说如何保证我点击的元素必定是能够点击的?

  1. 首先经过封装find方法,实现wait_for_element_ispresent,这样在对元素进行操做以前保证元素被找到,进而提升成功率。(WebDriverWait)
  2. 在对页面进行click以前,先滚动到该元素(经过Js封装),避免在页面未加在完成前或是在下拉以后才能显示。

 

4. Selenium有几种定位方式?你最偏心哪种,为何?

Selenium有八种定位方式

  1. 与name有关的有三种:name、class_name、tag_name
  2. 与link相关的有两种:link_text、partitial_link_text
  3. 与id有关:id
  4. 全能选手:xpath、css_selector

若是存在id,我必定使用Id,由于简单方便,定位最快。其次是Xpath,由于不少状况下html标签的属性不够规范,没法惟必定位。Xpath是经过相对位置定位

 

5. 如何去定位页面上动态加载的元素?

首先触发动态事件,而后再定位。若是是动态菜单,则须要层级定位。——JS实现(对动态事件封装)

http://www.cnblogs.com/tobecrazy/p/4817946.html 

6. 如何去定位属性动态变化的元素?

属性动态变化也就是指该元素没有固定的属性值能够经过:

  1. JS实现,
  2. 经过相对位置来定位,好比xpath的轴,paren/following-sibling/percent-sibling

http://www.cnblogs.com/zhaozhan/archive/2009/09/10/1564332.html

 

8. 点击连接之后,selenium是否会自动等待该页面加载完毕?

不会的。因此有的时候,当selenium并未加载完一个页面时再请求页面资源,则会误报不存在此元素。因此首先咱们应该考虑判断,selenium是否加载完此页面。其次再经过函数查找该元素。

  

11. 如何在定位元素后高亮元素(以调试为目的)?

 

12. 什么是断言?VS 验证

1)断言(assert):测试将会在检查失败时中止,并不运行后续的检查

优势:能够直截了当的看到检查是否经过

缺点:检查失败后,后续检查不会执行,没法收集那些检查结果状态

2)验证(vertify):将不会终止测试

缺点:你必须作更多的工做来检查测试结果:查看日志——>耗时多,因此更偏向于断言

# 断言验证:百度搜索的标题是否为:百度搜索
# import unittest

try:
    self.assertEqual(u"百度搜素", driver.title)
except AssertionError as e:
    print("Cannot find this title")

3)Waitfor:用于等待某些条件变为真。可用于AJAX应用程序的测试。

若是该条件为真,他们将当即成功执行。若是该条件不为真,则将失败并暂停测试。直到超过当前所设定的超时时间。 通常跟setTimeout时间一块儿用。

 

经常使用的断言:

 1 assertLocation          # 判断当前是在正确的页面
 2 assertTitle             #检查当前页面的title是否正确
 3 assertValue             # 检查input的值, checkbox或radio,有值为”on”无为”off”
 4 assertSelected          # 检查select的下拉菜单中选中是否正确
 5 assertSelectedOptions   # 检查下拉菜单中的选项的是否正确
 6 assertText              # 检查指定元素的文本
 7 assertTextPresent       # 检查在当前给用户显示的页面上是否有出现指定的文本
 8 assertTextNotPresent    # 检查在当前给用户显示的页面上是否没有出现指定的文本
 9 assertAttribute         # 检查当前指定元素的属性的值
10 assertTable             # 检查table里的某个cell中的值
11 assertEditable          # 检查指定的input是否能够编辑
12 assertNotEditable       # 检查指定的input是否不能够编辑
13 assertAlert             # 检查是否有产生带指定message的alert对话框
14 waitForElementPresent   # 等待检验某元素的存在。为真时,则执行。

 

13. 若是有一个按钮,点击该按钮后发出一个ajax call,而后获得返回结果后内容显示到新弹出的一个layer中。在写脚本的时候,点击这个按钮动做是否能够用clickAndWait命令?若是不行,怎么解决?

不可以。Ajax是一种支持动态改变用户界面元素的技术。在Ajax驱动的应用程序中,数据能够从应用服务器检索,而后显示在页面上,而不须要加载整个页面,只有一小部分页面或者元素自己被从新加载。

因此不可以使用ClickAndWait,由于Ajax call不会刷新整个页面,clickAndWait命令会由于等待页面从新加载而出现time out。

也就是说最大的麻烦是判断Ajax调用是否结束。能够用click + pause完成

使用JQuery进行辅助测试:http://www.cnblogs.com/nbkhic/archive/2011/10/23/2221729.html

 

 

其中,去哪儿网的题目以下:

1、 UI自动化测试

Qunar机票搜索场景

1) 访问Qunar机票首页http://flight.qunar.com,选择“单程”,输入出发、到达城市,选择today+7往后的日期,点“搜索”,跳转到机票单程搜索列表页。

2) 在列表页停留1分钟,至到页面上出现“搜索结束”。

3) 若是出现航班列表,对于出现“每段航班均需缴纳税费”的行随机点选“订票”按钮,在展开的列表中会出现“第一程”、 “第二程”;对于没有出现“每段航班均需缴纳税费”的行随机点选“订票”按钮,在展开的列表底部中会出现“报价范围”

4) 若是不出现航班列表,则页面会出现“该航线当前无可售航班”

请使用maven建立java工程,引入Selenium框架,编写WebUI代码,实现上述人工操做和验证。要求能随机验证100个城市对的3个月内的任意搜索条件。

 参见答案:http://www.cnblogs.com/tobecrazy/p/4752684.html

不少人可能第一步就卡住了,怎么选择7天之后的日期呢?

实际上很简单,直接在输入框里输入就行了。由于selenium支持的语言不少,这里就用js写一下。你们用selenium执行这段js就能够搞定了。

var date = new Date();
date.setDate(date.getDate() + 7);

var a_week_later = date.getFullYear() + '-' (date.getMonth()+1) + '-' + date.getDate();
$('input[name=fromDate]').val(a_week_later);

参考答案: http://www.cnblogs.com/tobecrazy/p/5873288.html                                     

相关文章
相关标签/搜索