More than 1 year has passed since last update.

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

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

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

E2Eテストツール 使っているもの 開発言語 GitHub★
Nightwatch WebDriver JavaScript 4,727
Protractor selenium-webdriver JavaScript 5,683
WebdriverIO WebDriver JavaScript 2,055
Codecept WebdriverIO JavaScript 656
Chimp WebdriverIO JavaScript 385
Karma 各種ランチャー JavaScript 7,337
CasperJS PhantomJS/SlimerJS JavaScript 5,854
Zombie jsdom JavaScript 4,008
参考 Codeception WebDriver PHP 2,295
参考 Capybara WebDriverほか Ruby 7,208
参考 Cucumber WebDriverほか いろいろ 2,143
テストプラットフォーム 対応ブラウザ 開発言語 GitHub★
Selenium Standalone Server 各種 Java 3,977
DalekJS 各種 JavaScript 695
ヘッドレスブラウザ エンジン 開発言語 GitHub★
PhantomJS WebKit JavaScript 18,941
SlimerJS Gecko JavaScript 1,912
Nightmare Electron JavaScript 8,161
jsdom n/a JavaScript 6,194
  • GitHubのスターは2016年7月30日調べ。ただし、登場年によるバイアスが激しいので、この件に関してはあまり参考にならないですね...。

E2Eテストツール

Nightwatch

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

1469874902-11B0E1E5-0769-4D80-BFBA-F7292E366860.png

書き方はこんな感じ。

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を使っている。

1469874926-E9969026-C0A4-40C7-A1B9-F85FC43C51BD.png

実際のテストはこんな感じ。テストフレームワークのデフォルトはJasmineだけど、他のと組み合わせてもOK。Mochaとか。

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より、だいぶ書きやすい。あくまでもブラウザの自動化ツールなので、テストフレームワークは自分の好きなものと組み合わせて使う。ちなみに、Codecept・Chimp・Spectronなどは、内部的にこのWebdriverIOを使っている。

1469882980-B0F0D94F-FB03-43F3-ADEB-4E9A6AD8F435.png

書き方はこんな感じ。

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

CodeceptJS

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

1469875072-1FC56365-6FBC-445C-A303-65D1EE5384F5.png

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

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を切り替えることで様々なブラウザが使え、PhantomJSElectronでのヘッドレステストも可能。

1469878025-F3E93481-D1D7-4DDF-BDC9-9D5AED659D05.png

Chimp

1469884023-2A9CC8CC-D071-410D-9DBC-9BC50552C6CB.png

CasperJS

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

1469875272-A4667953-A25F-4825-9634-8659E0E22BC4.png

Zombie

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

1469885202-6F57F49C-8EDB-46BD-8738-59615D8D14A6.png

Codeception

1469875629-F3ABB3DF-E36E-49B2-9BEB-D006EA9BEDC9.png

Capybara

1469874375-3EF89F1A-A323-4927-AAB3-9AF352B96855.png

Cucumber

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

1469894429-4FDC2B81-3134-4539-8BA9-D69255B455BF.png

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

# 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

1469875210-760A74E1-F145-4C14-9EBB-B991A06DFA46.png

DalekJS

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

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

1469875336-C65653E5-65A1-4D77-851F-14E84C651915.png

SlimerJS

1469875248-DC365F04-0B90-47A6-B28A-42B7E010DCF2.png

Nightmare

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

1469874876-0CE1A3B7-60B0-4FA2-9F07-8FD4FF7A0297.png

jsdom

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

まとめ

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

個人的には、しばらく次のような方針で行こうかと思っています。avatapeあたりと組み合わせて。mochaでもよし。

  • シンプルなライブラリ開発: Nightmare
  • クロスブラウザテストが必要なケース: WebdriverIO

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

Appendix

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

クラウドサービス

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

BrowserStack

1469875110-29C2E3BB-48D0-49FC-A987-4E37D37071CC.png

Saucelabs

1469875017-06238D38-F6C6-4445-B4D0-A3381C33506C.png

その他

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

WebDriver

SeleniumとWebDriverの関係性がややこしく感じるけれど、要はこういうこと。

Selenium 1.0 + WebDriver = Selenium 2.0

WebDriverはSeleniumのインターフェースで、W3Cでも標準化が進められている。各種ブラウザに対応したドライバが存在する。

  • ChromeDriver
  • FirefoxDriver
  • InternetExplorerDriver
  • PhantomJSDriver (=GhostDriver) すでに開発中止
  • SafariDriver

など。

Fake (GUI)

1469874392-3675E076-B275-403D-BD34-98CE947A3BB2.png

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

1469874758-4797A07E-FA71-4B7D-993C-A0170A84156A.png

  • Spectron: 公式 - GitHub - Electron(デスクトップアプリ)に特化したE2Eテストツール。
  • Appium: 公式 - GitHub - iOSとAndroidアプリの自動化。ネイティブも、ハイブリッドも。