一、selenium工具介绍
-
简介:selenium主要用于web应用程序的自动化测试, 支持多平台(linux,windows,MAC),
多语言(java,python,Ruby,JS), 多浏览器(谷歌,火狐IE,Edge,Opera)。 -
版本: 有selenium1.0、2.0和3.0,即将推出4.0。
版本介绍:
selenium由插件、类库组成
selenium1.0家族:selenium IDE、selenium Grid、selenium RC
- selenium IDE 嵌入到浏览器的一个插件,实现简单的浏览器操作的录制和回放功能。
3.0后只有录制和回放功能,不能导出脚本。 - selenium Grid 有Grid1和Grid2两个版本,Grid2同时支持selenium1和selenium2两种协议。
Grid2不再提供单独的包,其功能已经集成到selenium server中。
Grid工作原理:Grid是进行分布式测试的工具,其整个结构由一个hub主节点和多个node代理节点组成。hub主节点管理代理节点的注册和状态信息,并且接收远程客户端代码的请求调用,并且把请求的命令转发给代理节点来执行。
可以在各个代理节点启动不同的浏览器。
-
selenium RC或者Selenium Remote Control selenium RC有Client Libraries和selenium Server。
Client Libraries库主要用于编写测试脚本,用来控制selenium server的库。 selenium Server负责控制浏览器的行为。
selenium Server分为三部分:launcher、core和http proxy。其中core是被selenium server嵌入到浏览器页面中的,其实是一堆javascript函数的集合,即通过这些javascript函数,实现用程序对浏览器进行操作。launcher用来启动浏览器,将core加载到浏览器页面中,并且将浏览器的代理设置为http proxy。利用原理:JS代码可以很方便地获取页面上的任何元素并进行操作。
但注入JS代码会触发浏览器的同源策略,所以引入selenium Server,其中http proxy就是用来规避同源策略的。
selenium1.0的工作流程:
- 测试用例通过client libraries接口向selenium server 发送http请求,要求与selenium
server 建立连接;
(测试用例是在client libraries库中基于不同语言java、python、ruby等编写的) - 建立连接后,selenium server 通过launcher驱动浏览器,并且把selenium
core加载到浏览器页面中,把浏览器代理设置为server的http proxy; - 测试用例向selenium server发送http请求,selenium server解析http请求,然后通过http
proxy发送JS命令,通知core执行操作浏览器的动作; - core执行JS命令,操作浏览器;
- 如果浏览器接收到新的页面请求信息时,发送http请求,请求新的web页面; (由于Launcher在启动 浏览器时把Http
Proxy设置成为了浏览器的代理,所以Selenium RC Server会接收到所有由它启动 的浏览器发送的请求。) - selenium server接受到新的http请求并解析后,重组http请求以规避“同源策略”,获取对应的web页面;
- selenium server通过http proxy把接收到的web页面返回给浏览器。
课外小知识:
- 同源策略:同源是指域名、协议和端口相同。 当一个浏览器打开两个tab,分别是百度和搜狗。
在百度tab页下执行一个脚本时会先检查该脚本是哪个网页的,只有同源才会被执行。
selenium2.0
- selenium2.0 = selenium1.0 +webdriver selenium2.0的webdriver是selenium
RC的代替品,但是并没有完全抛弃selenium RC。
利用的原理:
- 将浏览器原生的api封装成webdriver api,直接控制浏览器。
webdriver的工作原理:
webdriver是典型的client-server模式
- 使用selenium2.0启动浏览器时,后台也同时将基于webdriver wire协议的web service作为web server,并将浏览器绑定到特定端口;
- 测试脚本作为client,将需要执行的页面操作以http请求发送给web server,其中http请求的body,是以webdriver wire协议的Json格式的字符串告诉浏览器接下来的操作;
- web server解析请求,并将请求结果发送给webdriver;
- 由于webdriver封装了浏览器原生的api,所以可以直接控制浏览器。
selenium3.0
- 增加了edge和Safari原生的驱动,且彻底抛弃selenium RC。
二、web端的UI自动化测试
1、自动化测试框架:
selenium-webdriver
2、windows下的测试环境搭建:
python3.7.3 + selenium3.14 + chrome69+ chromedriver2.37 +win10
课外小知识:
- Pycharm是python的IDE之一(集成开发环境),也就是编辑器
- anaconda是一个开源的python发行版本,其包含python和python的第三方库
- selenium是一个用于web应用程序的自动化测试工具
(1)安装python,安装anaconda也就安装了python,并且把python安装目录添加到系统环境变量的path;
anaconda安装教程:https://blog.csdn.net/ITLearnHall/article/details/81708148
(2)安装selenium,如果是pycharm,在python安装目录D:\pycharm\Anaconda3_2018.12\Scripts下执行pip install selenium;
pycharm安装教程:https://www.cnblogs.com/dcpeng/p/9031405.html
pycharm生成注册码:http://idea.lanyus.com/
(3)chrome.exe和chromedriver.exe两者的版本要适配,chromedriver.exe放在chrome.exe路径下,并且将chromedriver.exe的安装目录添加到系统环境变量的path。
(4)HTMLTestRunner.py放在python的lib文件中
3、gitlab项目管理
科普:
git是一个分布式版本管理系统,实现在线代码托管。
gitlab是在线代码托管平台。
步骤:
(1)git bash安装
- Windows下的Git安装:https://segmentfault.com/a/1190000011809698
(2)gitlab注册邮箱账号:https://gitlab.com/
(3)建立连接
- 本地git和gitlab服务器之间保持通信,是通过SSH KEY。
课外小知识: - sourcetree是开源git软件,是可视化界面工具,具有完整的git功能。
- fork是git客户端,在Windows中比sourcetree更友好。
sourcetree和Gitlab的连接步骤:
- sourcetree3.1.2版本以上:https://blog.csdn.net/robin_sky/article/details/89059084
或者
fork和gitlab的连接:
- file—configure ssh keys
- generate new SSH key,key file name输入id_rsa,邮箱输入gitlab注册的邮箱,即可生成秘钥
- 在gitlab的profile settings 的SSH keys点击add ssh key,将上一步生成的秘钥复制到gitlab
(4)gitlab new project , fork clone 文件到本地,本地会同时生成该文件夹
4、持续集成jenkins构建
课外小知识:
- 持续集成:持续集成是一种软件开发实践,即开发人员经常集成他们的工作。
- Jenkins 是基于 Java 开发的一种持续集成工具。
- Tomcat 是针对 Java 的一个开源中间件服务器(容器),基于 Java Web 的项目需要借助 Tomcat 才能运行起来。
环境搭建:
java环境+tomcat+jenkins
5、自动化测试项目架构:
- web:用于存放社区web项目的测试用例web_case、测试报告report
- report:创建用于存放测试报告.html
- package:用于存放自动化所用到的扩展包,如HTMLTestRunner.py
- web_case:测试用例目录,用于存放测试用例*web_.py、公共模块models、页面对象page_obj
- web_runtest.py:项目主程序。用于运行社区web自动化测试用例
- web文档:项目结构介绍和使用说明
三、自动化测试项目实战
1、项目是否适合自动化测试
(1)项目已有的模块功能基本稳定,UI界面没有大的改动,项目在开发新的模块,新的功能
(2)项目版本迭代频繁,每次发版时都需要进行冒烟测试,很耗时耗力。
2、自动化用例设计
(1)不是所有的手工用例都要转换为自动化测试用例。
(2)流程太复杂,难以用脚本实现自动化的用例,不建议开发。
(3)用例要有目的性,比如用作回归测试、冒烟测试。
(4)可以选取重复执行,烦琐的用例,可以让测试人员从重复烦琐的测试解脱。
课外小知识
- 回归测试:修改代码后验证Bug已修改并且没有引入新的错误。
- 冒烟测试:新的版本发布前要验证保证项目的基本功能没问题。
3、自动化测试用例编写原则
(1)一个用例为一个完整的场景,从用户登录到关闭浏览器。
但是,用例达到上百个甚至更多时,可以只登录一次,再执行上百个用例,最后再关闭浏览器。这样可以节省时间。
(2)一个用例只验证一个功能点。比如,用例1验证用户登录密码为空,用例2验证用户登录用户名为空。
(3)用例与用例之间尽量避免依赖。能做到最好,做不到也没关系。比如,编辑功能和删除功能总是依赖新增功能。
(4)一个用例完成测试之后需要对测试场景进行还原,以免影响其他用例的执行。比如搜索功能,搜索关键词后要清空搜索框的内容
4、采用Page Object设计模式
- 实现对界面细节的封装,将业务和界面细节分开来。
优点:
- 减少代码的重复。因为多个用例会重复定位某个元素
- 提高测试用例的可读性。
- 提高测试用例的可维护性。
5、Unittest单元测试框架
在web自动化测试中的作用:
- 组织和执行用例
- 提供断言方法,用例执行完后将实际结果与预期结果进行比较(断言)
- 提供丰富的日志:用例执行失败时抛出原因,以及执行结果:失败用例数、成功用例数
课外小知识:
- 单元测试的定义:负责对最小的软件设计单元进行验证,根据软件设计文档对重要的程序分支进行测试以发现模块中的错误
(1)组织和执行用例
- setUp,tearDown:是对每一个用例的初始化和用例执行完成后的清理工作,一般用来关闭浏览器;
在多个用例中,如果某个用例的元素定位或者其他出错,会阻止用例的继续运行。 - setUpClass,tearDownClass:是在执行用例之前初始化一遍,所有的用例执行完后再进行清理工作,
并且在setUpClass和tearDownClass的上面添加@classmethod装饰器,如果某个用例的元素定位或者其他出错,
不影响整个用例的执行工作;这样也许会更好一些,不用每次都去重新打开浏览器,节省测试时间,
但要注意的是不要忽略了用例之间的相互影响,所以用这种模式要考虑到用例之前的耦合, 尽可能不要让前个用例的测试环境影响后一个用例的执行。
web_init.py的代码:
- 执行所有测试用例的前置条件、后置条件
- 启动浏览器
#继承unittest模块的TestCase类,TestCase类是对特定类进行测试的集合
class MyTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
options=Options()
#设置chrome浏览器无界面模式
options.add_argument('window-size=1600x746')#指定浏览器全屏
options.add_argument('--headless')#浏览器不提供可视化页面
cls.driver = webdriver.Chrome(
executable_path="C:/Users/xiehuagui/AppData/Local/Google/Chrome/Application/chromedriver.exe",options=options)
@classmethod
def tearDownClass(cls):
cls.driver.quit()
- discover:查找并执行测试用例
runtest.py的代码: - 查找测试目录(zhsq_dir)中('test*.py)开头的测试用例文件并执行
import unittest
import os
#获取当前工作路径,并且把双斜杆换成反斜杆
home_dir = str(os.getcwd()).replace("\\", "/")
zhsq_dir = home_dir + '/test_case'
discover = unittest.defaultTestLoader.discover(zhsq_dir, pattern='test*.py')
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(discover)
- main()方法
main()方法是unittest提供的全局方法,可以使模块直接运行
main()方法提供TestLoader类搜索“test”开头的测试方法,并自动执行它们。
课外小知识:
.py文件有两种使用方法:作为模块被调用和直接使用。
if name ==“main”:
name 是模块的内置属性,当__name__ =="main"时表示模块直接使用
if __name__ =="__main__":
unittest.main()
- 用例的执行顺序
unittest框架默认根据ASCII码的顺序加载测试用例,顺序为:0-9,A-Z,a-z。对于测试目录和测试文件也是这样。
测试目录的命名:
测试用例的命名:
class SysOrggan(web_init.MyTest):
'''系统管理--组织管理'''
#@unittest.skip("跳过")
def test_01org_add(self):
'''新增功能'''
...
def test_02org_edit(self):
'''编辑功能'''
...
def test_03org_del(self):
'''删除功能'''
...
(2)提供断言方法
assertEqual(a,b):检查a=b
assertNotEqual(a,b):检查a!=b
self.assertEqual(tree_num2,tree_num1-1, msg="删除失败")
(3)提供日志
四、实现自动化的细节,跟代码有关
1、在网友分享的测试报告基础上,优化HTML测试报告
2、返回用例状态码给Jenkins,一旦用例不通过就触发Jenkins自动发邮件
def is_result_pass():
try:
fp = open(filename, "r" , encoding="UTF-8")
# 读报告
f = fp.read()
soup = BeautifulSoup(f, "html.parser")
status = soup.find_all(class_="attribute")
# 获取报告结果
result = status[3].contents[-1]
if "错误" in result or "失败" in result:
exit(1)
else:
exit(0)
except Exception as msg:
print("判断过程出现异常:%s"%str(msg))
return False
代码解析:可以通过html测试报告中的测试结果来判断用例是否通过,根据class_="attribute"定位,status[3]就是测试结果,测试结果有两行内容,contents[-1]表示最后一行内容。如果“错误”和“失败”不为0,则返回exit(1)给jenkins,就会触发jenkins发邮件。
3、元素的定位
(1)Xpath定位:
- 对于模块位置容易改变的项目,不建议使用绝对路径定位
button_loc = (By.XPATH,‘//*[@id="main"]/div/div[1]/div/ul/div[1]/li/ul/div[1]/li/span’)
- 可以利用元素属性定位
root_add_button_loc = (By.XPATH,'//*[@id="WY-0-add"]')
(2)CSS定位
- 组合定位
点号(.):class属性
#号(#):id属性
大于号(>):div>input:父子关系
加号(+):div+input:兄弟关系
空格( ):div input:div的所有input元素,包括子元素,孙元素,曾孙元素…
xq_node_loc = (By.CSS_SELECTOR,"span#arrow-2+div div.tree-node-title")
(3)调用JS定位元素
- webdriver提供了execute_script()方法执行JS代码。
js_root_add_xq = "document.getElementById('WY-0-addXQ').click()"
driver.execute_script(js_root_add_xq)
(4)如果以上都无法定位,测试人员就自己手动给元素加id等属性
参考文献:
1、selenium1.0 和2.0介绍:https://www.cnblogs.com/ZoeLiang/p/10746787.html
2、虫师,selenium2自动化测试实战基于python语音(书籍)