下面,笔者将结合Bing搜索案例在Chrome和Firefox浏览器上实现兼容性测试。在经过前面Selenium、Docker和Selenium Grid相关知识的学习后,您想到了什么?是不是可以通过使用Docker+Selenium Grid就能够完成基于不同浏览器的兼容性测试呢?是的,这确实是个好主意。
但是,如果让Selenium测试脚本在不同浏览器中运行,又需要做些什么呢?
在脚本设计上,您需要做一些改变,通常情况下,要在脚本的运行时指定主机和端口,脚本类似于以下方式:
import time
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
driver = webdriver.Remote(
command_executor='http://192.168.1.102:4444/wd/hub',
desired_capabilities=DesiredCapabilities.CHROME)
base_url = 'https://cn.bing.com'
driver.get(base_url)
driver.save_screenshot('chrome.png')
driver.close()
通常在执行时,只需指定Hub的地址(即:http://192.168.1.102:4444/wd/hub)。这里宿主机的IP如图1-242所示, Hub会将脚本自动分配给Node节点去执行。
- command_executor参数:该参数为选填参数,可指定远程服务器URL字符串或自定义远程连接,默认为“http://127.0.0.1:4444/wd/hub”。
- desired_capabilities参数:该参数为必填参数,可根据情况配置启动浏览器会话时请求功能的字典。这里我们应用的是“DesiredCapabilities.CHROME”,您可以查看其对应源代码如下所示。
class DesiredCapabilities(object):
"""
Set of default supported desired capabilities.
Use this as a starting point for creating a desired capabilities object for
requesting remote webdrivers for connecting to selenium server or selenium grid.
Usage Example::
from selenium import webdriver
selenium_grid_url = "http://198.0.0.1:4444/wd/hub"
# Create a desired capabilities object as a starting point.
capabilities = DesiredCapabilities.FIREFOX.copy()
capabilities['platform'] = "WINDOWS"
capabilities['version'] = "10"
# Instantiate an instance of Remote WebDriver with the desired capabilities.
driver = webdriver.Remote(desired_capabilities=capabilities,
command_executor=selenium_grid_url)
Note: Always use '.copy()' on the DesiredCapabilities object to avoid the side
effects of altering the Global class instance.
"""
FIREFOX = {
"browserName": "firefox",
"acceptInsecureCerts": True,
}
INTERNETEXPLORER = {
"browserName": "internet explorer",
"version": "",
"platform": "WINDOWS",
}
EDGE = {
"browserName": "MicrosoftEdge",
"version": "",
"platform": "ANY"
}
CHROME = {
"browserName": "chrome",
"version": "",
"platform": "ANY",
}
OPERA = {
"browserName": "opera",
"version": "",
"platform": "ANY",
}
SAFARI = {
"browserName": "safari",
"version": "",
"platform": "MAC",
}
HTMLUNIT = {
"browserName": "htmlunit",
"version": "",
"platform": "ANY",
}
HTMLUNITWITHJS = {
"browserName": "htmlunit",
"version": "firefox",
"platform": "ANY",
"javascriptEnabled": True,
}
IPHONE = {
"browserName": "iPhone",
"version": "",
"platform": "MAC",
}
IPAD = {
"browserName": "iPad",
"version": "",
"platform": "MAC",
}
ANDROID = {
"browserName": "android",
"version": "",
"platform": "ANDROID",
}
PHANTOMJS = {
"browserName": "phantomjs",
"version": "",
"platform": "ANY",
"javascriptEnabled": True,
}
WEBKITGTK = {
"browserName": "MiniBrowser",
"version": "",
"platform": "ANY",
}
WPEWEBKIT = {
"browserName": "MiniBrowser",
"version": "",
"platform": "ANY",
}
从DesiredCapabilities类的源码可知“DesiredCapabilities.CHROME”是该类定义的一个字典对象。
这里笔者采用多线程的方式,实现分别在Chrome和Firefox浏览器执行Bing搜索业务,对应脚本如下。
Grid_Test.py文件内容:
from threading import Thread
from selenium import webdriver
from time import sleep,ctime
from selenium.webdriver.common.by import By
def Test_Bing(Host, Browser):
caps = {'browserName': Browser}
driver = webdriver.Remote(command_executor=Host, desired_capabilities=caps)
driver.get('http://www.bing.com')
driver.find_element(By.ID,'sb_form_q').send_keys('异步社区')
driver.find_element(By.ID,'sb_form_go').click()
PicName=Browser+'_result'+'.png'
driver.save_screenshot(PicName)
assert ('没有与此相关的结果' not in driver.page_source)
sleep(2)
driver.close()
if __name__ == '__main__':
pcs = {'http://192.168.1.102:4444/wd/hub': 'chrome',
'http://localhost:4444/wd/hub': 'firefox'
}
threads = []
tds=range(len(pcs))
# 创建线程
for host, browser in pcs.items():
t = Thread(target=Test_Bing, args=(host, browser))
threads.append(t)
# 启动线程
for i in tds:
threads[i].start()
for i in tds:
threads[i].join()
从上面的脚本,大家可以看到创建了一个名称为Test_Bing()的函数,其包含两个参数,分别是主机和浏览器。函数的执行意图就是根据远程服务器URL字符串和传入的浏览器名称字符串,在对应的浏览器中执行搜索业务,且搜索词为“异步社区”,对执行结果进行截图,截图的名称为对应浏览器名称+“_result.png”文件,并对搜索后的结果进行断言。需要说明的是,这里对结果进行截图的目的不仅仅是想看一下结果,还有一个很重要的原因是在使用Selenium Grid时,执行测试过程中不会出现浏览器,所以您看不到执行过程,为了证明结果的正确性我们也需要截一个图证明其确实是工作了并且执行是正确的。如果您还想看到不同的容器在执行过程中的界面,也可以使用VNC Viewer连接到对应容器(但需下载对应的selenium/node-firefox-debug和selenium/node-chrome-debug镜像文件,debug结尾的镜像都带有VNC服务端,本机安装VNC客户端,即可远程连接。5900端口为VNC Viewer的监听端口,故做了一个端口映射),如图1-243和图1-244所示。
事实上这对于测试工作并没有太多意义,故不做太多文字赘述。
在主函数中,定义了一个包含2个元素的字典,大家可以看到笔者使用了2种同一个地址不同的表示方式(宿主机的IP地址为192.168.1.102),而“localhost”也表示本机,即宿主机。那么为什么不都用“192.168.1.102”或者“localhost”呢?这是因为字典的键(Key)是不允许重复的。接下来创建了一个线程列表,以pcs字典的键、值作为Test_Bing()函数的参数,并添加到线程列表。而后启动线程列表中的各线程。
在运行脚本前,需保证创建并启动Hub和Node节点容器(注:这里笔者应用的为非Debug版本Node镜像),如图1-245所示。
脚本执行完成后,将会生成“chrome_result.png”和“firefox_result.png”这2个图片文件,如图1-246所示。
如图1-247和图1-248所示,在本次兼容性测试中大家可以看到这2个浏览器都执行了相同的Bing搜索业务,它们的页面展示、布局、内容基本是相同的,但是却存在2个小的问题,就是在Chrome浏览器中搜索到的结果为“855,000 Results”,而Firefox浏览器中搜索到的结果为“859,000 Results”,它们是不一致的。另一个小问题是,在Firefox浏览器会显示“Sign in”和一个登陆图标,而在Chrome浏览器中却没有。理论上来讲这是2个严重级别较低的小Bug,但笔者建议针对这两个小的差异,需要和产品、研发的同学再确认一下,产品、测试、研发应统一、明确需求,明确后再修改需求或代码,使两者保持一致。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。