360Qtest团队 修改 chromedriver 进行浏览器自动化测试

雪_1919 · 2016年07月07日 · 最后由 Ccleo 回复于 2020年06月18日 · 7059 次阅读

浏览器的自动化测试包括很多方面,如性能测试、UI 测试、页面测试等。本文测试背景是页面测试部分,如:登录某个页面,检查是否登录成功等。

对浏览器页面进行自动化测试,一般选取的工具都是 selenium。selenium 是一个免费的 web 自动化测试工具,支持多平台(windows、linux 等)、多浏览器(ie、ff、safari、opera、chrome)、多语言(C、 java、ruby、python 等)。

使用 selenium 操作 webkit 核浏览器时,还需要 chromedriver 工具(下载地址:https://sites.google.com/a/chromium.org/chromedriver)。
操作 IE 浏览器时,需要工具 iedriver。

一、selenium 和 chormedriver 工作原理

chromedriver 是 google 为网站开发人员提供的自动化测试接口,是网站测试架构 selenium 的 chrome 基础部分,主要是通过 http 通信实现的。它是 selenium 和 浏览器进行通信的桥梁。他们的工作原理是:

  1. selenium 通过一套协议和 chromedriver 进行通信,selenium 实质上是对这套协议的底层封装,同时提供外部 WebDriver 的上层调用类库。Selenium 提供的操作包括:Session 相关、Element(页面)相关、Window 相关、Alert 相关
  2. selenium 通过指定的 port(如 9515)调用起 chromedriver 的实例,具体实现见 chromium 源码
  3. chromedriver 在本地 port(如 9515)端口打开一个 http 服务,selenium 通过网络编程与这个 http 服务进行通信,通信协议即 1 中提到的 protocol
  4. chromedriver 和外部(如 selenium)的通信,通过 session 进行标识,selenium 中每创建一个 WebDriver 实例,则 chromedriver 新建一个进程,通过包含唯一的远程调试端口的命令(如:--remote-debugging-port=12996)启动一个 chromebrowser 实例,并将其保存在一个 session 中,这个 session 保持 selenium 和 对应的 chromebrowser 的通信;
  5. chromedriver 中的 session 和 chromebrowser 通过 socket 进行 TCP 通信,即 4 中通过命令启动 chromebrowser 的同时,session 中包含一个 socket 的 client,和 chromebrowser 中的 socket 服务进行通信,进而控制 chromebrowser;
  6. selenium 中的 WebDriver 实例和 chromedriver 的关系为多对一,chromedriver 和 chromebrowser 的关系为一对多;

例如,使用 python + selenium + chormedriver 打开浏览器,并打开百度:

from selenium.webdriver import Chrome,ChromeOptions
driver_path = r "chromedriver.exe"  #chromedriver 路径
broswer_path = r "xxxx.exe"  #浏览器exe路径
Options = ChromeOptions()
Options.binary_location = broswer_path  #浏览器路径,不指定的话会自动查找Chrome 路径,如果Chrome安装的话
driver = Chrome(chrome_options=Options, executable_path = driver_path,port=9515)  #启动chromedriver,根据浏览器路径启动浏览器
driver.get( "https://www.baidu.com")   #打开百度

执行上面代码,你会发现浏览器启动的命令行中,有一项:--remote-debugging-port。这个启动参数是什么呢?它表示开启 Remote Debugging 远程调试,Remote Debugging 使得我们的待测浏览器(基于 webkit 的浏览器)成为一个 WebServer。加入启动浏览器时使用了参数 --remote-debugging-port=8000,这时访问 localhost:8000,就可以看到当前浏览器中打开的所有页面。

二、chormedriver 源码修改

但是,我们在测试浏览器的过程中,还需兼顾许多其他内容,比如浏览器要从桌面双击启动,然后打开某个页面进行一系列操作,此时通过 chromedriver 来打开浏览器是不合理的。这时就需要修改 chormedriver 的部分源码,以满足我们自动化测试的需求。修改的核心思想是屏蔽 chromedriver 对新的浏览器进程的创建,将它 attach 到一个已经运行的浏览器进程上。

知道了如何修改,接下来的问题是,如何获取 chormedriver 的源码。单纯找 chormedriver 的源码是找不到的,因为它集成在 Google 的 chromium 项目中(chrome 浏览器源码),和 chromium 项目中的很多文件有依赖关系。根据 https://www.chromium.org/developers/how-tos/get-the-code 文档可以下载到 chromium 源码,这是个很费时的过程。源码下载完成后,就能在 src/chrome/test/chromedriver 路径找到 chormedriver 的源码了。主要修改的是 chrome_launcher.cc 文件中的 LaunchDesktopChrome 函数。

修改的具体方法是:
(1)PrepareCommandLine、LaunchProcess 等和创建浏览器进程的代码注射掉
(2)根据浏览器安装路径参数 capabilities.binary 找到浏览器进程,并获取该进程的 remote-debugging-port(浏览器安装路径参数在 selenium 请求创建新的 session 时给出)
(3)WaitForDevToolsAndCheckVersion 中的远程调试端口使用上面获取到的 remote-debugging-port

修改完成后,对 chormedriver 进行编译(注意编译选项设置)。新编译出的 chormedriver 就能满足我们的需求了。这里需要注意的是,不同版本的 chormedriver 对 chrome 内核 的最低支持版本不同,如 chormedriver2.22 版本最低支持 chrome 49 或 50,所以在修改源码时,要获取合适的 chromium 分支。

使用方法是:
(1)启动我们的测试浏览器,注意要开启远程调试(remote-debugging-port )
(2)使用 selenium 启动 chromedriver.exe,由于修改了源码,这里不会再次启动浏览器 。注意:chromedriver.exe 启动时也有一个启动端口,这个端口用于和 selenium 通信, 不要和 remote-debugging-port 一样,否则会导致 chromedriver 无法使用。
(3)通过 selenium 控制 chromedriver.exe 进行浏览器的各种操作。

图示:

参考资料:
http://www.cnblogs.com/wiki-royzhang/p/3604000.html?utm_source=tuicool&utm_medium=referral
http://www.chawenti.com/articles/6474.html
https://www.chromium.org/developers/how-tos/get-the-code

共收到 4 条回复 时间 点赞

文章请使用 markdown,然后超链接挂了。另外为啥是 360QA 专区。。= =

请问怎么修改的,有源码么?

您好,请问更具体和详细的说明

编译后的 chromedriver 可以支持全部版本的 chrome 吗?

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册