UI 跑业务场景
接口自动化
单元自动化
Day12-Selenium自动化测试
1. 什么是自动化测试
让程序代替人为去验证程序功能的过程
自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程。
2. 为什么要进行自动化测试
1、解决回归测试
2、解决压力测试
3、解决兼容测试
4、提高测试效率,保证产品质量
3. 自动化测试所属分类
- 黑盒测试(功能测试)
- 灰盒测试(接口测试)
- 白盒测试(单元测试)
注意:Web自动化测试属于黑盒测试(功能测试)
4. 自动化测试优缺点
4.1. 优点
- 以较少时间运行更多的测试用例
- 自动化脚本可重复使用
- 减少人为的错误
- 测试数据存储
- 不能取代手工测试
- 手工测试比自动化测试发现的缺陷多,实际测试里边,手工bug 80%,自动化工具 20% (性能和功能)
- 测试人员技能要求,要懂编码
4.2. 缺点
5. 自动化测试过程
自动化测试与软件开发过程从本质上来讲是一样的,无非是利用自动化测试工具(相当于软件开发工具),经过对测试需求的分析(软件过程中的需求分析),设计出自动化测试用例(软件过程中的需求规格),从而搭建自动化测试的框架(软件过程中的概要设计),设计与编写自动化脚本(详细设计与编码),测试脚本的正确性,从而完成该套测试脚本(即主要功能为测试的应用软件)。
1) 自动化测试需求分析。
当测试项目满足了自动化的前提条件,并确定在该项目中需要使用自动化测试时,我们便开始进行自动化测试需求分析。此过程需要确定自动化测试的范围以及相应的测试用例、测试数据,并形成详细的文档,以便于自动化测试框架的建立。
2)自动化测试框架的搭建。
所谓自动化测试框架便是像软件架构一般,定义了在使用该套脚本时需要调用哪些文件、结构,调用的过程,以及文件结构如何划分。
而根据自动化测试用例,我们很容易能够定位出自动化测试框架的典型要素:
a. 公用的对象。
不同的测试用例会有一些相同的对象被重复使用,比如窗口、按钮、页面等。这些公用的对象可被抽取出来,在编写脚本时随时调用。当这些对象的属性因为需求的变更而改变时,只需要修改该对象属性即可,而无需修改所有相关的测试脚本。
b. 公用的环境。
各测试用例也会用到相同的测试环境,将该测试环境独立封装,在各个测试用例中灵活调用,也能增强脚本的可维护性。
c. 公用的方法。
当测试工具没有需要的方法时,而该方法又会被经常使用,我们便需要自己编写该方法,以方便脚本的调用。
d. 测试数据。
也许一个测试用例需要执行很多个测试数据,我们便可将测试数据放在一个独立的文件中,由测试脚本执行到该用例时读取数据文件,从而达到数据覆盖的目的。
在该框架中需要将这些典型要素考虑进去,在测试用例中抽取出公用的元素放入已定义的文件,设定好调用的过程。
6. 自动化测试分类
- Web—(ui)自动化测试
- 接口自动化测试
- 移动(app)自动化测试
- 单元测试—自动化测试
7. 什么是Web自动化测试
让程序代替人为去验证web项目功能的过程
8. 什么web项目适合自动化测试
1) 需求变动不频繁
测试脚本的稳定性决定了自动化测试的维护成本。如果软件需求变动过于频繁,测试人员需要根据变动的需求来更新测试用例以及相关的测试脚本,而脚本的维护本身就是一个代码开发的过程,需要修改、调试,必要的时候还要修改自动化测试的框架,如果所花费的成本不低于利用其节省的测试成本,那么自动化测试便是失败的。
项目中的某些模块相对稳定,而某些模块需求变动性很大。我们便可对相对稳定的模块进行自动化测试,而变动较大的仍是用手工测试
2) 项目周期足够长
自动化测试需求的确定、自动化测试框架的设计、测试脚本的编写与调试均需要相当长的时间来完成,这样的过程本身就是一个测试软件的开发过程,需要较长的时间来完成。如果项目的周期比较短,没有足够的时间去支持这样一个过程,那么自动化测试便成为笑谈。
3) 自动化测试脚本可重复使用(项目需要回归测试)
如果费尽心思开发了一套近乎完美的自动化测试脚本,但是脚本的重复使用率很低,致使其间所耗费的成本大于所创造的经济价值,自动化测试便成为了测试人员的练手之作,而并非是真正可产生效益的测试手段了。
另外,在手工测试无法完成,需要投入大量时间与人力时也需要考虑引入自动化测试。比如性能测试、配置测试、大数据量输入测试等。
9. 主流测试工具
Web自动化测试工具:selenium、QTP(全名HP QuickTest Professional software ), Robot Framework功能自动化测试框架
性能自动化测试工具:loadrunner、jmeter。
接口自动化测试工具:SoapUI、postman,jmeter,restclient
移动(app)自动化测试工具:robotium(Android自动化测试框架)、appium。monkey(压力测试,随机测试工具)、monkeyrunner
云测平台:testin
10. 功能测试工具Selenium简介
10.1. Selenium是什么
***** python中核心库有哪些说出常用的5个:
https://blog.csdn.net/alice_tl/article/details/89815949?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~first_rank_v2~rank_v28-1-89815949.nonecase&utm_term=python%E5%B8%B8%E7%94%A8%E5%BA%93%E6%9C%89%E5%93%AA%E4%BA%9B&spm=1000.2123.3001.4430
Selenium是一款基于web应用程序的开源测试工具。
Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。
它支持Firefox、ie等众多浏览器。
它同时支持JAVA、C#、Ruby、Python、PHP、Perl等众多的主流语言。
Java+selenium
Python+selenium
Selenium原理/机制
https://blog.csdn.net/lemo_ice/article/details/102852147
https://blog.csdn.net/p312011150/article/details/80672703
10.2. Selenium特点
开源、跨平台,运行在浏览器中
简单灵活、支持很多种语言
11. Selenium 核心组件
Selenium Core:支持DHTML 的测试案例(效果类似数据驱动测试),它是Selenium IDE 和Selenium RC的引擎
Selenium IDE 是一个Firefox 浏览器的一个插件,可以实现对浏览器的简单操作的录制与回放功能。一般用于测试人员在测试过程中发现bug,通过Selenium IDE 将重测试骤录制下来,快速创建了bug 重现脚本,从而供开发人员容易重现bug。IDE 除了录制回放外还可以导出录制的脚本,并导出成多种语言,不同版本的Selenium 脚本,供测试人员快速开发脚本。
Selenium RC:Selenium Remote Control。Selenium RC 使用的是javascript注入的方式跟浏览器打交道。这样 Selenium RC 需要启动一个Server,然后将操作页面元素的API 转成javascript脚本,再把这段脚本注入到浏览器中去执行。而通过这种javascript注入的方式一来太依赖翻译成javascript质量的好坏,二来javascript存在同源问题。这使测试变得不那么容易。
Selenium Grid:允许同时并行地、在不同的环境上运行多个测试任务,极大地加快Web 应用的功能测试。
12. Selenium 脚本环境配置
12.1. 安装最新版本的火狐浏览器到c盘
12.2. 配置火狐浏览器的系统环境变量到path
12.3. 将geckodriver放到火狐(最新版本)下边
12.4. 在python的Scripts文件夹下边,在线下载selenium的库
1、python中pip是用来安装python第三方库的工具。
2、安装 pip install -U selenium
3、卸载 pip unstall selenium
4、查看 pip show selenium
12.5. 打开PyCharm,查看selenium是否安装成功
13. Selenium IDE安装配置
13.1. 安装Firefox 浏览器
傻瓜式安装
13.2. 安装Selenium
打开火狐组件
选择本地安装文件
13.3. 显示菜单栏
13.4. 查看工具栏-如果安装不上,请多试几次
13.5. 安装成功
command:表示要进行打开点击操作所要执行的命令。
1、open:顾名思义,打开指定的url、 www.baidu.com
2、clickAndWait:命令,表示进行点击操作、其中有AndWait表示页面需要进行刷新、
3、type:设置输入关键字 美女
target:执行命令的对象。需要找到link才可以执行 clickAndWait操作。
其中target:是按照css或者Xpath的语法在页面寻找到对应元素。
1、指的是你当前录制时的开始连接地址。
2、这里就是你的测试用例,刚开始录制好之后都是没有命名的。
3、脚本命令内容,command:方法关键字;Target:元素定位;Value:参数。
4、新建和修改脚本的地方。
5、日志输出。
6、右上角的红色圆,空心的时候表示的正在录制,实心表示录制结束。
五、录制第一个脚本,打开www.baidu.com,再输入框输入Selenium,点击百度一下按钮。我们只需要打开seleniumIDE,然后在Firefox中操作以上步骤,之后打开seleniumIDE关闭录制按钮,生成脚本。
14. Selenium执行流程演示
14.1. 录制过程
14.2. 将资料中ptest拷贝到tomcat下的webapp下,启动tomcat
如果tomcat启动不成功,9成是jdk出问题
环境变量重新配置
JAVA_HOME C:\java
%JAVA_HOME%\bin;
14.3. 在PyCharm中创建测试项目
14.4. 使用selenium IDE进行录制
火狐浏览器打开:http://localhost:8081/ptest/regist.jsp
录制结束,停止
打开某一个,看参数变量,变量值
Target目标,value值,
14.5. 导出测试用例
14.6. 导出测试用例文件
14.7. 导入到pyCharm中
复制loginTest1.py文件,粘贴到python中
代码很多,简要分析下:
1、setup()里面大部分熟悉,不过有些还是第一次见:
self.verificationErrors = [] #脚本运行时,错误的信息将被打印到这个列表中。
self.accept_next_alert = True #是否继续接受下一下警告
2、teardown()下的代码:self.assertEqual([], self.verificationErrors) 是个难点,对前面verificationErrors方法获得的列表进行比较;如查verificationErrors的列表不为空,输出列表中的报错信息。这个东西,也可以将来被你自己更好的调用和使用,根据自己的需要写入你希望的信息。
14.8. 执行测试
15. 什么是WebDriver
WebDriver 提供一套更加面向对象,更易于使用的API,同时更容易操作浏览器和页面元素。所以现在我们学习Senlium 时更加推荐学习WebDriver。
16. Selenium WebDriver查找页面元素及元素操作
16.1. 元素常用定位方法
Id name classname xpath
- 通过id定位元素:find_element_by_id("id_vaule")
- 通过name定位元素:find_element_by_name("name_vaule")
- 通过tag_name定位元素:find_element_by_tag_name("tag_name_vaule")
- 通过class_name定位元素:find_element_by_class_name("class_name")
- 通过css定位元素:find_element_by_css_selector();用css定位是比较灵活的
- 通过xpath定位元素:find_element_by_xpath("xpath")
- 通过link_text定位:driver.find_element_by_link_text("新闻").click()
- 通过partial link_text 定位:driver.find_element_by_partial_link_text("闻").click()
- Id,name,class name:为元素属性定位
- tag_name:为元素标签
- link text 、partial link text:为超链接定位(a标签)
- Xpath:为元素路径
- Css :为css元素选择器定位
- Firebug是firefox下的一个扩展,能够调试所有网站语言,如Html,Css等,但FireBug最吸引人的就是javascript调试功能,使用起来非常方便,而且在各种浏览器下都能使用,是一整套完整而强大的 WEB开发工具。
- FirePath是一个Firebug扩展,它添加了一个开发工具来编辑、检查和生成XPath 1.0表达式、CSS 3选择器和JQuery选择器。
- Firefinder是Firebug的一个附加组件,它可以帮助找到匹配选定的CSS选择器(s)或XPath表达式的HTML元素。你也可以在悬停或通过上下文菜单时自动选择元素。
查看结果,然后通过friendfire特性与朋友分享,或者点击检查,在Firebug的HTML选项卡中找到对应的元素。
16.2. 定位分类总结
16.3. 安装fireBug和firePath,firefinder
打开附加组件,搜索firebug,firefinder,firepath依次安装
16.4. 定位元素
下面是百度输入框的html代码,可以通过firebug或者谷歌的审查元素得:
<input id="kw" class="s_ipt" autocomplete="off" maxlength="255" value="" name="wd">
16.4.1. 通过id定位:
则百度的输入框即可表示为:find_element_by_id(“kw1”)
16.4.2. 通过name定位:
则可以表示为:find_element_by_name(“wd”)
16.4.3. 通过class_name定位元素:
driver.find_element_by_class_name("s_ipt")
16.4.4. 通过tag_name定位:
input其实就是tag_name(标签名),
同样也可以表示成:find_element_by_tag_name("input")
返回:符合条件的第一个标签
可见仅仅通过标签名去定位时,一般一种标签在一个页面里面会出现不止一次甚至大量出现,这种定位方式的作用不是很大,所以用的也就比较少
16.4.5. 通过css定位元素:
Id>类选择器>标签选择器
cssSelector这种元素定位方式跟xpath比较类似,但执行速度较快,而且各种浏览器对它的支持都相当到位
一般class是用.标记,id是用#标记,标签名直接写具体标签名就好
find_element_by_css_selector("#su")
find_element_by_css_selector(".s_ipt")
find_element_by_css_selector("[name=wd]")
16.4.6. 通过xpath定位元素:
XPath是一种在XML文档中定位元素的语言。因为HTML可以看做XML的一种实现,所以selenium用户可是使用这种强大语言在web应用中定位元素。
XPATH的值可以通过firebug或者谷歌的审查元素中:
右键功能:复制XPATH即可获得。
例子:
driver.find_element_by_xpath(".//input[@id='kw']")
driver.find_element_by_xpath(".//*[@id='kw']")
其中的标签名input也可以用*来代替,而且只要是在该标签内,任意属性都可以
16.4.7. 通过link_text、partial_link_text定位:
这两种定位方式是专门用于定位超链接的,也就是对应html页面中的<a>标签,括号里传的值就是a标签中的超链接文字,两者的区别在于一个是完整的超链接文字,一个是可以只写部分超链接文字。
比如点击百度首页中右上角的新闻超链接,可以这样去定位:
driver.find_element_by_link_text("新闻").click()
driver.find_element_by_partial_link_text("闻").click()
鼠标事件和键盘事件
https://www.cnblogs.com/mashuqi/p/10442150.html
16.5. elements复数定位
在上面的例举的八中基本定位方式种,都有对应的复数形式,分别是下面:
id复数定位find_elements_by_id()
name复数定位find_elements_by_name()
这些复数定位方式每次取到的都是具有相同类型属性的一组元素,所以返回的是一个list队列,我们也可以利用这个去定位单个的元素。比如百度首页种,右上角有新闻、视频、地图、贴吧等一些链接,我们通过f12查看源码可以发现,这些链接都有共同的class, class="mnav"。
举个例子,比如定位排在第六个的学术,可以这样定位:driver.find_elements_by_class_name("mnav")[5].click()
总结
1. 当页面元素有id属性时,最好尽量用id来定位。但由于现实项目中很多程序员其实写的代码并不规范,会缺少很多标准属性,这时就只有选择其他定位方法。
2. xpath很强悍,但定位性能不是很好,所以还是尽量少用。如果确实少数元素不好定位,可以选择xpath或cssSelector。
3. 当要定位一组元素相同元素时,可以考虑用tagName或name。
4. 当有链接需要定位时,可以考虑linkText或partialLinkText方式。
16.6. 简单元素操作
clear()清除文本
send_keys(*value) 模拟按键输入
click()单击元素
size 返回元素的尺寸
text 获取元素的文本
get_attribute(name)获取属性值
is_displayed()设置该元素是否可见 判断元素是否可见 是否可用 is_enable() 了解
selenium.common.exceptions.StaleElementReferenceException: Message: The element reference of <a class="mnav" href="http://news.baidu.com" name="tj_trnews"> is stale; either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed
17. 键盘事件---(了解)
send_keys()模拟键盘输入 from selenium.webdriver.common.keys import Keys
send_keys(Keys.BACK_SPACE) 删除键 * send_keys(Keys.SPACE) 空格键(Space) * send_keys(Keys.TAB) 制表键(Tab) * send_keys(Keys.ESCAPE) 回退键(Esc) * send_keys(Keys.ENTER) 回车键(Enter) * send_keys(Keys.CONTROL,'a') 全选(Ctrl+A) * send_keys(Keys.CONTROL,'c') 复制(Ctrl+C) * send_keys(Keys.CONTROL,'x') 剪切(Ctrl+X) * send_keys(Keys.CONTROL,'v') 粘贴(Ctrl+V) * send_keys(Keys.F1) 键盘 F1 …… * send_keys(Keys.F12) 键盘 F12 |
18. 设置元素等待
Selenium显示等待和隐式等待的区别 |
18.1. 显式等待
element=WebDriverWait(driver,timeout, poll_frequency=0.5,ignored_exceptions=None).until( EC.presence_of_element_located((By.ID, "kw")) ) driver 浏览器驱动 timeout 最长超时时间 默认以秒为单位 poll_frequency=0.5 步长 ignored_exceptions 超时后的异常信息 默认抛noSuchElementException EC.presence_of_element_located((By.ID, "kw")) 判断元素是否被加载在dom树中,不代表他一定可见。 |
18.2. 隐式等待
含义:通过一定时长等待,如果超出设置的时长元素还没有被加载,抛出NosuchException. # 设置隐式等待为 10 秒 driver.implicitly_wait(10) |
18.3. sleep休眠方法
Time.sleep(1) |
19. 浏览器的基本操作
选择浏览器: driver = webdriver.Firefox()
打开url: driver.get(self.base_url + " www.baidu.com")
前进/后退: driver.forward()/driver.back()
刷新: driver.refresh()
最大化:browser.maximize_window()
返回当前页面标题:print(driver.title)
返回当前页面url:print(driver.current_url)
返回当前浏览器的所有窗口:driver.window_handles
返回当前浏览器的窗口句柄:driver.current_window_handle
选择窗口: driver.switch_to_window(“window_name”)
对话框操作: driver.switch_to_alert() #选择窗口对象
#浏览器最大化
driver.maximize_window()
#设置浏览区宽高
driver.set_window_size(480, 800)
截取当前页面: driver.get_screenshot_as_file("C:/Users/Administrator/Desktop/selenium/baidu.png")
关闭浏览器: driver.quit()/driver.close()
19.1. 生成HTML测试报告
19.1.1. 拷贝HTMLTestRunner.py到当前项目
19.2. 新建一个py类
if __name__ == '__main__':
|
19.3. 将生成报告通过邮件发送到指定人员邮箱
19.3.1. 开启邮箱的授权密码
导入工具类,执行代码
注意:
1、关于导包,在方法体中 alt+enter实现导包
2、密码是 授权密码
3、关于路径,不要复制粘贴,注意\\
4、可以设置多个接收邮箱地址
5、注意书写过程,中英文字符不要出错
20. 注册登录优化
def test_loginn(self):
login = open("csv.txt", "r", encoding="gbk")
for lo in login.readlines():
name = lo.split(",")
login.close()
driver = self.driver
driver.get(self.base_url + "/ptest/regist.jsp")
driver.find_element_by_id("username").clear()
driver.find_element_by_id("username").send_keys(name[0])
driver.find_element_by_name("password").clear()
driver.find_element_by_name("password").send_keys(name[1])
# driver.find_element_by_name("phone").clear()
# driver.find_element_by_name("phone").send_keys("123")
# driver.find_element_by_name("phone").clear()
# driver.find_element_by_name("phone").send_keys("123789")
# driver.find_element_by_id("email").clear()
# driver.find_element_by_id("email").send_keys("1234567@qq.com")
driver.find_element_by_xpath(".//*[@id='email']").clear()
driver.find_element_by_xpath(".//*[@id='email']").send_keys(name[3])
driver.find_element_by_css_selector("input[type=\"submit\"]").click()
p = driver.find_element_by_xpath("html/body/p").text
try:
self.assertEqual(p,"注册成功")
except:
print("注册失败了")
else:
driver.find_element_by_link_text(u"登录").click()
driver.find_element_by_id("username").clear()
driver.find_element_by_id("username").send_keys("zhangsan")
driver.find_element_by_id("password").clear()
driver.find_element_by_id("password").send_keys("123")
driver.find_element_by_css_selector("input[type=\"submit\"]").click()