基于Selenium和ChromeDriver的自动化页面性能测试

Posted 皖南笑笑生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Selenium和ChromeDriver的自动化页面性能测试相关的知识,希望对你有一定的参考价值。

由于最近工作一直很紧张,拖了很久才在五一假期将Selenium实现自动化页面性能测试的代码实现部分补上,希望今后自己能更勤勉,多一些知识产出。
Selenium WebDriver(以下简称SW)提供了一套用于Web应用程序的自动化测试工具。SW按其应用场景不同可以分为(1)基于htmlUnit的无界面实现,并非驱动真实浏览器进行测试;(2)模拟真实输入,对多浏览器的支持和测试,包括FirefoxDriver、InternetExplorerDriver、OperaDriver和ChromeDriver;(3)对移动应用的测试,包括androidDriver和iPhoneDriver。
针对SW进行功能性测试的文章和书已经很多了,比如如何操作获取页面元素内容。而本文所要写的是如何基于Selenium和ChromeDriver做页面性能测试,比如获取页面请求的加载时间、获取页面的DOM元素加载完成时间等等。类似于一些成熟的拨测产品的实现原型(这也是笔者正在做的项目)。我想这是非常有意义的一次探索。

1. Maven依赖

首先,项目需要引入依赖的相关selenium包:selenium-api和selenium-java,要考虑不同版本和JDK版本的兼容性,笔者是JDK 1.8。

<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-api -->
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-api</artifactId>
    <version>3.5.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.5.3</version>
</dependency>

2、ChromeDriver使用详解

本节内容参考https://sites.google.com/a/chromium.org/chromedriver/home,另外ChromeDriver的安装,笔者在《CentOS 7.x环境下搭建: Headless chrome + Selenium + ChromeDriver 实现自动化测试》中有详述。

2.1、DesiredCapabilities & ChromeOptions

Capabilities属性可以定义和配置你的ChromeDriver会话,以满足对应功能和需求。
在Java实现中,类ChromeOptions和类DesiredCapabilities都可以用于具体定义Capabilities
比如以下代码,通过ChromeOptions来定义Chrome的window-size属性:

// 设置chromedriver路径
System.setProperty("webdriver.chrome.driver","/opt/drivers/chromedriver");

ChromeOptions options = new ChromeOptions();
// 设置chrome启动时size大小
options.addArguments("--window-size=1980,1000");
// 根据ChromeOptions实例化ChromeDriver
WebDriver driver = new ChromeDriver(options);
try 
    // 打开苏宁易购
    driver.get("https://www.suning.com");
     catch (Exception e) 
    e.printStackTrace();
     finally 
    // 关闭浏览器
    driver.quit();

当然,以上例子也可以改写为通过DesiredCapabilities来实现:

// 设置chromedriver路径
System.setProperty("webdriver.chrome.driver","/opt/drivers/chromedriver");

ChromeOptions options = new ChromeOptions();
// 设置chrome启动时size大小
options.addArguments("--window-size=1980,1000");
DesiredCapabilities cap = DesiredCapabilities.chrome();
cap.setCapability(ChromeOptions.CAPABILITY, options);
// 根据DesiredCapabilities实例化ChromeDriver
WebDriver driver = new ChromeDriver(cap);
try 
    // 打开苏宁易购
    driver.get("https://www.suning.com");
     catch (Exception e) 
    e.printStackTrace();
     finally 
    // 关闭浏览器
    driver.quit();

2.2、Performance Log

ChromeDriver支持性能日志(Performance Log)数据的采集。想想看Chrome的F12控制台,我们能够采集到”Network”、Page”等,而这些是实现页面性能测试的基础。
Performance Log并非是默认开启的属性,所以我们可以通过上节说的DesiredCapabilities在创建新会话的时候开启Performance Log。
而采集到的日志,我们可以通过LogEntry对象输出到Console。具体代码实现如下:

package com.suning.webdrivertest.chromedemo;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;

import java.util.logging.Level;

/**
 *
 * Created by zhuyiquan90 on 2018/1/3.
 */
public class ChromeDriverDemo1 

    public static void main(String[] args) 

        // 设置chromedriver路径
        System.setProperty("webdriver.chrome.driver", "/opt/drivers/chromedriver");

        DesiredCapabilities cap = DesiredCapabilities.chrome();
        LoggingPreferences logPrefs = new LoggingPreferences();
        // 启用Performance Log日志采集
        logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
        cap.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);

        // 根据DesiredCapabilities实例化ChromeDriver
        WebDriver driver = new ChromeDriver(cap);
        try 
            // 打开苏宁易购
            driver.get("https://www.suning.com");
            for (LogEntry entry : driver.manage().logs().get(LogType.PERFORMANCE)) 
                // 输出采集到的性能日志
                System.out.println(Thread.currentThread().getName() + entry.toString());
            
         catch (Exception e) 
            e.printStackTrace();
         finally 
            // 关闭浏览器
            driver.quit();
        
    

其输出结果如下:

Starting ChromeDriver 2.34.522932 (4140ab217e1ca1bec0c4b4d1b148f3361eb3a03e) on port 29777
Only local connections are allowed.
四月 30, 2018 3:06:27 下午 org.openqa.selenium.remote.ProtocolHandshake createSession
信息: Detected dialect: OSS
main[2018-04-30T15:06:27+0800] [INFO] "message":"method":"Page.frameAttached","params":"frameId":"49C70573CE1145CEB5B38A270213A48","parentFrameId":"28DAFE9FE90E9292F1B8EDB3315608EC","stack":"callFrames":["columnNumber":240,"functionName":"","lineNumber":0,"scriptId":"21","url":""],"webview":"28DAFE9FE90E9292F1B8EDB3315608EC"
main[2018-04-30T15:06:27+0800] [INFO] "message":"method":"Page.frameStartedLoading","params":"frameId":"49C70573CE1145CEB5B38A270213A48","webview":"28DAFE9FE90E9292F1B8EDB3315608EC"
main[2018-04-30T15:06:27+0800] [INFO] "message":"method":"Page.frameNavigated","params":"frame":"id":"49C70573CE1145CEB5B38A270213A48","loaderId":"EE699DC52C8ACA226069D24DC92E16","mimeType":"text/html","name":"chromedriver dummy frame","parentId":"28DAFE9FE90E9292F1B8EDB3315608EC","securityOrigin":"://","url":"about:blank","webview":"28DAFE9FE90E9292F1B8EDB3315608EC"

2.3、Chrome DevTools Protocol View

这一节,我们来讲讲Network和Page包含的内容,即针对上一节输出的内容,我们如何有效利用,通过它们来计算页面性能(参考Chrome DevTools Protocol)。

2.3.1、Network

Network中我们用到的事件主要是requestWillBeSent、responseReceived、loadingFailed和loadingFinished四种:

Network.requestWillBeSent

当页面即将发送HTTP请求时触发,其Json格式为:


    "message": 
        "method": "Network.requestWillBeSent",
        "params": 
            "documentURL": "about:blank",
            "frameId": "C80F96297F4216E35079CFD86251AB8B",
            "initiator": 
                "lineNumber": 0,
                "type": "parser",
                "url": "https://www.suning.com/"
            ,
            "loaderId": "58DDB2CF16600EAE484A541DF9440089",
            "redirectResponse": 
                "connectionId": 639,
                "connectionReused": false,
                "encodedDataLength": 497,
                "fromDiskCache": false,
                "fromServiceWorker": false,
                "headers": 
                    "Cache-Control": "no-cache",
                    "Connection": "keep-alive",
                    "Content-Length": "0",
                    "Date": "Mon, 30 Apr 2018 07:06:42 GMT",
                    "Expires": "Thu, 01 Jan 1970 00:00:00 GMT",
                    "Location": "https://cm.g.doubleclick.net/pixel?google_nid=ipy&google_cm",
                    "P3P": "CP=\\"NON DSP COR CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa CONa HISa TELa OTPa OUR UNRa IND UNI COM NAV INT DEM CNT PRE LOC\\"",
                    "Pragma": "no-cache",
                    "Server": "nginx/1.10.2",
                    "Set-Cookie": "CMBMP=IWl; Domain=.ipinyou.com; Expires=Thu, 10-May-2018 07:06:42 GMT; Path=/" ,
                "headersText": "HTTP/1.1 302 Found\\r\\nServer: nginx/1.10.2\\r\\nDate: Mon, 30 Apr 2018 07:06:42 GMT\\r\\nContent-Length: 0\\r\\nConnection: keep-alive\\r\\nCache-Control: no-cache\\r\\nPragma: no-cache\\r\\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\\r\\nP3P: CP=\\"NON DSP COR CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa CONa HISa TELa OTPa OUR UNRa IND UNI COM NAV INT DEM CNT PRE LOC\\"\\r\\nSet-Cookie: CMBMP=IWl; Domain=.ipinyou.com; Expires=Thu, 10-May-2018 07:06:42 GMT; Path=/\\r\\nLocation: https://cm.g.doubleclick.net/pixel?google_nid=ipy&google_cm\\r\\n\\r\\n",
                "mimeType": "",
                "protocol": "http/1.1",
                "remoteIPAddress": "127.0.0.1",
                "remotePort": 1086,
                "requestHeaders": 
                    "Accept": "image/webp,image/apng,image/*,*/*;q=0.8",
                    "Accept-Encoding": "gzip, deflate, br",
                    "Accept-Language": "zh-CN,zh;q=0.9",
                    "Connection": "keep-alive",
                    "Cookie": "sessionId=I4UF6b1WcgGMC; PYID=I4UF6b1Wcg99; CMTMS=p7Ik3Ve; CMSTMS=p7Ik3Ve; CMPUB=ADV-DefaultAdv; CMBMP=IW2",
                    "Host": "cm.ipinyou.com",
                    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" ,
                "requestHeadersText": "GET /baidu/cms.gif?baidu_error=1&timestamp=1525072001 HTTP/1.1\\r\\nHost: cm.ipinyou.com\\r\\nConnection: keep-alive\\r\\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36\\r\\nAccept: image/webp,image/apng,image/*,*/*;q=0.8\\r\\nAccept-Encoding: gzip, deflate, br\\r\\nAccept-Language: zh-CN,zh;q=0.9\\r\\nCookie: sessionId=I4UF6b1WcgGMC; PYID=I4UF6b1Wcg99; CMTMS=p7Ik3Ve; CMSTMS=p7Ik3Ve; CMPUB=ADV-DefaultAdv; CMBMP=IW2\\r\\n",
                "securityDetails": 
                    "certificateId": 0,
                    "cipher": "AES_256_GCM",
                    "issuer": "RapidSSL SHA256 CA",
                    "keyExchange": "ECDHE_RSA",
                    "keyExchangeGroup": "P-256",
                    "protocol": "TLS 1.2",
                    "sanList": ["*.ipinyou.com", "ipinyou.com"],
                    "signedCertificateTimestampList": [ "hashAlgorithm": "SHA-256", "logDescription": "Symantec log", "logId": "DDEB1D2B7A0D4FA6208B81AD8168707E2E8E9D01D55C888D3D11C4CDB6ECBECC", "origin": "Embedded in certificate", "signatureAlgorithm": "ECDSA", "signatureData": "3045022024364934CBC90A8529E327E6EF853E3EF5E48B7F1598414E0F10059DC92685FC022100A74F93A8CF23D6572D7597C072368D69EC43AFB6A9EDAA4B01B43921AADEFDC2", "status": "Verified", "timestamp": 1511173770857.0 ,  "hashAlgorithm": "SHA-256", "logDescription": "Google 'Pilot' log", "logId": "A4B90990B418581487BB13A2CC67700A3C359804F91BDFB8E377CD0EC80DDC10", "origin": "Embedded in certificate", "signatureAlgorithm": "ECDSA", "signatureData": "3046022100F319D0F56F27C82228E2B01934A1C7F46915A1509F094EE91508F08C3B5AE2B2022100B0D94DD6FD00CB435EC33B916B52EC76FE5FFCC5D5BD8CB559248243AEDFE3CE", "status": "Verified", "timestamp": 1511173770923.0 ],
                    "subjectName": "*.ipinyou.com",
                    "validFrom": 1511136000,
                    "validTo": 1547942399 ,
                "securityState": "secure",
                "status": 302,
                "statusText": "Found",
                "timing": 
                    "connectEnd": 772.852999994939,
                    "connectStart": 0.566999995498918,
                    "dnsEnd": -1,
                    "dnsStart": -1,
                    "proxyEnd": -1,
                    "proxyStart": -1,
                    "pushEnd": 0,
                    "pushStart": 0,
                    "receiveHeadersEnd": 1226.29800000141,
                    "requestTime": 42129.997749,
                    "sendEnd": 773.012999998173,
                    "sendStart": 772.960999995121,
                    "sslEnd": 772.844999999506,
                    "sslStart": 1.62599999748636,
                    "workerReady": -1,
                    "workerStart": -1 ,
                "url": "https://cm.ipinyou.com/baidu/cms.gif?baidu_error=1&timestamp=1525072001"
            ,
            "request": 
                "headers": 
                    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" ,
                "initialPriority": "Low",
                "method": "GET",
                "mixedContentType": "none",
                "referrerPolicy": "no-referrer-when-downgrade",
                "url": "https://cm.g.doubleclick.net/pixel?google_nid=ipy&google_cm"
            ,
            "requestId": "20524.247",
            "timestamp": 42131.225431,
            "type": "Image",
            "wallTime": 1525072000.35906
        
    ,
    "webview": "28DAFE9FE90E9292F1B8EDB3315608EC"

参数说明:

参数类型说明
requestIdString唯一请求ID
loaderIdString加载ID
documentURLString页面文档URL
requestRequest请求数据对象
timestampfloat以过去某个任意时间点为基点,从打开页面开始,以秒为单位单调递增的时间戳
wallTimefloatUTC时间
initiatorInitiator请求初始化对象
redirectResponseResponse重定向响应对象
typeString资源类型
frameIdStringFrameID
hasUserGesturebooleanWhether the request is initiated by a user gesture. Defaults to false.

其中,
Request对象:

参数类型说明
urlString请求url
methodStringHTTP请求类型
headersObject请求头信息
postDataStringPost请求数据
hasPostDataboolean如果是Post请求,则为true
mixedContentTypeString是否存在混淆内容问题:blockable, optionally-blockable, none.
initialPriorityString资源加载优先级:VeryLow, Low, Medium, High, VeryHigh.
referrerPolicyString跨域策略:no-referrer-when-downgrade, no-referrer, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin
isLinkPreloadboolean是否通过预加载方式加载

Response对象:

参数类型说明
urlString请求url
statusint响应状态码
statusTextString状态码内容
headersObject响应头部,json格式
headersTextString响应头部,文本格式
mimeTypeStringResource mimeType
requestHeadersObeject请求头部,json格式
requestHeadersTextString请求头部,文本格式
connectionReusedboolean连接是否被复用
connectionIdlong物理连接ID
remoteIPAddressStringRemote IP address
remotePortintRemote port
fromDiskCacheboolean是否直接从浏览器缓存获取资源
fromServiceWorkerbooleanSpecifies that the request was served from the ServiceWorker
encodedDataLengthlong响应字节数
timingResourceTimingResourceTiming对象
protocolString协议
securityStateStringSecurity state of the request resource:unknown, neutral, insecure, secure, info
securityDetailsSecurityDetailsSecurity details for the request

ResourceTiming对象:

参数类型说明
requestTimefloat时间基线
proxyStartfloatStarted resolving proxy.
proxyEndfloatFinished resolving proxy.
dnsStartfloatStarted DNS address resolve.
dnsEndfloatFinished DNS address resolve.
connectStartfloatStarted connecting to the remote host.
connectEndfloatConnected to the remote host.
sslStartfloatStarted SSL handshake.
sslEndfloatFinished SSL handshake.
workerStartfloatStarted running ServiceWorker.
workerReadyfloatFinished Starting ServiceWorker.
sendStartfloatStarted sending request.
sendEndfloatFinished sending request.
pushStartfloatTime the server started pushing request.
pushEndfloatTime the server finished pushing request.
receiveHeadersEndfloatFinished receiving response headers.

Network.responseReceived

当HTTP响应可用时触发,其Json格式为:


    "message": 
        "method": "Network.responseReceived",
        "params": 
            "frameId": "28DAFE9FE90E9292F1B8EDB3315608EC",
            "loaderId": "44DBCD0BEBFCEE5AED6388366BCB719B",
            "requestId": "20524.277",
            "response": 
                "connectionId": 468,
                "connectionReused": true,
                "encodedDataLength": 439,
                "fromDiskCache": false,
                "fromServiceWorker": false,
                "headers": 
                    "Cache-Control": "no-cache, max-age=0, must-revalidate",
                    "Connection": "keep-alive",
                    "Content-Length": "43",
                    "Content-Type": "image/gif",
                    "Date": "Mon, 30 Apr 2018 07:06:42 GMT",
                    "Expires": "Fri, 01 Jan 1980 00:00:00 GMT",
                    "Last-Modified": "Mon, 28 Sep 1970 06:00:00 GMT",
                    "Pragma": "no-cache",
                    "Server": "nginx/1.6.3",
                    "X-Dscp-Value": "0",
                    "X-Via": "1.1 dxun38:1 (Cdn Cache Server V2.0), 1.1 shb115:4 (Cdn Cache Server V2.0), 1.1 ls10:0 (Cdn Cache Server V2.0)" ,
                "headersText": "HTTP/1.1 200 OK\\r\\nDate: Mon, 30 Apr 2018 07:06:42 GMT\\r\\nServer: nginx/1.6.3\\r\\nContent-Type: image/gif\\r\\nContent-Length: 43\\r\\nLast-Modified: Mon, 28 Sep 1970 06:00:00 GMT\\r\\nExpires: Fri, 01 Jan 1980 00:00:00 GMT\\r\\nPragma: no-cache\\r\\nCache-Control: no-cache, max-age=0, must-revalidate\\r\\nX-Dscp-Value: 0\\r\\nX-Via: 1.1 dxun38:1 (Cdn Cache Server V2.0), 1.1 shb115:4 (Cdn Cache Server V2.0), 1.1 ls10:0 (Cdn Cache Server V2.0)\\r\\nConnection: keep-alive\\r\\n\\r\\n",
                "mimeType": "image/gif",
                "protocol": "http/1.1",
                "remoteIPAddress": "127.0.0.1",
                "remotePort": 1086,
                "requestHeaders": 
                    "Accept": "image/webp,image/apng,image/*,*/*;q=0.8",
                    "Accept-Encoding": "gzip, deflate, br",
                    "Accept-Language": "zh-CN,zh;q=0.9",
                    "Connection": "keep-alive",
                    "Cookie": "_snstyxuid=ADFD3F4299718846; _snvd=152507199416958111",
                    "Host": "sa.suning.cn",
                    "Referer": "https://www.suning.com/",
                    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" ,
                "requestHeadersText": "GET /ajaxSiteExpro.gif?oId=152507199969277498&pvId=152507199147454663&expoInfo=index3_homepage1_32618013033_word03,index3_homepage1_32618013033_word04,index3_homepage1_newUser_tankuang&expoType=1&pageUrl=https://www.suning.com/&visitorId=&loginUserName=&memberID=-&sessionId=&pageType=web&hidUrlPattern=&iId=log_1525071999692 HTTP/1.1\\r\\nHost: sa.suning.cn\\r\\nConnection: keep-alive\\r\\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36\\r\\nAccept: image/webp,image/apng,image/*,*/*;q=0.8\\r\\nReferer: https://www.suning.com/\\r\\nAccept-Encoding: gzip, deflate, br\\r\\nAccept-Language: zh-CN,zh;q=0.9\\r\\nCookie: _snstyxuid=ADFD3F4299718846; _snvd=152507199416958111\\r\\n",
                "securityDetails": 
                    "certificateId": 0,
                    "cipher": "AES_256_GCM",
                    "issuer": "WoSign OV SSL CA",
                    "keyExchange": "ECDHE_RSA",
                    "keyExchangeGroup": "P-256",
                    "protocol": "TLS 1.2",
                    "sanList": ["*.suning.cn", "suning.cn"],
                    "signedCertificateTimestampList": [],
                    "subjectName": "*.suning.cn",
                    "validFrom": 1479721356,
                    "validTo": 1574329356 ,
                "securityState": "secure",
                "status": 200,
                "statusText": "OK",
                "timing": 
                    "connectEnd": -1,
                    "connectStart": -1,
                    "dnsEnd": -1,
                    "dnsStart": -1,
                    "proxyEnd": -1,
                    "proxyStart": -1,
                    "pushEnd": 0,
                    "pushStart": 0,
                    "receiveHeadersEnd": 656.157999997959,
                    "requestTime": 42130.56839,
                    "sendEnd": 1.03800000215415,
                    "sendStart": 0.979999997070991,
                    "sslEnd": -1,
                    "sslStart": -1,
                    "workerReady": -1,
                    "workerStart": -1 ,
                "url": "https://sa.suning.cn/ajaxSiteExpro.gif?oId=152507199969277498&pvId=152507199147454663&expoInfo=index3_homepage1_32618013033_word03,index3_homepage1_32618013033_word04,index3_homepage1_newUser_tankuang&expoType=1&pageUrl=https://www.suning.com/&visitorId=&loginUserName=&memberID=-&sessionId=&pageType=web&hidUrlPattern=&iId=log_1525071999692"
            ,
            "timestamp": 42131.22618,
            "type": "Image"
        
    ,
    "webview": "28DAFE9FE90E9292F1B8EDB3315608EC"

参数说明:

参数类型说明
requestIdString唯一请求ID
timestampfloat以过去某个任意时间点为基点,从打开页面开始,以秒为单位单调递增的时间戳
typeString资源类型
responseResponse响应对象
frameIdStringFrameID

应用场景:根据Response可以快速识别请求的各种异常状态码(5XX、4XX),以及时间的分布。

Network.loadingFailed

当HTTP请求无法加载时触发,其Json格式为:


    "message": 
        "method": "Network.loadingFailed",
        "params": 
            "canceled": true,
            "errorText": "net::ERR_ABORTED",
            "requestId": "20524.271",
            "timestamp": 42130.877864,
            "type": "Image"
        
    ,
    "webview": "28DAFE9FE90E9292F1B8EDB3315608EC"

参数说明:

参数类型说明
requestIdString唯一请求ID
loaderIdString加载ID
timestampfloat以过去某个任意时间点为基点,从打开页面开始,以秒为单位单调递增的时间戳
typeString资源类型
errorTextString错误原因提示
canceledboolean如果请求加载被取消,则为true
blockedReasonString请求被阻塞的原因

应用场景:我们可以通过loadingFailed和requestWillBeSent确定哪些请求加载失败。

Network.loadingFinished

当HTTP请求完成加载时触发,其Json格式为:


    "message": 
        "method": "Network.loadingFinished",
        "params": 
            "blockedCrossSiteDocument": false,
            "encodedDataLength": 327,
            "requestId": "20524.262",
            "timestamp": 42130.87542
        
    ,
    "webview": "28DAFE9FE90E9292F1B8EDB3315608EC"

参数说明:

参数类型说明
requestIdString唯一请求ID
timestampfloat以过去某个任意时间点为基点,从打开页面开始,以秒为单位单调递增的时间戳
encodedDataLengthlong响应字节数
blockedCrossSiteDocumentboolean如果由于跨域阻塞了响应,则为true

应用场景:根据encodedDataLength,计算响应的最终大小。

针对requestWillBeSent、responseReceived、loadingFailed和loadingFinished四种对象,Java构建Model如下所示:

2.3.2、Page

Page中我们用到的事件主要是domContentEventFired和loadEventFired两种:

Page.domContentEventFired

页面Dom内容加载完成时间。


    "message": 
        "method": "Page.domContentEventFired",
        "params": 
            "timestamp": 42124.003701
        
    ,
    "webview": "28DAFE9FE90E9292F1B8EDB3315608EC"

Page.loadEventFired

页面加载完成时间。


    "message": 
        "method": "Page.loadEventFired",
        "params": 
            "timestamp": 42133.108263
        
    ,
    "webview": "28DAFE9FE90E9292F1B8EDB3315608EC"

以上,我们可以根据ChromeDriver来完成对页面加载性能分析的自动化测试了。

3、持久化ChromeDriverService的使用

本节介绍ChromeDriverService,这完全是出于提高测试性能的考虑。我们知道每次创建一个ChromeDriver,完成测试以后再释放掉这个对象,等下次来了一个新的测试,仍要再新建一个对象,如此反复。这相当于每次都打开浏览器,再关闭浏览器,再打开浏览器。这种实现方式并不利于高并发的测试场景。
我们希望如Java的池化设计思想一样,初始化生成多个持久化的浏览器对象,后面每次测试都用这些浏览器对象进行,这样会极大提升测试性能(想想看,避免了往复创建和关闭进程的过程啊!)。因此引入ChromeDriverServiceChromeDriverService是一个管理ChromeDriver serve

以上是关于基于Selenium和ChromeDriver的自动化页面性能测试的主要内容,如果未能解决你的问题,请参考以下文章

使用Postman或requests结合chromedriver模拟Selenium操作浏览器

Selenium和ChromeDriver的安装与配置

ubuntu下安装selenium和安装chromedriver

selenium 中的 ChromeDriver 和 WebDriver 有啥区别?

在 Mac 上使用 selenium 和 chromedriver

安装selenium和chromedriver