软件测试-4-自动化测试Selenium和浏览器调试信息

参考教程
本教程环境:
✔  windows 10
✔  Python:3.6.5
✔  selenium:3.13.0
知识储备:
✔  Python 基础
✔  前端基础(html、css、js)

1 Selenium介绍

官方文档:https://www.selenium.dev/documentation/en/
中文文档:https://selenium-python-zh.readthedocs.io/en/latest/index.html
github 主页:https://github.com/SeleniumHQ/selenium

Selenium是开源的自动化测试工具,它主要是用于Web应用程序的自动化测试,不只局限于此,同时支持所有基于web的管理任务自动化。

1.1 Selenium工具集

Selenium到目前为止经历了三个版本,本教程以最新的3.0版本为基础。
(1)Selenium IDE
IDE是一个Firefox插件,可以录制用户的基本操作并生成测试用例,然后可以运行这些测试用例在浏览器里回放,还可以将测试用例转换为其他语言的自动化脚本。

(2)WebDriver
Webdriver是Selenium的核心,它会在本地启动一套WebService服务并绑定一个动态端口,脚本运行时通过selenium将请求发送到Webdriver服务端,然后经过不同的浏览器驱动,转换为浏览器指令。

(3)Selenium Grid
用于将多个测试用例并行运行在不同浏览器、操作系统或机器上。可最大程度的运行兼容性测试,减少运行时间。

(4)特点
支持多种浏览器
支持多种语言
支持多种操作系统
开源免费

1.2 Selenium安装

(1)使用pip安装

CMD>pip install selenium
CMD>>pip show selenium
Version: 3.141.0

(2)安装浏览器驱动
下载driver

Chrome(对应 chromedriver):
http://chromedriver.storage.googleapis.com/index.html,
如果地址无法打开,可以在http://npm.taobao.org/mirrors搜索对应的driver下载。

Firefox(对应 geckodriver):
https://github.com/mozilla/geckodriver/releases

Edge(对应 edgedriver):
https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/

注意:下载 chromedriver 时一定要注意对应的chrome浏览器版本。
在这里插入图片描述
下载chromedriver_win32.zip
在这里插入图片描述

安装driver
将下载的driver驱动放在C:\Program Files (x86)\Google\Chrome\Application目录中。
谷歌浏览器目录。
在这里插入图片描述

CMD>chromedriver --help
CMD>chromedriver --version
ChromeDriver 96.0.4664.45

1.3 入门示例

配置好了Selenium环境就可以编写自动化代码了,
下面的代码将会打开chrome浏览器 -> 浏览百度页面 -> 关闭浏览器。

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
driver.find_element_by_id("kw").send_keys("test")
driver.quit()

编写一个简单的web自动化测试用例的顺序就是:
打开浏览器 -> 浏览网页 -> 操作元素 -> 关闭页面。

2 浏览器基础操作

2.1 启动浏览器

from selenium import webdriver

driver = webdriver.Chrome()
driver = webdriver.Firefox()
driver = webdriver.Edge()
driver = webdriver.Safari()
driver = webdriver.Opera()

2.2 打开关闭页面

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
# (法1)关闭所有页面,结束driver进程
driver.quit()   
# (法2)关闭当前页面,进入任务管理器查看后台进程中仍有chromedriver.exe
driver.close()   

2.3 窗口操作

import time
from selenium import webdriver

driver = webdriver.Chrome()
driver.get('http://www.baidu.com')

driver.minimize_window()    # 窗口最小化
driver.maximize_window()    # 窗口最大化
driver.set_window_size(800,600)    # 设置窗口大小
# 获取窗口大小,返回一个字典 {'width': 800, 'height': 600}
print("获取窗口大小:", driver.get_window_size())    
time.sleep(1)
driver.set_window_position(100, 100)    # 设置窗口位置
print("获取窗口位置:", driver.get_window_position())
time.sleep(1)
driver.set_window_rect(100, 100, 600, 400)  # 设置窗口位置和大小
print("获取窗口大小和位置", driver.get_window_rect())
time.sleep(1)
driver.quit()

注:设置窗口大小后可能会影响元素的可见性

2.4 前进后退刷新

import time
from selenium import webdriver

driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
driver.get('https://www.jd.com/')

time.sleep(1)
driver.back()       # 浏览器后退操作
time.sleep(1)
driver.forward()    # 浏览器前进操作
time.sleep(1)
driver.refresh()     # 网页刷新
time.sleep(1)

driver.quit()

注:浏览器执行前进、后退、刷新操作后一定要重新定位元素再进行操作。

2.5 页面元素截图

from selenium import webdriver

driver = webdriver.Chrome()
driver.maximize_window()

driver.get('http://www.baidu.com')
#页面截图,方法一
driver.get_screenshot_as_file("百度.png")

#页面截图,方法二,该方法内部就是调用的 get_screenshot_as_file
driver.save_screenshot("百度.png")   

# 单个元素截图
driver.find_element_by_id("su").screenshot("百度一下按钮.png")    

driver.quit()

2.6 获取浏览器信息

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
print("当前页面 url: %s" % driver.current_url)
print("当前页面 title:%s" % driver.title)
print("浏览器名称:%s" % driver.name)
# 获取浏览器所有信息,如 browserName,browserVersion 等
print("获取浏览器所有信息:%s" % driver.desired_capabilities)       
print("页面源代码:%s" % driver.page_source)

driver.quit()

2.7 获取当前窗口句柄

driver.window_handles # 获取所有窗口句柄
driver.current_window_handle  # 获取当前窗口句柄

2.8 打开关闭新的标签页

import time
from selenium import webdriver

driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
time.sleep(5)

# 打开新的标签页
js = 'window.open("https://www.jd.com")'
driver.execute_script(js)
time.sleep(5)
current_handles = driver.current_window_handle  # 获取当前窗口句柄
handles = driver.window_handles # 获取所有窗口句柄
driver.switch_to.window(handles[-1])  # 切换到新的标签页
driver.close()  # 关闭当前标签页
driver.switch_to.window(current_handles)  # 切换为原来的窗口句柄

time.sleep(1)
driver.quit()

注:打开新的标签页只能通过 js 来操作,可以根据不同的窗口句柄来切换标签页

3 浏览器调试

参考前端chrome浏览器调试总结
参考http请求加响应

3.1 开发者模式

3.1.1 箭头按钮

(1)箭头按钮
用于在页面选择一个元素来审查和查看它的相关信息,当我们在Elements这个按钮页面下点击某个Dom元素时,箭头按钮会变成选择状态。

(2)设备图标
点击它可以切换到不同的终端进行开发模式,移动端和pc端的一个切换,可以选择不同的移动终端设备,同时可以选择不同的尺寸比例,chrome浏览器的模拟移动设备和真实的设备相差不大,是非常好的选择。

(3)Element内容
用来查看,修改页面上的元素,包括DOM标签,以及css样式的查看,修改,还有相关盒模型的图形信息。
当鼠标选择元素时,右侧的css样式对应的会展示出此id的样式信息,此时可以在右侧进行一个修改,修改即可在页面上生效。

当浏览网站看到某些特别炫酷的效果和难做的样式时候,打开这个功能,即可看到别人是如何实现的。

3.1.2 console控制台

用于打印和输出相关的命令信息,其实console控制台除了熟知的报错,打印console.log信息外,还有很多相关的功能。

一些对页面数据的指令操作,比如打断点正好执行到获取的数据上,由于数据都是层层嵌套的对象,这个时候查看里面的key/value不是很方便。

此时就可以用这个指令查看,obj的json string 格式的key/value,对于数据里面有哪些字段和属性即可一目了然。
在这里插入图片描述
展开如下:
在这里插入图片描述

3.1.3 Sources

js资源页面,这个页面内我们可以找到当然浏览器页面中的js源文件,方便查看和调试,所有的代码都是压缩之后的。可以点击下面的{}大括号按钮将代码转成可读格式。

(1)Sinppets
比如当想不起某个方法的具体使用时候,会打开控制台随意写一些测试代码,或者想测试一下刚刚写的方法是否会出现期待的样子,但是控制台一打回车,本想换行但是却执行刚写的半截代码。

所以推荐使用Sources下面的左侧的Sinppets代码片段按钮,这时候点击创建一个新的片段文件,写完测试代码后把鼠标放在新建文件上run,再结合控制台查看相关信息。

新建了一个片段代码,在你的项目环境页面内,该片段可执行项目内的方法。

var a = ["A","B","C","D"]
console.log(a);

(2)Content scripts
Chrome 的一种扩展程序,它是按照扩展的ID来组织的,这些文件也是嵌入在页面中的资源,这类文件可以读写和操作我们的资源,需要调试这些扩展文件,则可以在这个目录下打开相关文件调试,但是几乎我们的项目还没有相关的扩展文件,所以啥也看不到,平时也不需要关心这块。

3.1.4 Network

网络请求标签页,可以看到所有的资源请求,包括网络请求,图片资源,html,css,js文件等请求,可以根据需求筛选请求项,一般多用于网络请求的查看和分析,分析后端接口是否正确传输,获取的数据是否准确,请求头,请求参数的查看。

选择了All,就会把该页面所有资源文件请求下来。
选择XHR 异步请求资源,则可以分析相关的请求信息。

打开一个Ajax异步请求,可以看到它的请求头信息,是一个POST请求,参数有哪些,还可以预览它的返回的结果数据,这些数据的使用和查看有利于我们很好的和后端工程师们联调数据,也方便我们前端更直观的分析数据。

3.2 http请求和响应

HTTP请求是指:客户端通过发送HTTP请求向服务器请求对资源的访问。 它向服务器传递了一个数据块,也就是请求信息。
HTTP 请求由三部分组成:请求行、请求头和请求正文。

 请求行:请求方法 URI 协议/版本
 请求头(Request Header)
 【请求空行 标志着请求头结束,请求正文(请求体)的开始】
 请求正文

3.2.1 请求的数据示例

(1)一个HTTP请求的数据实例

(1)POST /index.html HTTP/1.1   请求方法 url 协议/版本号
(2-1)Host: localhost  主机地址
(2-6)User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
(2-3)Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
(2-5)Accept-Language: zh-cn,zh;q=0.5
(2-4)Accept-Encoding: gzip, deflate
(2-2)Connection: keep-alive
(2-12)Referer: <a target=_blank href="http://localhost/" style="color: rgb(51, 102, 153); text-decoration: none;">http://localhost/</a>
(2-10)Content-Length:25
(2-11)Content-Type:application/x-www-form-urlencoded
【请求空行 标志着请求头结束,请求正文(请求体)的开始】
username=aa&password=1234

(2)示例二

(1)POST /iplat/service/BIRD11/queryOperatorTree HTTP/1.1
(2-1)Host: 10.70.70.74:8080
(2-2)Connection: keep-alive
(2-10)Content-Length: 246
(2-3)Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
(2-6)User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
(2-11)Content-Type: application/json;charset=UTF-8
Origin: http://10.70.70.74:8080
(2-12)Referer: http://10.70.70.74:8080/iplat/web/BIRD11?__post__=8ac6c6ca7b803e61017b9f5492bc0121&method=update&id=a02558b6c5e74c64b06a6eafd317261b
(2-4)Accept-Encoding: gzip, deflate
(2-5)Accept-Language: zh-CN,zh;q=0.9
(2-9)Cookie: iplat.sessionId=IPLAT-2C2877AFEAE64BE392C62E55CB5EDF04; JSESSIONID=BAB540F9551D670655B16EE2585A53C8; iplat.theme=ant
【请求空行 标志着请求头结束,请求正文(请求体)的开始】
{"__version__":"2.0","__sys__":{"name":"","descName":"","msg":"","msgKey":"","detailMsg":"","status":0,"traceId":""},"__blocks__":{"inqu_status":{"attr":{},"meta":{"desc":"","attr":{},"columns":[{"pos":0,"name":"node"}]},"rows":[["operators"]]}}}

3.2.2 请求的字段解析

(1)请求行
根据HTTP标准,HTTP请求可以使用多种请求方法。例如:HTTP1.1支持7种请求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE和TARCE。在Internet应用中,最常用的方法是GET和POST。

URL完整地指定了要访问的网络资源,通常只要给出相对于服务器的根目录的相对目录即可,因此总是以“/”开头。

最后,协议版本声明了通信过程中使用HTTP的版本。
(2)请求头
每个头域由一个域名,冒号(:)和域值三部分组成。
域名是大小写无关的,域值前可以添加任何数量的空格符.
头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。

【Transport 头域】
(2-1)Host(发送请求时,该报头域是必需的)
(2-2)Connection:作用:表示是否需要持久连接。


【Client 头域】
(2-3)Accept:
(2-4)Accept-Encoding:
(2-5)Accept-Language:
(2-6)User-Agent:
(2-7)Accept-Charset:
(2-8)Authorization:

【Cookie/Login 头域】
(2-9)Cookie:

【Entity头域】
(2-10)Content-Length:
(2-11)Content-Type:

【Miscellaneous 头域】
(2-12)Referer:

【Cache 头域】
(2-13)If-Modified-Since:
(2-14)If-None-Match:
(2-15)Pragma:
(2-16)Cache-Control:

(2-1)Host
发送请求时,该报头域是必需的
Host请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的。
(2-2)Connection
作用:表示是否需要持久连接。

Connection: keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的 网页,会继续使用这一条已经建立的连接。

Connection: close 代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭, 当客户端再次发送Request,需要重新建立TCP连接。
(2-3)Accept
作用:浏览器可以接受的媒体类型(MIME类型),

例如: Accept: text/html 代表浏览器可以接受服务器回发的类型为 text/html 也就是我们常说的html文档, 如果服务器无法返回text/html类型的数据,服务器应该返回一个406错误(non acceptable)。

通配符 * 代表任意类型。例如 Accept: / 代表浏览器可以处理所有类型,(一般浏览器发给服务器都是发这个)

(2-4)Accept-Encoding

作用: 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate),(注意:这不是只字符编码);

例如: Accept-Encoding: gzip, deflate。Server能够向支持gzip/deflate的浏览器返回经gzip或者deflate编码的HTML页面。 许多情形下这可以减少5到10倍的下载时间,也节省带宽。

(2-5)Accept-Language

作用: 浏览器申明自己接收的语言。

语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等;

例如: Accept-Language:zh-cn 。如果请求消息中没有设置这个报头域,服务器假定客户端对各种语言都可以接受。

(2-6)User-Agent

作用:告诉HTTP服务器, 客户端使用的操作系统和浏览器的名称和版本.

我们上网登陆论坛的时候,往往会看到一些欢迎信息,其中列出了你的操作系统的名称和版本,你所使用的浏览器的名称和版本,这往往让很多人感到很神奇,实际上, 服务器应用程序就是从User-Agent这个请求报头域中获取到这些信息User-Agent请求报头域允许客户端将它的操作系统、浏览器和其它属性告诉服务器。

例如: User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; InfoPath.2; .NET4.0E)

(2-7)Accept-Charset

作用:浏览器申明自己接收的字符集,这就是本文前面介绍的各种字符集和字符编码,如gb2312,utf-8(通常我们说Charset包括了相应的字符编码方案);

例如:Accept-Charset:iso-8859-1,gb2312.如果在请求消息中没有设置这个域,缺省是任何字符集都可以接受。

(2-8)Authorization
授权信息,通常出现在对服务器发送的WWW-Authenticate头的应答中;

Authorization请求报头域主要用于证明客户端有权查看某个资源。当浏览器访问一个页面时,如果收到服务器的响应代码为401(未授权),可以发送一个包含Authorization请求报头域的请求,要求服务器对其进行验证。
(2-9)Cookie

作用: 最重要的header, 将cookie的值发送给HTTP 服务器

(2-10)Content-Length

作用:发送给HTTP服务器数据的长度。即请求消息正文的长度;

例如: Content-Length: 38

(2-11)Content-Type

作用:

例如:Content-Type: application/x-www-form-urlencoded

(2-12)Referer

作用: 提供了Request的上下文信息的服务器,告诉服务器我是从哪个链接过来的,比如从我主页上链接到一个朋友那里, 他的服务器就能够从HTTP Referer中统计出每天有多少用户点击我主页上的链接访问 他的网站。

例如: Referer:http://translate.google.cn/?hl=zh-cn&tab=wT

(2-13)If-Modified-Since

作用: 把浏览器端缓存页面的最后修改时间发送到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比。如果时间一致,那么返回304,客户端就直接使用本地缓存文件。如果时间不一致,就会返回200和新的文件内容。客户端接到之后,会丢弃旧文件,把新文件缓存起来,并显示在浏览器中。

例如:If-Modified-Since: Thu, 09 Feb 2012 09:07:57 GMT。

(2-14)If-None-Match

作用: If-None-Match和ETag一起工作,工作原理是在HTTP Response中添加ETag信息。 当用户再次请求该资源时,将在HTTP Request 中加入If-None-Match信息(ETag的值)。如果服务器验证资源的ETag没有改变(该资源没有更新),将返回一个304状态告诉客户端使用本地缓存文件。否则将返回200状态和新的资源和Etag. 使用这样的机制将提高网站的性能

例如: If-None-Match: “03f2b33c0bfcc1:0”

(2-15)Pragma

作用: 防止页面被缓存, 在HTTP/1.1版本中,它和Cache-Control:no-cache作用一模一样

Pargma只有一个用法, 例如: Pragma: no-cache

注意: 在HTTP/1.0版本中,只实现了Pragema:no-cache, 没有实现Cache-Control

(2-16)Cache-Control

作用: 这个是非常重要的规则。 这个用来指定Response-Request遵循的缓存机制。各个指令含义如下

Cache-Control:Public 可以被任何缓存所缓存()
Cache-Control:Private 内容只缓存到私有缓存中
Cache-Control:no-cache 所有内容都不会被缓存

3.2.2 响应的数据示例

在接收和解释请求消息后,服务器会返回一个 HTTP 响应消息。HTTP 响应也是由三个部分组成,分别是:状态行、消息报头和响应正文。

状态行
消息报头
响应正文

(1)示例一

<p>HTTP/1.1 200 OK
Date: Sun, 17 Mar 2013 08:12:54 GMT
Server: Apache/2.2.8 (Win32) PHP/5.2.5
X-Powered-By: PHP/5.2.5
Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 4393
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8</p><p>
<html>
<head>
<title>HTTP响应示例<title>
</head>
<body>
Hello HTTP!
</body>
</html></p><p> </p>

(2)示例二

HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: SAMEORIGIN
Content-Type: text/json;charset=UTF-8
Content-Length: 48607
Date: Wed, 01 Sep 2021 03:08:45 GMT
Keep-Alive: timeout=20
Connection: keep-alive
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮皮冰燃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值