什么是selenium?
一个用于Web应用程序测试的工具直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。测试与浏览器的兼容性,测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能,创建衰退测试检验软件功能和用户需求。
slenium前世
早期是直接使用 javascrip 注入技术与浏览器打交道,slenium RC启动一个server 将web元素api转换为javascript。在Selenium内核启动浏览器之后注入这段Javascript,由此才实现了Selenium的目的:自动化Web操作。这种Javascript注入技术的缺点是速度不理想,而且稳定性大大依赖于Selenium内核对API翻译成的Javascript质量高低。
slenium现在
Selenium2.x 提出了WebDriver的概念之后与浏览器交互利用原生的API,直接操作浏览器页面里的元素。不同的浏览器厂商对Web元素的操作和呈现一些差异直接导致了Selenium WebDriver要分浏览器厂商不同,而提供不同的实现。Selenium3.0发布后,最大更新点就是干掉了对selenium rc的支持,后面就一直是webdriver协议,
WebDriver工作流程
1、通过WebDriver创建一个浏览器服务,remote server
2、脚本启动时会在新的线程中启动一个浏览器,并绑定特定的端口,没个浏览器有不同的端口段。
3、client 创建1个session,在该session中通过http请求向remote server发送restful的请求,remote server解析请求,完成相应操作并返回response。
4、分析response,继续执行脚本还是结束执行
command.py:Command类中定义了WebDriver的一些常用的常量。
remote\webdrvier.py:所有浏览器webdrvier的基类,其中包含了所有webdriver的api接口
remote\remote_connection.py:包含启动Remote WebDrvier server,执行client请求,self._commands是selenium的核心请求参数,根据对应的Command常量,发送不同的http请求。
selenium 中的等待方式:time(固定等待),implicitly_wait(隐式等待),WebDriverWait(显示等待)
webdriver client的原理
当测试脚本启动Chrome的时候,selenium-webdriver 会首先在新线程中启动Chrome浏览器。启动后selenium-webdriver会将Chrome绑定到特定的端口,绑定完成后该chrome实例便作为webdriver的remote server存在;客户端(也就是测试脚本)创建1个会话,在该session中通过http请求向remote server发送请求,remote server解析请求,完成相应操作并返回response;客户端接受response,并分析其返回值以决定是转到第3步还是结束脚本;
webdriver是按照server – client的经典设计模式设计的。
server端就是remote server,可以是任意的浏览器。当我们的脚本启动浏览器后,该浏览器就是remote server,它的职责就是等待client(脚本)发送请求并做出相应;
client端简单说来就是我们的测试代码,我们测试代码中的一些行为,比如打开浏览器,转跳到特定的url等操作是以http请求的方式发送给被测试浏览器,也就是remote server;remote server接受请求,并执行相应操作,并在response中返回执行状态、返回值等信息;
selenium的搭建
1.在python中安装好selenium包 : pip install selenium
2.在配置好浏览器的驱动程序根据http://www.imdsx.cn/index.php/2017/08/02/drvier/ 驱动对照表下载Chrome对驱动,并添加在PATH环境变量中,(或者直接把驱动放在pytho的安装目录下)
Firefox驱动下载地址为:https://github.com/mozilla/geckodriver/releases/ ,
IE浏览器驱动下载地址为:http://selenium-release.storage.googleapis.com/index.html
编写以下代码能打开对应的浏览器就配置成功:
from selenium import webdriver driver = webdriver.Chrome() driver.get('http://www.imdsx.cn')
from selenium import webdriver driver = webdriver.Firefox() driver.get('http://www.imdsx.cn')
from selenium import webdriver driver = webdriver.Ie() driver.get('http://www.imdsx.cn')
selenium定位
import selenium #引用selenium包 from selenium import webdriver#引用包的服务 driver = webdriver.Chrome()#创建浏览器 当做我们的服务端 driver.get('xxxxxxxxxxxxxxx/')#打开对应测试网站,这里的url 必须带有http # 8种单数定位方式 # id进行定位 # driver.find_element_by_id('i1').send_keys('123123')#send_keys向文本框输入数字 # class 定位方式 # driver.find_element_by_class_name('classname').send_keys('123123') # name定位方式 # driver.find_element_by_name('name').send_keys('123123') # 文案定位 # driver.find_element_by_link_text('新建标签页面').click() #.click()表示点击操作 # 文案包含定位方式 js = 'window.scrollTo(0,0);' # 将滚动条调制最上方 driver.execute_script(js)# 执行写好的js # import time # # time.sleep(2)#界面如果反应比较慢可以加载等等时间 # driver.find_element_by_partial_link_text('新建标签').click() # 标签名定位 最不常用的 # driver.find_element_by_tag_name('input').send_keys('1111') # xpath 定位 # driver.find_element_by_xpath('//*[@id="i1"]').send_keys('2222') # css id 定位 # driver.find_element_by_css_selector('#i1').send_keys('2222') # # css name 定位 # driver.find_element_by_css_selector('name').send_keys()
xpath定位
xpath(xpath 定位尽量少用层级定位,如果开发更改了页面的层级,所有定位都挂了,尽量属性定位为主,层级为辅助) //* 取当前页面的全部元素 //*[@id='i1'] id 进行定位 @代表引用属性 //*[@placeholder="请通过ID定位元素"] //input[@placeholder="请通过ID定位元素"] 通过 标签名进一步缩小范围 //select[4] 如果存在不唯一的情况 可以通过角标进行取值 xpath从1开始取 //select[@size="4" and @multiple="multiple"] 逻辑定位
当不确定时可以只用copy直接复制xpath地址(这个地址相当于层级定位最好少用)
css selector定位
css selector 1.支持ID,class 定位 (# 代表id) ( . 表示class) 不是说不能用class 如果class属性在页面中唯一,那么是可以等同于id来使用 2.属性定位 [placeholder = "请通过ID定位元素"] 属性定位 3.标签组合定位 input[placeholder = "请通过ID定位元素"] 缩小范围 先定位input 在定位属性 4.多属性组合定位 Css Selector 的多属性组合选择过滤 没有and 只需要多个[] 连接 就可以 select[size = "4"][multiple = "multiple"] 多属性确立唯一 5.层级关系定位 通过 > 来区分层级的界定 select>option[value='3'] 6.模糊匹配 ^= 匹配元素属性以什么开头 input[value ^= "登"] $= 匹配属性以什么结尾 input[value$="录"] *= 匹配属性包含什么值 input [value *= "录"]
做UI自动化前需要了解什么
1.什么时候做UI自动化:当项目已经稳定不在大面积修改的情况下,就可以接自动化了。
2.做UI自动化需要了解什么知识:前端HTML,CSS,定位方式
简单的UI自动化框架
1.bin 目录下放程序入口 2.lib 目录下放一些配置文件 3.log 目录下放日志 (HTMLTestRunne :生产网页的报告页面, logger 生成日志 path 配置地址 pyse 定位页元素使用的框架 tool 生成错误图片) 4.pages 目录下放页面元素、 5.report 目录下放文件运行报告 (picture)下放错误截图 6.test_case 目录下放用例 框架能实现: 1、基于显示等待 解决不稳定的情况 (time:固定等待 , implicitly_wait: 隐式等待,webDriveWait:显示等待) 2.解决维护麻烦 PO(page object)思想(以一个页面当做一个类,每一个页面的功能点当做一个函数) 3.自动化测试用例和页面数据源进行分离。 怎么判断业务逻辑的成功 举例说明:假设是登录的业务逻辑,判断登录的特有元素消失 ,就代表登录成功了。 只有登录成功了才会出现的元素 判断一下他是否出现
from lib.logger import logger from lib.path import WEBCASEPATH,REPORTPATH from lib.HTMLTestRunner import HTMLTestRunner import unittest from lib.tool import Tool class Main(object): def run(self): Tool().clear_picture() suite = unittest.TestSuite() cases = unittest.defaultTestLoader.discover(WEBCASEPATH) print(cases) for case in cases: print(case) suite.addTest(case) f = open(REPORTPATH,'wb') runner = HTMLTestRunner(f,verbosity=1,title=u'测试报告', description=u'用例执行情况:') runner.run(suite) f.flush() f.close() if __name__ == '__main__': Main().run()
# -*- coding: utf-8 -*- """ A TestRunner for use with the Python unit testing framework. It generates a HTML report to show the result at a glance. The simplest way to use this is to invoke its main method. E.g. import unittest import HTMLTestRunner ... define your tests ... if __name__ == '__main__': HTMLTestRunner.main() For more customization options, instantiates a HTMLTestRunner object. HTMLTestRunner is a counterpart to unittest's TextTestRunner. E.g. # output to a file fp = file('my_report.html', 'wb') runner = HTMLTestRunner.HTMLTestRunner( stream=fp, title='My unit test', description='This demonstrates the report output by HTMLTestRunner.' ) # Use an external stylesheet. # See the Template_mixin class for more customizable options runner.STYLESHEET_TMPL = '' # run the test runner.run(my_test_suite) ------------------------------------------------------------------------ Copyright (c) 2004-2007, Wai Yip Tung All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name Wai Yip Tung nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ # URL: http://tungwaiyip.info/software/HTMLTestRunner.html __author__ = "Wai Yip Tung" __version__ = "0.8.3" """ Change History Version 0.8.3 * Use Bootstrap (Zhang Xin) * Change to Chinese (Zhang Xin) Version 0.8.2 * Show output inline instead of popup window (Viorel Lupu). Version in 0.8.1 * Validated XHTML (Wolfgang Borgert). * Added description of test classes and test cases. Version in 0.8.0 * Define Template_mixin class for customization. * Workaround a IE 6 bug that it does not treat%(heading)s %(report)s %(ending)s