Selenium Grid的使用(分布式测试)

时间:2019-06-28 22:29:41   收藏:0   阅读:118


1、Selenium Grid简介
Selenium Grid组件专门用于远程分布式测试或并发测试。使用此组件可以在一台计算机上给多台计算机(不同操作系统和不同版本浏览器环境)分发多个测试用例从而并发执行,
大大提高了测试用例的执行效率,基本满足大型项目自动化测试的时限要求和兼容性要求。
Selenium Grid使用Hub和Node模式,一台计算机作为Hub(管理中心)管理其他多个Node(节点)计算机,Hub负责将测试用例分发给多台Node计算机执行,并收集多台Node计算机执行结果的报告,汇总后提交一份总的测试报告。
Hub:
>在分布式测试模式中,只能有一台作为Hub的计算机
>Hub负责管理测试脚本,并负责发送脚本给其他Node节点
>所有的Node节点计算机必须先在作为Hub的计算机中进行注册,注册成功后再和Hub计算机通信,Node节点计算机会告之Hub自己的相关信息,例如,Node节点的操作系统和浏览器相关版本。
Node:
>在分布式测试模式中,可以有一个或多个Node节点
>Node节点会打开本地的浏览器完成测试任务并返回测试结果给Hub
>Noel节点的操作系统和浏览器版本无需和Hub保持一致
>在Node节点上可以同时打开多个浏览器并行执行测试任务

2、分布式自动化测试环境准备
(1)下载 JDK 1.8安装文件(最好从官网下载)
(2)安装JDK
(3)配置环境变量(1.8后的JDK会自动添加环境变量)
(4)在CMD中输入java -version命令后回车,显示出java信息,不报错说明安装成功

3、Selenium Grid的使用方法
(1)远程调用Firefox浏览器进行自动化测试(其他浏览器同理)
具体步骤如下:
1)找两台WIndows系统的计算机A和B,A计算机作为Hub,B计算机作为Node(如果没有可以用本机即作Hub又作Node)
2)两台计算机均访问http://www.seleniumhq.org/download,单击“Selenium Standalone Server”下的“Download Version x.x.x”进行下载,并保存在两台计算机的存放Webdriver驱动的目录中(如D盘根目录)
3)在机器A上打开CMD窗口,并当前工作目录切换到D盘根目录,然后执行如下语句:
java -jar selenium-server-standalone-3.141.59.jar -role hub (不报错即成功)
-role hub : 启动一个Hub服务,作为分布式管理中心,等待webdriver客户端进行注册和请求,默认接收注册的地址为:http://localhost:4444/grid/register,默认启动端口为4444
4)在机器A(假如Ip地址为192.168.1.123)中的Firefox浏览器(其他浏览器也可以)地址栏中访问http://localhost:4444/grid/console,如果访问的网页中显示出“view config”的链接,表示Hub已经成功启动
5)在机器B(假如Ip地址为192.168.1.124)中打开CMD窗口,将当前工作目录D盘根目录(即selenium-server-standalone-3.141.59.jar和Webdriver驱动所在目录),输入如下命令:
运行Firefox:
java -jar selenium-server-standalone-3.141.59.jar -role webdriver -hub http://192.168.31.94:4444/grid/register-Dwebdriver.firefox.driver="D:\geckodriver.exe" -port 6666 -maxSession 5 -browser browserName="firefox",maxInstances=5
运行Chrome:
java -jar selenium-server-standalone-3.141.59.jar -role webdriver -hub http://192.168.31.94:4444/grid/register-Dwebdriver.chrome.driver="D:\chromedriver.exe" -port 6666 -maxSession 5 -browser browserName="chrome",maxInstances=5
运行IE:
java -jar selenium-server-standalone-3.141.59.jar -role webdriver -hub http://192.168.31.94:4444/grid/register-Dwebdriver.ie.driver="D:\IEDriverServer.exe" -port 6666 -maxSession 5 -browser browserName="internet explorer",maxInstances=5
运行三个浏览器:
java -jar selenium-server-standalone-3.141.59.jar -role webdriver -hub http://172.29.10.127:4444/grid/register-Dwebdriver.chrome.driver="e:\chromedriver.exe"-Dwebdriver.ie.driver="e:\IEDriverServer.exe"-Dwebdriver.firefox.driver="e:\geckodriver.exe" -port 6666 -maxSession 5 -browser browserName="internet explorer",maxInstances=5 -browser browserName="chrome",maxInstances=5 -browser browserName="firefox",maxInstance=5

参数说明:
>role : 参数值wevdriver表示Node节点名字
>hub : 参数值表示管理中心的Url地址,Node会连接到这个地址进行节点注册
>port : 参数值表示Node节点服务的端口号为6666,建议使用大于5000的端口号

6)再次访问http://localhost:4444/grid/console,验证Node节点是否已在Hub上注册成功
7)分布式执行的测试脚本
测试逻辑:
使用FireFox浏览器访问sogou首页,进行关键词“webdriver 实战宝典”的搜索,并验证搜索结果页面源码中是否出现作者名称
测试脚本:

#encoding=utf-8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

driver = webdriver.Remote(
    #设定Node节点的Url地址,后续将通过这个地址连接到Node计算机
    command_executor = "http://localhost:6666/wd/hub",
    desired_capabilities = {
        #指定远程计算机执行使用的浏览器
        "browserName":"internet explorer",
        "video":"True",
        #远程计算机的平台
        "platform":"WINDOWS"
        #"platform":"windows_nt"
    }
)

print ("Video" + "http://www.baidu.com" + driver.session_id)

try:
    driver.implicitly_wait(30)
    driver.maximize_window()
    driver.get("http://www.sogou.com")
    assert u"搜索" in driver.title
    ele = driver.find_element_by_id("query")
    ele.send_keys(u"webdriver 实战宝典")
    ele.send_keys(Keys.RETURN)
    time.sleep(3)
    assert u"吴晓华" in driver.page_source
    print "done!"
finally:
    driver.quit()

测试结果:在机器B上可以看到,计算机会自动启动浏览器执行测试脚本,执行完毕后浏览器会自动退出。在机器A上可以看到自动化测试的执行结果

4、实现并发的分布式自动化测试
Selenium Grid不仅支持在同一台机器上同时启动好几个浏览器并发跑测试用例,也支持同时在多台不同机器上启动不同的浏览器并发跑测试用例。
操作步骤:
(1)在机器A、B和C的D盘根目录(Webdriver驱动所在目录)放入selenium-server-standalone-3.141.59.jar
(2)机器A启动Hub服务
(3)机器A重新打开一个CMD,并注册为节点
(4)机器B、机器C打开Cmd,并注册为节点
注意:注册的A、B和C机器节点的端口号必须不一致
测试脚本:

#encoding=utf-8
from multiprocessing import Pool
import os, time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from multiprocessing import Manager, current_process

def node_task(name, lock, arg, successTestCases, failTestCases):
    # 获取当前进程名
    procName = current_process().name
    print procName
    time.sleep(1.2)
    print arg[node]
    print arg["browerName"]
    print Run task %s (%s)...\n % (name, os.getpid())
    start = time.time()
    driver = webdriver.Remote(
        command_executor = "%s" %arg[node],
        desired_capabilities={
            "browserName": "%s" %arg["browerName"],
            "video": "True",
            "platform": "WINDOWS"})
    try:
        driver.implicitly_wait(30)
        driver.maximize_window()
        driver.get("http://www.sogou.com")
        assert u"搜狗" in driver.title
        elem = driver.find_element_by_id("query")
        elem.send_keys(u"webdriver实战宝典")
        time.sleep(2)
        elem.send_keys(Keys.RETURN)
        assert u"吴晓华" not in driver.page_source
        # 请求获取共享资源的锁
        lock.acquire()
        # 向进程间共享列表successTestCases中添加执行成功的用例名称
        successTestCases.append("TestCase" + str(name))
        # 释放共享资源的锁,以便其他进程能获取到此锁
        lock.release()
        print "TestCase" + str(name) + " done!"
    except AssertionError,e:
        print "AssertionError occur!""testCase" + str(name)
        print e
        # 截取屏幕
        driver.save_screenshot(e:\\screenshoterror + str(name) + .png)
        lock.acquire()
        # 向共享列表failTestCases中添加执行失败的用例名称
        failTestCases.append("TestCase" + str(name))
        lock.release()
        print u"测试用例执行失败"
    except Exception,e:
        print "Exception occur!"
        print e
        driver.save_screenshot(e:\\screenshoterror + str(name) + .png)
        # 请求获得共享资源操作的锁,操作完后自动释放
        with lock:
            # 向共享列表failTestCases中添加执行失败的用例名称
            failTestCases.append("TestCase" + str(name))
        print u"测试用例执行失败"
    finally:
        driver.quit()
    end = time.time()
    print Task %s runs %0.2f seconds. % (name, (end - start))

def run(nodeSeq):
    # 创建一个多进程的Manager实例
    manager = Manager()
    # 定义一个共享资源列表successTestCases
    successTestCases = manager.list([])
    # 定义一个共享资源列表failTestCases
    failTestCases = manager.list([])
    # 创建一个资源锁
    lock = manager.Lock()
    # 打印主进程的进程ID
    print Parent process %s. % os.getpid()
    # 创建一个容量为3的进程池
    p = Pool(processes=3)
    testCaseNumber = len(nodeSeq)
    for i in range(testCaseNumber):
        # 循环创建子进程,并将需要的数据传入子进程
        p.apply_async(node_task, args=(i + 1, lock, nodeSeq[i],
                                       successTestCases, failTestCases))
    print Waiting for all subprocesses done...
    # 关闭进程池,不再接受新的请求任务
    p.close()
    # 阻塞主进程直到子进程退出
    p.join()
    return successTestCases, failTestCases

def resultReport(testCaseNumber, successTestCases, failTestCases):
    # 下面代码用于打印本次测试报告
    print u"测试报告:\n"
    print u"共执行测试用例:" + str(testCaseNumber) + u"个\n"
    print u"成功的测试用例:", str(len(successTestCases))
    if len(successTestCases) > 0:
        for t in successTestCases:
            print t
    else:
        print u""
    print u"失败的测试用例:", str(len(failTestCases))
    if len(failTestCases) > 0:
        for t in failTestCases:
            print t
    else:
        print u""

if __name__ == __main__:
    # 节点列表
    nodeList=[
        {"node":"http://127.0.0.1:6666/wd/hub","browerName":"internet explorer"},
        {"node":"http://127.0.0.1:6666/wd/hub","browerName":"chrome"},
        {"node":"http://127.0.0.1:6666/wd/hub", "browerName":"firefox"}]
    # 获取节点个数
    testCaseNumber = len(nodeList)
    # 开始多进程分布式测试
    successTestCases, failTestCases = run(nodeList)
    print All subprocesses done.
    # 在控制台中打印测试报告
    resultReport(testCaseNumber, successTestCases, failTestCases)

5、注意点:
jar和Webdriver浏览器驱动放在同一目录下
机器A:启动Hub
机器B:注册到这个Hub
程序:在机器A运行,然后指定机器B的ip作为driver的参数,然后可以在机器B运行测试程序

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!