Behat3/Mink Extension で複数のウェブドライバーを目的に応じて切り替える


Behat の Mink Extension を使うとリモートのウェブサイトに対する E2E テストを実行することができます。

Mink Extension では、以下の URL に書いてある通り複数の WebDriver をサポートしています。

多くの場合、Selenuim2 を使えば、テスト先のウェブサイトの JavaScript や CSS のテストも可能で、スクリーンショットを自動的に取ったりすることもできます。

また、ウインドウサイズを変更することもできますのでレスポンシブデザインのテストも自動化することができます。

ただし、Selenium2 ドライバーではレスポンスヘッダーへのアクセスができません。

これについては、Selenium2 の開発チームもそれはサポートしないよという旨のことを GitHub でたびたび発言していて、その理由をいろいろ読んでみると仕方なさそうですね。。。

Goutte ドライバーを使ってレスポンスヘッダーにアクセスする

上述のように Selenium2 では レスポンスヘッダーにアクセスできませんが、Goutte ドライバーを使えばそれが可能になります。

// HTTP ステータスコードを取得
$this->getSession()->getStatusCode();

ただし、Goutte ドライバーでは、JavaScript の実行やウインドウサイズの変更、スクリーンショットの取得等ができません。

そこで、実行したいテストの内容によって WebDriver を切り替えるようにしてみます。

behat.yml に複数のウェブドライバーを追加する

まず、behat.yml に複数の今回使用したい Selenium2 ドライバーと、Goutte ドライバーを追加します。

behat.yml
default:
  suites:
    default:
      paths:
        - %paths.base%/features
      contexts:
        - FeatureContext
        - Behat\MinkExtension\Context\MinkContext
  extensions:
    Behat\MinkExtension:
      base_url: http://127.0.0.1:8080
      default_session: default
      sessions:
        default:
          selenium2:
            wd_host: http://127.0.0.1:4444/wd/hub
        goutte:
          goutte: ~

重要な項目は以下です。

  • default > extensions > Behat\MinkExtension > default_session
  • default > extensions > Behat\MinkExtension > sessions

ひとつめの default_session はデフォルトのウェブドライバーを指定します。 この値には sessions 以下の要素のうちの一つを入れる必要があります。

Behat では、@mink:selenium2 のようなタグを記述することで、そのシナリオで使用する WebDriver を切り替えることができます。

default_sessions を記述すると、このタグが指定されていない時に、ここで指定したドライバーが使用されます。

ふたつめの sessions という項目には使用したい WebDriver を記述します。ここで項目名を default って書けばそれがデフォルトになるのかと思ってましたが、上述の default_session を記述しないとダメみたいで、それに気がつくまでにかなりハマりました。

それぞれの WebDriver は、composer require することを忘れないこと。

あと、base_url ってやつはテスト先のサイトのURLですね。

テストを書く

テストは以下のように記述します。

Feature: HTTP response

  @mink:goutte
  Scenario: Check http status code

    When I am on "/"
    Then the HTTP status should be 200

    When I am on "/the-page-not-found"
    Then the HTTP status should be 404

このテストのためのコンテキストは以下のような感じ

    /**
     * Check http status code.
     *
     * @param string $expect The HTTP status code.
     * @then /^the HTTP status should be (?P<expect>[0-9]+)$/
     */
    public function the_http_status_should_be( $expect )
    {
        $status = $this->getSession()->getStatusCode();
        $this->assertSame( intval( $status ), intval( $expect ), sprintf(
            'The HTTP status is %1$s, but it should be %2$s',
            $status,
            $expect
        ) );
    }

この例の場合 @mink:goutte というタグがあれば、Goutte ドライバーが使用され、レスポンスヘッダー等にアクセスすることができます。

このタグがないと以下のようにエラーとなります。

Status code is not available from Behat\Mink\Driver\Selenium2Driver (Behat\Mink\Exception\UnsupportedDriverActionException)

WordPress 用エクステンションについて

この記事で説明した内容は以下のリポジトリでみることができます。

このプロジェクトでは、WordPress に対する E2E テストのための Mink エクステンションに取り組んでいます。