ブラウザテストツール総まとめ・2016年夏版


WebサイトやWebアプリケーションの文脈(フロント寄り)で、E2E関連ツールを整理してみます。いろいろありすぎるようでいて、「結局[Selenium](#selenium)かよっ」ていう話ですが...。ただ、クロスブラウザテストが不要であれば[Nightmare](#nightmare)は簡便な選択肢としてオススメです。個人的な見解は[まとめ](#まとめ)参照。

*(当初『E2Eは「End to end」の略ですよ。まとめ』と題したのですが、「E2E」という用語がそれほど浸透していない?ようなので、改題しました)*

以下、目次を兼ねて並べてみました。E2Eの文脈でないものも一部含みますが、全体像を把握するために入れてあります。変なところあれば、コメントでご指摘くださいませ。

E2Eテストツール | 使っているもの | 開発言語 | GitHub★
:-- | :--: | :--: | --: | --:
[Nightwatch](#nightwatch) | WebDriver | JavaScript | 4,727
[Protractor](#protractor) | selenium-webdriver | JavaScript | 5,683
[WebdriverIO](#webdriverio) | WebDriver | JavaScript | 2,055
[Codecept](#codecept) | WebdriverIO | JavaScript | 656
[Chimp](#chimp) | WebdriverIO | JavaScript | 385
[Karma](#karma) | 各種ランチャー | JavaScript | 7,337
[CasperJS](#casperjs) | PhantomJS/SlimerJS | JavaScript | 5,854
[Zombie](#zombie) | jsdom | JavaScript | 4,008
参考 [Codeception](#codeception) | WebDriver | PHP | 2,295
参考 [Capybara](#capybara) | WebDriverほか| Ruby | 7,208
参考 [Cucumber](#cucumber) | WebDriverほか | いろいろ | 2,143

テストプラットフォーム | 対応ブラウザ | 開発言語 | GitHub★
:-- | :--: | :--: | --: | --:
[Selenium Standalone Server](#seleniumstandaloneserver) | 各種 | Java | 3,977
[DalekJS](#dalekjs) | 各種 | JavaScript | 695

ヘッドレスブラウザ | エンジン | 開発言語 | GitHub★
:-- | :--: | :--: | --: | --:
[PhantomJS](#phantomjs) | WebKit | JavaScript | 18,941
[SlimerJS](#slimerjs) | Gecko | JavaScript | 1,912
[Nightmare](#nightmare) | Electron | JavaScript | 8,161
[jsdom](#jsdom) | n/a | JavaScript | 6,194

- GitHubのスターは2016年7月30日調べ。ただし、登場年によるバイアスが激しいので、この件に関してはあまり参考にならないですね...。



## E2Eテストツール

### Nightwatch

総合的なE2Eテストツール。WebDriver実装(独自)と、アサーションライブラリが一体となっているのが、使いやすいような使いにくいような。

- http://nightwatchjs.org/
- https://github.com/nightwatchjs/nightwatch

![1469874902-11B0E1E5-0769-4D80-BFBA-F7292E366860.png](https://qiita-image-store.s3.amazonaws.com/0/1858/290d7b95-7d1c-b446-efc3-95abd920a80c.png "1469874902-11B0E1E5-0769-4D80-BFBA-F7292E366860.png")

書き方はこんな感じ。

```javascript
module.exports = {
  'Demo test Google' : function (client) {
    client
      .url('http://www.google.com')
      .waitForElementVisible('body', 1000)
      .assert.title('Google')
      .assert.visible('input[type=text]')
      .setValue('input[type=text]', 'rembrandt van rijn')
      .waitForElementVisible('button[name=btnG]', 1000)
      .click('button[name=btnG]')
      .pause(1000)
      .assert.containsText('ol#rso li:first-child',
        'Rembrandt - Wikipedia')
      .end();
  }
};
```

### Protractor

UIテストの定番。AngularJSのために作られたフレームワーク。AngularJS以外からだと、余計な機能もあるが、Reactなどと合わせて使う人も多い。内部的には、[selenium-webdriver](https://www.npmjs.com/package/selenium-webdriver)を使っている。

- http://www.protractortest.org/
- https://github.com/angular/protractor

![1469874926-E9969026-C0A4-40C7-A1B9-F85FC43C51BD.png](https://qiita-image-store.s3.amazonaws.com/0/1858/8206915f-8359-d52a-0e5c-055f16d6b994.png "1469874926-E9969026-C0A4-40C7-A1B9-F85FC43C51BD.png")

実際のテストはこんな感じ。テストフレームワークのデフォルトは[Jasmine](http://jasmine.github.io/)だけど、他のと組み合わせてもOK。Mochaとか。

```javascript
describe('angularjs homepage todo list', function() {
  it('should add a todo', function() {
    browser.get('https://angularjs.org');

    element(by.model('todoList.todoText')).sendKeys('write first protractor test');
    element(by.css('[value="add"]')).click();

    var todoList = element.all(by.repeater('todo in todoList.todos'));
    expect(todoList.count()).toEqual(3);
    expect(todoList.get(2).getText()).toEqual('write first protractor test');

    // You wrote your first test, cross it off the list
    todoList.get(2).element(by.css('input')).click();
    var completedAmount = element.all(by.css('.done-true'));
    expect(completedAmount.count()).toEqual(2);
  });
});
```

### WebdriverIO

Selenium 2.0 bindings for NodeJS。公式の[selenium-webdriver](https://www.npmjs.com/package/selenium-webdriver)より、だいぶ書きやすい。あくまでもブラウザの自動化ツールなので、テストフレームワークは自分の好きなものと組み合わせて使う。ちなみに、Codecept・Chimp・Spectronなどは、内部的にこのWebdriverIOを使っている。

- http://Webdriver.IO/
- https://github.com/webdriverio/webdriverio

![1469882980-B0F0D94F-FB03-43F3-ADEB-4E9A6AD8F435.png](https://qiita-image-store.s3.amazonaws.com/0/1858/287f96b7-82c0-dc93-c0b7-9c9ede5d6ae2.png "1469882980-B0F0D94F-FB03-43F3-ADEB-4E9A6AD8F435.png")

書き方はこんな感じ。

```javascript
browser
  .get("http://www.google.com")
  .elementById('q')
  .sendKeys('webdriver')
  .elementById('btnG')
  .click()
```

### CodeceptJS

比較的後発で、Codeception(PHP製)を元に作られたJavaScriptのツール。「同期的に」書けるのがウリ。ただ、書き方が独特なので好き嫌いが分かれそう。

- http://codecept.io/
- https://github.com/codeception/codeceptjs/

![1469875072-1FC56365-6FBC-445C-A303-65D1EE5384F5.png](https://qiita-image-store.s3.amazonaws.com/0/1858/d5eb0c86-aa05-b425-fdcb-a37a9e5ab49b.png "1469875072-1FC56365-6FBC-445C-A303-65D1EE5384F5.png")

実際のテストはこんな感じ。

```javascript
Feature('CodeceptJS Demonstration');

Scenario('submit form successfully', (I) =>
  I.amOnPage('/documentation')
  I.fillField('Email', 'hello@world.com')
  I.fillField('Password', '123456')
  I.checkOption('Active')
  I.checkOption('Male');
  I.click('Create User')
  I.see('User is valid')
  I.dontSeeInCurrentUrl('/documentation')
});
```

### Karma

AngularJSのために生まれたテストフレームワーク。E2Eというより、ユニットテスト的な使い方が基本。ただ、境界はあいまいなので、E2E的に使っているケースもあり。`launcher`を切り替えることで様々なブラウザが使え、[PhantomJS](https://github.com/karma-runner/karma-phantomjs-launcher)や[Electron](https://github.com/twolfson/karma-electron)でのヘッドレステストも可能。

- https://karma-runner.github.io
- https://github.com/karma-runner/karma/

![1469878025-F3E93481-D1D7-4DDF-BDC9-9D5AED659D05.png](https://qiita-image-store.s3.amazonaws.com/0/1858/6114d26c-d431-8dfa-7bf1-296dcd0c5bf8.png "1469878025-F3E93481-D1D7-4DDF-BDC9-9D5AED659D05.png")

### Chimp

- https://chimp.readme.io/
- https://github.com/xolvio/chimp

![1469884023-2A9CC8CC-D071-410D-9DBC-9BC50552C6CB.png](https://qiita-image-store.s3.amazonaws.com/0/1858/d056e7ca-6e24-8cc3-36a2-9066cf974d24.png "1469884023-2A9CC8CC-D071-410D-9DBC-9BC50552C6CB.png")

### CasperJS

PhantomJSとSlimerJSを透過的に使えるツール。でも、モバイルどうするの...。

- http://casperjs.org/
- https://github.com/casperjs/casperjs

![1469875272-A4667953-A25F-4825-9634-8659E0E22BC4.png](https://qiita-image-store.s3.amazonaws.com/0/1858/f5b7c3a9-eadc-975d-2ca5-1dbf4de554e5.png "1469875272-A4667953-A25F-4825-9634-8659E0E22BC4.png")

### Zombie

jsdomベースのテストツール。そろそろ開発止まってる...?

- http://zombie.js.org/
- https://github.com/assaf/zombie

![1469885202-6F57F49C-8EDB-46BD-8738-59615D8D14A6.png](https://qiita-image-store.s3.amazonaws.com/0/1858/94e0d292-2ab6-cc32-0ee9-d7f611585b8d.png "1469885202-6F57F49C-8EDB-46BD-8738-59615D8D14A6.png")

### Codeception

- http://codeception.com/
- https://github.com/codeception/codeception
- 開発言語はPHP

![1469875629-F3ABB3DF-E36E-49B2-9BEB-D006EA9BEDC9.png](https://qiita-image-store.s3.amazonaws.com/0/1858/7bd88eae-4d6f-9e9c-4c21-d42ed923dd11.png "1469875629-F3ABB3DF-E36E-49B2-9BEB-D006EA9BEDC9.png")

### Capybara

- http://jnicklas.github.io/capybara/
- 開発言語はRuby

![1469874375-3EF89F1A-A323-4927-AAB3-9AF352B96855.png](https://qiita-image-store.s3.amazonaws.com/0/1858/359f7346-41d8-6875-9dc4-984493e71eb5.png "1469874375-3EF89F1A-A323-4927-AAB3-9AF352B96855.png")

### Cucumber

異次元方向に向かっているのがCucumber。JavaScript実装も存在する。

- https://cucumber.io/
- https://github.com/cucumber/cucumber-js

![1469894429-4FDC2B81-3134-4539-8BA9-D69255B455BF.png](https://qiita-image-store.s3.amazonaws.com/0/1858/7c92161d-8cda-caaf-7e79-14f02d05bb90.png "1469894429-4FDC2B81-3134-4539-8BA9-D69255B455BF.png")

Gherkinという自然言語風味なDSLで書く。

```gherkin
# features/my_feature.feature

Feature: Example feature
  As a user of Cucumber.js
  I want to have documentation on Cucumber
  So that I can concentrate on building awesome applications

  Scenario: Reading documentation
    Given I am on the Cucumber.js GitHub repository
    When I go to the README file
    Then I should see "Usage" as the page title
```

## テストプラットフォーム

### Selenium Standalone Server

- http://www.seleniumhq.org/
- https://github.com/SeleniumHQ/selenium
- 開発言語: Java 😱 (クライアントライブラリについては、複数言語存在)

![1469875210-760A74E1-F145-4C14-9EBB-B991A06DFA46.png](https://qiita-image-store.s3.amazonaws.com/0/1858/d235c385-d2cc-1750-8b8d-83f895d35f2c.png "1469875210-760A74E1-F145-4C14-9EBB-B991A06DFA46.png")

### DalekJS

もともとSeleniumのインターフェースだったWebDriverを、Node環境で独自実装したもの。すごく期待していたんですが、開発止まってる...😱 (誰かその後を知りませんか?)

- http://dalekjs.com/
- https://github.com/dalekjs/dalek
- 開発言語: JavaScript

![1469875176-6B670F74-5CE4-44A9-9DB0-734BC6DE47CC.png](https://qiita-image-store.s3.amazonaws.com/0/1858/590f6e2d-f2d2-2e79-b380-4ee530080a10.png "1469875176-6B670F74-5CE4-44A9-9DB0-734BC6DE47CC.png")

## ヘッドレスブラウザ

クロスブラウザテストは、時間とお金がかかります。そこで、一般的なのが次の布陣です。GitHubで受け付けるプルリクエストも、Travisまでにしておいてクロスブラウザテストを省略することが多いようですね。

- ローカル: ヘッドレスブラウザ
- Travisとか: ヘッドレスブラウザ
- BrowserStack / Saucelabs: クロスブラウザ

しばらく、PhantomJS一択だったのですが、v1.9で永らく足踏みしていた結果、ES5対応も不完全な状態が続いたため、React勢からは完全に見放され「もうjsdomだけでいいよ」的な風潮が生まれたりします。2016年になって無事、PhantomJSもバージョンアップを果たしv2に。ベースとなるWebKitが新しくなりだいぶ使いやすくなりました。

しかし、PhantomJSは早晩、Chromeの度重なるアップデートに着いていけなくなりそうな気配もあります(誰か「違う」と言って!)。ダークホースだったのがElectronで、これをブラウザの代わりに使おうという動きがここしばらく活発です。単体で使うならNightmare押し。ただ、SeleniumからElectronを使うルートがまだいまいち確立されていない2016年夏現在です。

### PhantomJS

- http://phantomjs.org/
- https://github.com/ariya/phantomjs/
- WebKit

![1469875336-C65653E5-65A1-4D77-851F-14E84C651915.png](https://qiita-image-store.s3.amazonaws.com/0/1858/43295940-0aae-a06f-2d45-325aa9687a3e.png "1469875336-C65653E5-65A1-4D77-851F-14E84C651915.png")

### SlimerJS

- https://slimerjs.org/
- https://github.com/laurentj/slimerjs/
- Gecko and SpiderMonkey

![1469875248-DC365F04-0B90-47A6-B28A-42B7E010DCF2.png](https://qiita-image-store.s3.amazonaws.com/0/1858/e7ee6393-02ef-4e5f-3476-8c2482cd2afe.png "1469875248-DC365F04-0B90-47A6-B28A-42B7E010DCF2.png")

### Nightmare

最近、エンジンをPhantomJSからElectronに切り替えて注目が集まっている。これ自体でE2Eツールとしても十分使える。

- http://www.nightmarejs.org/
- https://github.com/segmentio/nightmare
- Electron

![1469874876-0CE1A3B7-60B0-4FA2-9F07-8FD4FF7A0297.png](https://qiita-image-store.s3.amazonaws.com/0/1858/babf3ddf-cf24-0637-824f-5b7decfd5d1f.png "1469874876-0CE1A3B7-60B0-4FA2-9F07-8FD4FF7A0297.png")

### jsdom

Reactのテストでよく使われる。

- https://github.com/tmpvar/jsdom
- WHATWG DOM と HTML のJavaScriptによる実装。


## まとめ

Seleniumから脱却したい気持ちは大きいですが、しばらくは使わざるを得ないようです。ただ、Nightwatch・ProtractorをはじめWebDriverクライアントの使い勝手はだいぶ向上しました。第二のWebDriver実装である`WebdriverIO`は、単体で相当シンプルに書けるようになったので、もうラッパーライブラリを使う必要もないかもしれません。

個人的には、しばらく次のような方針で行こうかと思っています。[ava](https://github.com/avajs/ava)か[tape](https://github.com/substack/tape)あたりと組み合わせて。[mocha](https://mochajs.org/)でもよし。

- シンプルなライブラリ開発: [Nightmare](#nightmare)
- クロスブラウザテストが必要なケース: [WebdriverIO](#webdriverio)

あとはコードカバレッジどうするか...。「統合テストでカバレッジを取らない」のが基本なのでしょうが、フロント中心になるとそうも言ってられないような。[Karma](#karma)なら簡単に取れるけれど、ページ遷移が扱えないのが困りどころです。

## Appendix

以下は、一応メモしておくぐらい。ご参考まで。

### クラウドサービス

Seleniumをローカルに立ち上げたくない僕らのためのサービス。モバイルを含めたブラウザの種類が充実。基本有料だけど、オープンソースブロジェクトはたいてい無料。

#### BrowserStack

- https://www.browserstack.com/

![1469875110-29C2E3BB-48D0-49FC-A987-4E37D37071CC.png](https://qiita-image-store.s3.amazonaws.com/0/1858/4ff9a54d-6fe5-149a-a7fa-75409e28e914.png "1469875110-29C2E3BB-48D0-49FC-A987-4E37D37071CC.png")


#### Saucelabs

- https://saucelabs.com/

![1469875017-06238D38-F6C6-4445-B4D0-A3381C33506C.png](https://qiita-image-store.s3.amazonaws.com/0/1858/f0b61e54-ed6f-71fd-e392-a4dfcb45710f.png "1469875017-06238D38-F6C6-4445-B4D0-A3381C33506C.png")

#### その他

- TestingBot https://testingbot.com/
- Rainforest QA https://www.rainforestqa.com/

ほか、結構いっぱいあります。

### WebDriver

Seleniumと[WebDriver](http://www.seleniumhq.org/projects/webdriver/)の関係性がややこしく感じるけれど、要はこういうこと。

> Selenium 1.0 + WebDriver = Selenium 2.0

WebDriverはSeleniumのインターフェースで、[W3Cでも標準化が進められている](https://www.w3.org/TR/webdriver/)。各種ブラウザに対応したドライバが存在する。

- ChromeDriver
- FirefoxDriver
- InternetExplorerDriver
- PhantomJSDriver (=[GhostDriver](https://github.com/detro/ghostdriver)) すでに開発中止
- SafariDriver

など。

### Fake (GUI)

- http://fakeapp.com/
- WebKitベース
- 動作環境: Mac OS X

![1469874392-3675E076-B275-403D-BD34-98CE947A3BB2.png](https://qiita-image-store.s3.amazonaws.com/0/1858/2b08e582-b6f2-6a8f-57ba-ce74b1dd0545.png "1469874392-3675E076-B275-403D-BD34-98CE947A3BB2.png")

### アプリケーションテスト (ハイブリッド系)

![1469874758-4797A07E-FA71-4B7D-993C-A0170A84156A.png](https://qiita-image-store.s3.amazonaws.com/0/1858/0a286eed-e511-05ef-55a5-684095662bbc.png "1469874758-4797A07E-FA71-4B7D-993C-A0170A84156A.png")

- Spectron: [公式](http://electron.atom.io/spectron/) - [GitHub](https://github.com/electron/electron) - Electron(デスクトップアプリ)に特化したE2Eテストツール。
- Appium: [公式](http://appium.io/) - [GitHub](https://github.com/appium/appium) - iOSとAndroidアプリの自動化。ネイティブも、ハイブリッドも。