WordPressに対してBDDなテストを行うためのボイラープレートをつくった

WordPressサイトに対して BDD なテストを行うためのボイラープレートを作りました。

https://github.com/vccw-team/boilerplate-behat-wordpress

BDDとはなにかというと振る舞い駆動という意味で、ユニットテストがよりプログラマーよりなものであるなら、BDDは顧客の要求仕様に基づいたテストになります。

たとえばユニットテストでは、特定の関数の戻り値の確認作業を自動化するわけですが、これは必ずしも顧客の要求仕様に基づいたものではありません。

一方で、BDDなテストでは、「スマホでみたときに、このサイドバーを非表示にして!」みたいなことをテストするものなので、顧客からの要求仕様を直接テストに落とし込んだものになります。

Behat とは

Behat とは、PHPで書かれたBDDテスト用のフレームワークで、その最大の特徴はまるでドキュメントのようにテストを記述できることです。

Given the screen size is 1440x900
And I login as "admin" with password "admin"

When I am on "/wp-admin/"
Then I should see "ダッシュボード"

上にかかれている内容をよーく読むと

http://behat.org/en/latest/

  • ウインドウのサイズは 1440×900 です。
  • ユーザー名 admin 、パスワード admin でログインしてください。
  • /wp-admin/ に移動して。
  • ダッシュボード ってどこかに表示されてるはず。

というようなことを順番にやってることがお分かりいただけると思います。

たとえばこのテストで、ウインドウのサイズの数字を 320×400 に変更すると、このテストは失敗します。なぜかというとWordPressの管理画面では”ダッシュボード”という文字はそのサイズでは表示されなくなるからなんですね。

ちなみにBehat は僕がコミッターを務める WP-CLI でも大活躍しています。

https://github.com/wp-cli/wp-cli/blob/master/features/cli-info.feature

WP-CLIでは、現在7,000ケースぐらいのコマンドの組み合わせを Behat でテストしてる感じですね。

Behat に関しては去年のPHPカンファレンスでも発表したのでそちらもどうぞ。

このボイラープレートについて

今回作ったものは以前から使用していた Behat の WordPress 用のExtesionをわりと導入しやすいようにあらかじめ構成したものです。

https://github.com/vccw-team/boilerplate-behat-wordpress

もしデフォルトのVCCW環境があれば使い方は以下のコマンドを順番に実行するだけです。

$ git clone git@github.com:vccw-team/boilerplate-behat-wordpress.git
$ cd boilerplate-behat-wordpress
$ composer install
$ npm install

そしてテストを実行。

$ npm test

なぜ npm コマンドかというと Phantom.js を実行して対象サイトに見に行ってもらっているからです。

結果は以下のとおりです。

$ npm test

> wordpress-behat@1.0.0 test /Users/miyauchi/Desktop/boilerplate-behat-wordpress
> /usr/bin/env node bin/run-tests.js

Feature: Example Features

  Scenario: Login as the "administrator" role # features/sample.feature:3
    When I login as the "administrator" role  # VCCW\Behat\Mink\WordPressExtension\Context\WordPressContext::login_as_the_role()
    And I am on "/wp-admin/"                  # Behat\MinkExtension\Context\MinkContext::visit()
    Then I should see "Dashboard"             # Behat\MinkExtension\Context\MinkContext::assertPageContainsText()

  Scenario: Take a screenshot                                          # features/sample.feature:9
    Given the screen size is 1440x900                                  # VCCW\Behat\Mink\WordPressExtension\Context\WordPressContext::set_window_size()
    And I login as the "administrator" role                            # VCCW\Behat\Mink\WordPressExtension\Context\WordPressContext::login_as_the_role()
    When I am on "/"                                                   # Behat\MinkExtension\Context\MinkContext::visit()
    Then take a screenshot and save it to "_out/1440x900.png"          # VCCW\Behat\Mink\WordPressExtension\Context\WordPressContext::take_a_screenshot()
    When I am on "/wp-admin/"                                          # Behat\MinkExtension\Context\MinkContext::visit()
    Then take a screenshot and save it to "_out/1440x900-wp-admin.png" # VCCW\Behat\Mink\WordPressExtension\Context\WordPressContext::take_a_screenshot()
    Given the screen size is 320x400                                   # VCCW\Behat\Mink\WordPressExtension\Context\WordPressContext::set_window_size()
    When I am on "/"                                                   # Behat\MinkExtension\Context\MinkContext::visit()
    Then take a screenshot and save it to "_out/320x400.png"           # VCCW\Behat\Mink\WordPressExtension\Context\WordPressContext::take_a_screenshot()
    When I am on "/wp-admin/"                                          # Behat\MinkExtension\Context\MinkContext::visit()
    Then take a screenshot and save it to "_out/320x400-wp-admin.png"  # VCCW\Behat\Mink\WordPressExtension\Context\WordPressContext::take_a_screenshot()

2 個のシナリオ (2 個成功)
14 個のステップ (14 個成功)
0m6.89s (10.84Mb)

デフォルトのテストでは、1440×900 と 320×400 という2つのウインドウサイズで、WordPress にログインして、スクリーンショットを保存するという処理をしています。

保存されたスクリーンショットは _out ディレクトリ以下に保存されていますので、テーマを変えるなどしてぜひいろいろ試してください。

テストでは人間が目視で確認できるありとあらゆることを自動化することができます。

たとえば、フォームで特定の値を入力してボタンを押して、期待通りの画面に遷移するか?とか、エラーメッセージが期待通り出るか?とか。

他にも指定したプラグインがインストールされているか?とか有効化されているか?などです。

それらのテストのサンプルは、以下のURLにあります。

https://github.com/vccw-team/wordpress-mink-extension/tree/master/features

カスタマイズ方法

まずデフォルトの設定ファイル behat.yml.dist をコピーして behat.yml というファイルで保存してください。

https://github.com/vccw-team/boilerplate-behat-wordpress/blob/master/behat.yml.dist

次にまずユーザーアカウントを記述します。

ここのユーザー名とパスワードを書き換える感じです。

https://github.com/vccw-team/boilerplate-behat-wordpress/blob/master/behat.yml.dist#L14-L15

この設定ファイルの内容は環境変数から取得することも可能なので、暗号化しておいてTravis CIで自動的に確認ということもできます。

ユーザーは以下のように複数登録することもできます。

extensions:
  VCCW\Behat\Mink\WordPressExtension:
    roles:
      administrator:
        username: admin
        password: admin
      me:
        username: user
        password: 1111

この場合、以下のように記述することで、user というユーザー名でログインすることができます。

Given I login as the "me" role

 たとえばユーザーの権限によって、特定の画面にアクセスできるか?みたいなことをテストできるわけです。

次に、テスト対象のサイトの URL を base_url という項目で指定してください。

https://github.com/vccw-team/boilerplate-behat-wordpress/blob/master/behat.yml.dist#L17

以上が終わったら、npm test を実行してみましょう。

テストを追加する

すべてのテストは、.feature という拡張しで features ディレクトリ以下に保存されています。

同じ拡張子のファイルが順番にテストされる感じですね。

上述したようにいくつかのサンプルが以下のURLにありますのでいろいろ見てください。

https://github.com/vccw-team/wordpress-mink-extension/tree/master/features

使用できるテストの文書のパターンは以下のコマンドでも見ることができます。

vendor/bin/behat -di --lang=en

参考までにちょっと複雑なパターンのテストを紹介します。

Feature: WordPress Admin

  Scenario: Showing the Homepage with PC
    Given the screen size is 1440x900
    And I login as "admin" with password "admin"

    When I am on "/wp-admin/plugin-install.php"
    And I fill in "s" with "contact-form-7"
    And I wait for 10 seconds
    Then I should see "Just another contact form plugin."

    When I click the "a.install-now" element
    And I wait for 20 seconds

    Then I should see "Activate"

    When I click the "a.activate-now" element
    Then I should see "Plugin activated."

    When I am on "/wp-admin/admin.php?page=wpcf7"
    Then I should see "Contact Forms"

これは、みなさんが普段 Contact Form 7というプラグインをインストールするときに実行するであろう以下の手順を再現したものです。

  1. ウインドウサイズは 1440×900 である。
  2. 管理者としてログイン。
  3. プラグインのページに移動する。
  4. 検索フィールドに “contact-form-7” と入力。
  5. 検索結果に “Just another contact form plugin.” と表示されていることを確認。
  6. インストールボタンをクリック。
  7. 20秒待つ。
  8. 有効化ボタンが表示されていることを確認。
  9. 有効化ボタンをクリック。
  10. “Plugin activated.” というメッセージが表示されたことを確認。
  11. Contact Form 7 の管理画面に移動。
  12. “Contact Forms” というテキストが表示されていることを確認。

という感じです。

この中で、たとえばプラグインの検索や有効化などは、Ajaxが使用されていますが、このテストではそれらも正しく扱うことができます。

フォームのテストは以下のような感じ。

Scenario: Send message from contact form
  Given I am on "/contact"
    When I fill in the following:
      | your-name | miya |
      | your-email | miya@example.com |
      | your-subject | Hello |
      | your-message | こんにちは! |
     And I press "Send"
     And I wait for 3 seconds
     Then I should see "Thank you"

どうです?簡単ですよね?

まとめ

長くなりましたが、一見難しく見える Behat によるテストですが、一度やってしまうととても簡単で、なおかつ再利用しやすいテストです。

そして、冒頭で紹介したように開発者以外の人でもテストに書いてあることを理解しやすいものになっています。

ぜひぜひ、みなさん試してください。

あっ、GitHubにスターをつけるのをお忘れなく!