Selenium 与 ChromeDriver

王某某瞎编于 2018年3月20日

Selenium

Selenium 是 ThoughtWorks 提供的一个强大的基于浏览器的开源自动化测试工具。
Selenium 是一个用于 Web 应用程序测试的工具,测试直接自动运行在浏览器中,就像真正的用户在手工操作一样。支持的浏览器包括 IE、Chrome 和 Firefox 等。这个工具的主要功能包括:测试与浏览器的兼容性 - 测试您的应用程序看是否能够很好地工作在不同浏览器和操作系统之上;测试系统功能 - 创建回归测试检验软件功能和用户需求;支持自动录制动作,和自动生成 .NET、Perl、Python、Ruby 和 Java 等不同语言的测试脚本。

Selenium 1 (又叫 Selenium RC 或 Remote Control)

Webdriver

Selenium 2,又名 WebDriver,它的主要新功能是集成了 Selenium 1.0 以及 WebDriver, 是两个项目的合并,既兼容 Selenium API 也支持 WebDriver API。

WebDriver 曾经是 Selenium 的竞争对手(最开始是google的一个人弄的,主要用于避免在JavaScript的沙箱环境里存在的各种限制),他主要是通过利用浏览器原生API的方式来操控浏览器执行各种动作(还包括系统级别的调用来模拟用户输入)。

Selenium WebDriver 就是对浏览器提供的原生API进行封装,使其成为一套更加面向对象的Selenium WebDriver API。
使用这套API可以操控浏览器的开启、关闭,打开网页,操作界面元素,控制Cookie,还可以操作浏览器截屏、安装插件、设置代理、配置证书等。由于使用的原生API,其速度与稳定性都会好很多。但浏览器厂商各不相同,提供的驱动各异(ChromeDriver、FirefoxDriver(xpi插件)、InternetExplorerDriver(exe)等),API也会有差异(好像都走JSON Wire Protocol,并且向W3C标准靠拢)。Selenium 对不同厂商的各个驱动进行了封装,如:selenium-chrome-driver、selenium-edge-driver、selenium-firefox-driver等。
还包括了对移动应用进行测试的AndroidDriver和iOS WebDriver,以及一个基于HtmlUnit的无界面实现HtmlUnitDriver。

WebDriver API可以通过Python、Ruby、Java和C#访问

WebDriver是一个用来进行复杂重复的web自动化测试的工具。意在提供一种比Selenium1.0更简单易学,有利于维护的API。它没有和任何测试框架进行绑定,所以他可以很好的在单元测试和main方法中调用。一旦创建好一个Selenium工程,你马上会发现WebDriver和其他类库一样:它是完全独立的,你可以直接使用而不需要考虑其他配置,这个Selenium RC是截然相反的。

两者的差异

  • 对于所有类型的浏览器Selenium- RC都是使用的同一种方法:
    当浏览器启动时,向其中注入javascript,从而使用这些js来驱动浏览器中的AUT(Application Under Test)。
  • WebDriver并没有使用这种技术,它是通过调用浏览器原生的自动化API直接驱动浏览器。

Selenium IDE

Selenium IDE (集成开发环境) 是一个创建测试脚本的原型工具。它是一个 Firefox 插件,提供创建自动化测试的建议接口。Selenium IDE 有一个记录功能,能记录用户的操作,并且能选择多种语言把它们导出到一个可重用的脚本中用于后续执行。


ChromeDriver - WebDriver for Chrome

WebDriver是一个开源工具,用于在许多浏览器上自动测试webapps。它提供了导航到网页,用户输入,JavaScript执行等功能。ChromeDriver是一个独立的服务,它为 Chromium 实现 WebDriver 的 JsonWireProtocol 协议。

目前正在实现并转向W3C标准。 ChromeDriver适用于Android版Chrome和桌面版Chrome(Mac,Linux,Windows和ChromeOS)。

官网地址:
https://sites.google.com/a/chromium.org/chromedriver/home

ChromeDriver 是 google 为网站开发人员提供的自动化测试接口,它是 selenium2chrome浏览器 进行通信的桥梁。selenium 通过一套协议(JsonWireProtocol :https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol)和 ChromeDriver 进行通信,selenium 实质上是对这套协议的底层封装,同时提供外部 WebDriver 的上层调用类库。

大概的工作流程:

在代码中 new ChromeDriver() 时,selenium会随机挑选一个端口调用chromedriver程序,调用成功后 chromedriver 会在指定的端口启动一个服务(会有一个进程)

>tasklist | find "chromedriver"
chromedriver.exe              7848 Console                    1     13,740 K

selenium 中使用 apache 的 commons-exec 来运行 chromedriver.exe 启动 ChromeDriver 服务
直接在控制台运行 chromedriver.exe 时,默认端口是9515

selenium 通过指定的端口和约定的协议来和 ChromeDriver 进行通信,一个ChromeDriver可用管理多个chrome。
(具体细节可以看看协议部分,ChromeDriver如何控制chrome可能需要去看源码~~)

>tasklist | find "chrome"
chromedriver.exe             14692 Console                    1     14,888 K
chrome.exe                   20952 Console                    1     72,204 K
chrome.exe                    7288 Console                    1      9,052 K
chrome.exe                   15524 Console                    1     10,000 K
chrome.exe                   13036 Console                    1     96,028 K
chrome.exe                   11836 Console                    1     29,836 K
chrome.exe                    2788 Console                    1     59,876 K 

selenium 中多个 WebDriver 实例对应一个 chromedriver 进程,一个 chromedriver 进程管理多个 chrome 进程。
一个 WebDriver 实例对应一个浏览器窗口。

在代码中直接 new ChromeDriver() 将会启动一个 chromedriver 进程
使用 RemoteWebDriver 则只会连接到 chromedriver 服务,不会启动一个新的进程,连接不上会报错。
不管哪种方式都会打开一个浏览器窗口。

WebDriver driver = new RemoteWebDriver(new URL("http://127.0.0.1:9515"), DesiredCapabilities.chrome());

使用

官方指导页面

https://sites.google.com/a/chromium.org/chromedriver/getting-started

基于java

  1. 创建Maven项目
    引入相关依赖
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.7.1</version>
</dependency>
  1. 确保Chromium / Google Chrome安装在认可的位置

ChromeDriver希望您将Chrome安装在您平台的默认位置。您还可以强制ChromeDriver通过设置特殊功能来使用自定义位置。

ChromeOptions options = new ChromeOptions();
options.setBinary("/path/to/other/chrome/binary");
  1. 下载与你安装的chrome对应的chromedriver
chromedriver 版本 chrome 版本
ChromeDriver 2.36 Chrome v63-65
ChromeDriver 2.35 Chrome v62-64
ChromeDriver 2.34 Chrome v61-63
ChromeDriver 2.33 Chrome v60-62

(这里随便复制了几个)
下载地址:
https://sites.google.com/a/chromium.org/chromedriver/downloads

  1. 指定ChromeDriver所在位置,可以通过两种方法指定:
  • 通过配置ChromeDriver.exe位置到path环境变量

  • 通过设置webdriver.chrome.driver 系统属性实现-

  1. 创建一个新的ChromeDriver的实例,并调用get方法打开页面

代码:


import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class BaseTest {

    public static void main(String[] args) {
        // 设置ChromeDriver的路径
        System.setProperty("webdriver.chrome.driver", "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chromedriver.exe");

        WebDriver driver = new ChromeDriver();

        driver.get("http://www.baidu.com/");
        
        //driver.quit();
    }
}

执行这段代码将打开一个浏览器窗口,并访问百度
同时浏览器上将显示:Chrome 正受到自动测试软件的控制

代码执行完成后chrome并不会关闭,需要调用 driver.quit(); 才能关闭浏览器窗口。

打开百度并进行搜索:

public static void main(String[] args) throws InterruptedException {

        // 如果不设置将搜索环境变量
        System.setProperty("webdriver.chrome.driver", "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chromedriver.exe");

        WebDriver driver = new ChromeDriver();
        driver.get("http://www.baidu.com/");

        Thread.sleep(3000);

        WebElement searchBox = driver.findElement(By.id("kw"));

        searchBox.sendKeys("ChromeDriver");
        searchBox.submit();

        Thread.sleep(3000);
        driver.quit();

    }

高效使用

ChromeDriver 启动ChromeDriver服务器进程,并在调用退出时终止它。
在大型测试时每个测试都会创建一个ChromeDriver实例,这将会浪费大量时间。有两种方法可以解决这个问题:

1. 使用ChromeDriverService

@RunWith(BlockJUnit4ClassRunner.class)
public class ChromeTest extends TestCase {

  private static ChromeDriverService service;
  private WebDriver driver;

  @BeforeClass
  public static void createAndStartService() {
    service = new ChromeDriverService.Builder()
        .usingDriverExecutable(new File("path/to/my/chromedriver"))
        .usingAnyFreePort()
        .build();
    service.start();
  }

  @AfterClass
  public static void createAndStopService() {
    service.stop();
  }

  @Before
  public void createDriver() {
    driver = new RemoteWebDriver(service.getUrl(),
        DesiredCapabilities.chrome());
  }

  @After
  public void quitDriver() {
    driver.quit();
  }

  @Test
  public void testGoogleSearch() {
    driver.get("http://www.google.com");
    // rest of the test...
  }
}

2. 在运行测试之前单独启动ChromeDriver服务器,并使用Remote WebDriver连接到它

在控制台执行chromedriver(如果没有添加环境变量的话需要到对应目录下执行)

F:\temp>chromedriver
Starting ChromeDriver 2.37.543627 (63642262d9fb93fb4ab52398be4286d844092a5e) on port 9515
Only local connections are allowed.

Java 代码:

public static void main(String[] args) throws MalformedURLException {
    WebDriver driver = new RemoteWebDriver(new URL("http://127.0.0.1:9515"), DesiredCapabilities.chrome());

    driver.get("http://www.baidu.com");
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,473评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,229评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,570评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,427评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,335评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,737评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,392评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,693评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,730评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,512评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,349评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,750评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,017评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,290评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,706评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,904评论 2 335

推荐阅读更多精彩内容