BehatでWordPressの振る舞いテストを自動化する「 WordHat」

  • ブックマーク
  • -
    コピー
テーマの開発やWordPressでサービスを構築する時に手間となる振る舞いテストを自動化することができるPHP製のBehatにWordPress特有のテストも加えておこなえる “WordHat” を使ってみました。 導入方法や関連リンクなどをまとめます。

Behatとは?

BehatとはWebサイトやWebサービスの振る舞いをわかりやすく定型 (シナリオ) 化し、各手順を自動的にサイトにアクセスしてテストを自動化することができるPHPでできたツールです。 Behatを使うことによって「サイトにアクセスしたらトップページに○○と表示されている」または「#buttonをクリックしたらこのURLに行き、そこでは○○と表示される」などといったテストを自動で行うことができます。 スプレッドシートでテスト項目を出しながらひたすら潰していきなんていう過酷な修行からおさらばできるだけではなく、依存や影響関係を調べて気を使いなが開発することからも開放されます。もし影響が出てしまったらテスト実行すれば依存・影響があったかどうかも確認できるのでより快適に開発や運用をおこなうことができるでしょう。

WordHatの導入方法

WordHatの導入方法は WordHat – Behat for WordPress に記載のとおりですが、本家では英語の説明しかないため日本語で手順の説明をしていきます。 まずは要件についてです。WordHatを使ってテストをするためには下記項目が必要です。
  • PHP 7.1 以上
  • Composer
  • WordPRess 4.8 以上

インストール

1. ターミナルからテスト用のフォルダを作成し、移動します。

mkdir project
cd project

2. Composerを使ってWordHatをダンロードする。

composer require --dev paulgibbs/behat-wordpress-extension behat/mink-goutte-driver behat/mink-selenium2-driver


3. WordHatの設定ファイルをサンプルからコピーして作成する。

cp vendor/paulgibbs/behat-wordpress-extension/behat.yml.dist behat.yml

4. コピーした設定ファイル (behat.yml) を書き換える
  1. base_url をテストするURLに書き換えます。
  2. path をWordPressのコアファイルがあるディレクトリに相対パス・絶対パスで書き換えます。
  3. users をWordPressの管理者権限に変更します。
  4. WordPressがサブディレクトリにインストールされている場合はFAQを参照してください。
5. Behatの初期設定をおこないます。

vendor/bin/behat --init

6. 設定が完了しているかコマンドを実行して確認する。

vendor/bin/behat -dl

設定がうまくいっている場合は、下記のようにどのようなシナリオをかけるか表示されます。

default | 前提< /^(?:|ユーザーは )ホームページを表示している$/
default | もし< /^(?:|ユーザーは )ホームページへ移動する$/
default | 前提< /^(?:|ユーザーは )"(?P<page>[^\s]+)" を表示している$/u
default | もし< /^(?:|ユーザーが )"(?P<page>[^\s]+)" へ移動する$/u
default | もし< /^(?:|ユーザーが )ページをリロードする$/u
default | もし< /^(?:|ユーザーが )履歴の前のページに戻る$/u
default | もし< /^(?:|ユーザーが )履歴の次のページヘ進む$/u
default | もし< /^(?:|ユーザーが )"(?P<button>(?:[^"]|\\")*)" ボタンをクリックする$/u
default | もし< /^(?:|ユーザーが )"(?P<link>(?:[^"]|\\")*)" のリンク先へ移動する$/u
default | もし< /^(?:|ユーザーが )"(?P<field>(?:[^"]|\\")*)" フィールドに "(?P<value>(?:[^"]|\\")*)" と入力する$/u
default | もし< /^(?:|ユーザーが )"(?P<field>(?:[^"]|\\")*)" フィールドに以下の値を入力する:$/u
default | もし< /^(?:|ユーザーが )"(?P<value>(?:[^"]|\\")*)" という値を "(?P<field>(?:[^"]|\\")*)" に入力する$/u
default | もし< /^(?:|ユーザーが)次のように入力する:$/u
default | もし< /^(?:|ユーザーが )"(?P<option>(?:[^"]|\\")*)" という値を "(?P<select>(?:[^"]|\\")*)" から選択する$/u
default | もし< /^(?:|ユーザーが )"(?P<option>(?:[^"]|\\")*)" という値を "(?P<select>(?:[^"]|\\")*)" から追加で選択する$/u
default | もし< /^(?:|ユーザーが )"(?P<option>(?:[^"]|\\")*)" にチェックをつける$/u
default | もし< /^(?:|ユーザーが )"(?P<option>(?:[^"]|\\")*)" のチェックをはずす$/u
default | もし< /^(?:|ユーザーが)パス "(?P<path>[^"]*)" にあるファイルを "(?P<field>(?:[^"]|\\")*)" に添付する$/u
default | ならば< /^(?:|ユーザーが )(?P<page>[^\s]+) を表示していること$/u
default | ならば< /^(?:|ユーザーが )ホームページを表示していること$/u
default | ならば< /^(?i)url(?-i)が (?P<pattern>"(?:[^"]|\\")*") にマッチすること$/u
default | ならば< /^レスポンスコードが (?P<code>\d+) であること$/u
default | ならば< /^レスポンスコードが (?P<code>\d+) ではないこと$/u
default | ならば< /^(?:|画面に )"(?P<text>(?:[^"]|\\")*)" と表示されていること$/u
default | ならば< /^(?:|画面に )"(?P<text>(?:[^"]|\\")*)" と表示されていないこと$/u
default | ならば< /^(?:|画面に )"(?P<pattern>"(?:[^"]|\\")*")" にマッチするテキストが表示されていること$/u
default | ならば< /^(?:|画面に )"(?P<pattern>"(?:[^"]|\\")*")" にマッチするテキストが表示されていないこと$/u
default | ならば< /^レスポンスに "(?P<text>(?:[^"]|\\")*)" が含まれていること$/u
default | ならば< /^レスポンスに "(?P<text>(?:[^"]|\\")*)" が含まれていないこと$/u
default | ならば< /^"(?P<element>[^"]*)" エレメントに "(?P<text>(?:[^"]|\\")*)" と表示されていること$/u
default | ならば< /^"(?P<element>[^"]*)" エレメントに "(?P<text>(?:[^"]|\\")*)" と表示されていないこと$/u
default | ならば< /^"(?P<element>[^"]*)" エレメントに "(?P<value>(?:[^"]|\\")*)" という値が含まれていること$/u
default | ならば< /^"(?P<element>[^"]*)" エレメントに "(?P<value>(?:[^"]|\\")*)" という値が含まれていないこと$/u
default | ならば< /^(?:|画面に )"(?P<element>[^"]*)" エレメントが表示されていること$/u
default | ならば< /^(?:|画面に )"(?P<element>[^"]*)" エレメントが表示されていないこと$/u
default | ならば< /^"(?P<field>(?:[^"]|\\")*)" フィールドに "(?P<value>(?:[^"]|\\")*)" が含まれていること$/u
default | ならば< /^"(?P<field>(?:[^"]|\\")*)" フィールドに "(?P<value>(?:[^"]|\\")*)" が含まれていないこと$/u
default | ならば< /^(?:|画面に )(?P<num>\d+) 個の "(?P<element>[^"]*)" エレメントが表示されていること$/u
default | ならば< /^チェックボックス "(?P<checkbox>(?:[^"]|\\")*)" のチェックがついていること$/u
default | ならば< /^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox is checked$/
default | ならば< /^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" (?:is|should be) checked$/
default | ならば< /^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should (?:be unchecked|not be checked)$/
default | ならば< /^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox is (?:unchecked|not checked)$/
default | ならば< /^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" should (?:be unchecked|not be checked)$/
default | ならば< /^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" is (?:unchecked|not checked)$/
default | ならば< /^現在のURLを表示$/
default | ならば< /^最後のレスポンスを表示$/u
default | ならば< /^最後のレスポンスをブラウザで表示$/u
default | 前提< /^(?:there are|there is a) posts?:/
default | 前提< /^(?:I am|they are) viewing (?:a|the)(?: blog)? post(?: "([^"]+)"|:)/
default | 前提< I delete the post :post_title
default | ならば< I should not be able to view the post :post_title
default | 前提< /^(?:I am|they are) on the dashboard/
default | 前提< /^(?:I am|they are) in wp-admin/
default | もし< /^(?:I|they) go to the dashboard/
default | もし< /^(?:I|they) go to wp-admin/
default | もし< I click on the :link link in the header
default | ならば< I should be on the :admin_screen screen
default | 前提< I go to the menu :item
default | 前提< I go to the :item menu
default | ならば< /^(?:I|they) should see an? (error|status) message that says "([^"]+)"$/
default | もし< the cache is cleared
default | 前提< the cache has been cleared
default | 前提< the :name plugin is active
default | もし< I activate the :name plugin
default | もし< I deactivate the :name plugin
default | もし< I switch the theme to :name
default | 前提< /^(?:there are|there is a) users?:/
default | もし< I delete the :user_login user account
default | もし< /^(?:I am|they are) viewing posts published by (.+)$/
default | 前提< /^(?:I am|they are) an anonymous user/
default | もし< I log out
default | 前提< /^(?:I am|they are) logged in as an? (.+)$/
default | 前提< /^(?:I am|they are) logged in as (?!an? )(.+)$/
default | ならば< /^(?:I|they) should not be able to log in as an? (.+)$/
default | ならば< /^(?:I|they) should not be able to log in as (.+)$/
default | 前提< /^I am on the edit ([a-zA-z_-]+) screen for "([^"]*)"$/
default | 前提< /^I am on the edit screen for "(?P<title>[^"]*)"$/
default | もし< /^I change the title to "(?P<title>[^"]*)"$/
default | もし< /^I switch to the post content editor's (visual|text) mode$/i
default | もし< I enter the following content into the post content editor:
default | ならば< /^the post content editor is in (visual|text) mode$/i
default | もし< /^I publish the (post|changes?)$/
default | ならば< I should be on the edit :post_type screen for :post_title
default | ならば< I should see the :title metabox
default | ならば< I should not see the :title metabox
default | 前提< I have the :widget_name widget in :sidebar_name
default | もし< I search for :search in the toolbar
default | ならば< I should see :text in the toolbar
default | ならば< the toolbar should show I am authenticated as :username
default | もし< I follow the toolbar link :link

シナリオを追加したい場合はGherkinの文法を確認しfeatures/sample.featureのファイルにならって追記していけばよいでしょう。
Gherkin Syntax : Cucumber

参考URL


追記 : 2019-01-09

複数行にわたるテキストエリアの振る舞いを追加する場合。
Behat scenario multi line input
  • ブックマーク
  • -
    コピー

この記事を書いた人

Susumu Seino

1988年 東京都足立区生まれ。瀬戸内海の小島と東京に拠点を持ち、2020年からは夫婦でアドレスホッピングを計画しているデジタルノマドな日本人。デジタルパブリッシング代理店のアニューマの創業者です。