什么是自动化测试?
在**预设条件下(自动化脚本)**运行系统,预设的条件包括正常和异常的情况,不需要手工的干涉,机器就可以执行。
自动化测试的优势?
降低大型系统由于变更引起的大量的回归测试的人力投入。特别是代码更改频繁时,效果明显,自动化测试前期投入人力多,但进入维护期后,节省大量人力。
- 减少重复测试的时间,快速回归测试;
- 测试过程可靠,减少人为失误;
- 可以进行更多更繁琐的测试;
- 执行一些手工测试困难,或者不可能进行的测试;
- 节省人力资源,更好的利用资源;
- 测试具有一致性和重复性;
- 测试脚本的重用性;
自动化测试的价值:脚本的复用率高,复用率越高,价值越大;
自动化测试方法
测试对象:UI、接口、代码;
测试过程:系统测试、集成测试、单元测试;
执行人员:测试人员、开发人员;
- 自动化测试可以在整个测试过程中任何一个阶段实施,前提:功能相对稳定;
UI自动化
对系统的界面元素进行操作,用脚本实现模拟用户的使用,完成功能的正常和异常测试;
- 测试时间段:项目后期,项目完成前后端的开发和联调后;
- 用例维护量大;
- 适合的项目:适合界面元素变动小的项目;
接口自动化
- 测试时间段:项目前期接口开发完成开始进行测试;
- 用力维护量少;
- 适合的项目:适合接口变动较少的项目;
自动化框架和自动化工具的区别
自动化测试框架可以分为两个层次:
- 上层管理整个自动化测试的开发执行维护,包括自动化测试用例的执行的次序,测试脚本的维护,集中管理测试用例,测试报告测试任务;
- 下层主要是测试脚本的开发,充分的使用相关的测试工具,构建测试驱动,并完成测试业务逻辑;
为什么选的selenium?
- 免费;
- 小巧;
- 支持多种语言:Java C python;
- 支持多种浏览器平台:chrome FireFox Edge;
- 支持分布式测试用例的执行:当测试用例比较多的时候,把测试用例分布到不同的测试机器执行;(需要配置环境 selenium Grid)
支持多浏览器多平台的好处? 进行兼容性测试;
selenium
Selenium是ThroughtWorks公司一个强大的开源Web功能测试工具系列,支持多平台、多浏览器、多语言去实现自动化测试,Selenium2将浏览器原生的API封装成WebDriver API,可以直接操作浏览器页面里的元素,甚至操作浏览器本身(截屏,窗口大小,启动,关闭,安装插件,配置证书之类的),所以就像真正的用户在操作一样。
WebDriver工作原理
- 启动浏览器,WebDriver把浏览器绑定到一个端口,这个端口就是浏览器的remote server;
- 客户端(测试脚本)通过ComandExecutor,向浏览器发生HTTP请求,控制浏览器进行一系列操作;
- 浏览器驱动把指令解析成web service的命令,转换成浏览器的native指令,操作浏览器进行一系列的操作;
selenium IDE录制脚本
FireFox:
配置驱动
谷歌:
https://chromedriver.storage.googleapis.com/index.html
火狐:
https://github.com/mozilla/geckodriver/releases/download/
安装pychram
PyCharm:JetBrains为专业开发者提供的Python IDE
脚本编写
脚本解析:
coding = utf-8
导包,使用selenium 的webdriver 里的函数:
from selenium import webdriver
需要控制哪个浏览器:
browser = webdriver.Firefox()
用id定位控件,输入搜索内容"你好":
browser.find_element_by_id("kw").send_keys("你好")
点击id叫su的按钮:
browser.find_element_by_id("su").click()
退出并关闭窗口的每一个相关的驱动程序:
browser.quit()
关闭当前窗口:
bash
browser.close()
close方法关闭当前的浏览器窗口,quit方法不仅关闭窗口,还会彻底的退出webdriver,释放与driver server之间的连接。所以简单来说quit是更加彻底的close,quit会更好的释放资源。
定位元素
定位对象在自动化测试中很重要,要操作一个对象,首先要时别这个对象。不论用哪种方式定位对象,必须保证页面上该属性是唯一的。
- id :如果元素有id,那id一定是全局唯一的;
- name :name不一定全局唯一
- class name:类属性;
- partial link text:部分链接内容,且链接内容全局唯一
- link text:链接内容,且链接内容全局唯一
- tag name:元素标签;
- xpath:每一个元素都有xpath的定位方式,通过xpath定位肯定全局唯一定位一个元素;APP的元素定位都是用的xpath;
- css selector;
以上所有属性,必须存在且全局唯一才可以定位到。
操作测试对象
定位元素后,对元素进行操作。操作对象的方法:
- send_keys():向元素发送信息
- click():点击元素
- submit():提交表单,清除对象的内容
- text():获取元素的内容
- clear():清除元素的内容
添加等待
固定等待:
import time time.sleep(3)
隐式等待(智能等待):
browser.implicitly_wait(3)
文档解释:
selenium.webdriver.remote.webdriver.implicitly_wait(time_to_wait)
隐式地等待一个无素被发现或一个命令完成;这个方法每次会话只需要调用一次time_to_wait: 等待时间
- 比如在网页搜索一个东西,它还没加载出来,脚本就开始执行下一条语句,这个时候就会报错,所以就得加个等待时间,等待页面加载出来,再去执行下面的脚本。固定等待只能选择一个固定的时间等待,智能等待在一个时间范围内智能等待。
打印信息
print driver.title # 把页面title 打印出来
print driver.current_url #打印url
打印结果在脚本运行的执行结果的地方看见。
浏览器操作
调用启动浏览器时,不一定是全屏,将浏览器窗口最大化:
浏览器最大化:
browser.maximize_window() #将浏览器最大化
设置浏览器宽、高:
browser.set_window_size(480, 800) #(宽,高)
浏览器前进、后退:
browser.forward() #前进 browser.back() #后退 #coding=utf-8 from selenium import webdriver import time browser = webdriver.Chrome() #访问百度首页 first_url= 'http://www.baidu.com' print "now access %s" %(first_url) browser.get(first_url) time.sleep(2) #访问新闻页面 second_url='http://news.baidu.com' print "now access %s" %(second_url) browser.get(second_url) time.sleep(2) #返回(后退)到百度首页 print "back to %s "%(first_url) browser.back() time.sleep(1) #前进到新闻页 print "forward to %s"%(second_url) browser.forward() time.sleep(2) browser.quit()
浏览器滚动条:
#将页面滚动条拖到底部 #一个js语句 ,scrollTop=10000 离最顶端有10000 js="var q=document.documentElement.scrollTop=10000" #执行js语句 driver.execute_script(js) time.sleep(3) #将滚动条移动到页面的顶部 #scrollTop=0 离最顶端有0 js="var q=document.documentElement.scrollTop=0" driver.execute_script(js execute_script(script, *args),在当前窗口/框架同步执行javaScript
键盘事件
使用键盘需要引入keys包:
from selenium.webdriver.common.keys import Keys
通过send_keys()调用按键:
send_keys(Keys.TAB) # TAB send_keys(Keys.ENTER) # 回车 #coding=utf-8 from selenium import webdriver from selenium.webdriver.common.keys import Keys #需要引入keys 包 import os,time driver = webdriver.Chrome() driver.get("http://demo.zentao.net/user-login-Lw==.html") time.sleep(3) driver.maximize_window() # 浏览器全屏显示 driver.find_element_by_id("account").clear() time.sleep(3) driver.find_element_by_id("account").send_keys("demo") time.sleep(3) #tab 的定位相当于清除了密码框的默认提示信息,等同上面的clear() driver.find_element_by_id("account").send_keys(Keys.TAB) time.sleep(3) #通过定位密码框,enter(回车)来代替登陆按钮 driver.find_element_by_name("password").send_keys(Keys.ENTER) #也可定位登陆按钮,通过enter(回车)代替click() driver.find_element_by_id("login").send_keys(Keys.ENTER) time.sleep(3) driver.quit()
键盘组合键(ctrl+A ctrl+C...):
导包:
from selenium.webdriver.common.keys import Keys #ctrl+a 全选输入框内容 driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a') time.sleep(3) #ctrl+x 剪切输入框内容 driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'x') time.sleep(3)
有的键盘操作,必须建立在定位元素的基础上。
鼠标事件
双击:
#定位一个元素 b=driver.find_element_by_id("su") #perform() 执行所有存储的行为 ActionChains(driver).double_click(b).perform()
右击:
b=driver.find_element_by_id("su") ActionChains(driver).double_click(b).perform()
定位一组元素
定位一组元素需要使用findElements方法。定位一组元素:比如要将页面的checkbox都勾选上。
如果是本地的HTML页面:HTML文件要和脚本在同一个目录下。
objectivecimport os os.path.abspath(文件的绝对路径)
获取文件路径:
file_path = "file:///" + os.path.abspath("D:\\Test\\checkbox.html") driver.get(file_path)
先定位出同一类元素(tag name,name class等),然后根据需要定位的元素的特征(type)筛选出具体元素,进行操作。
筛选出checkbox:
#coding=utf-8 from selenium import webdriver import time import os dr = webdriver.Chrome() file_path = 'file:///' + os.path.abspath('checkbox.html') dr.get(file_path) # 选择页面上所有的input,然后从中过滤出所有的checkbox 并勾选之 inputs = dr.find_elements_by_tag_name('input') for input in inputs: if input.get_attribute('type') == 'checkbox': #get_attribute:获得属性值 input.click() time.sleep(2) dr.quit()
多层框架、窗口的定位
iframe:框架里面嵌套框架;
解决不同层框架上的页面的元素的定位;