BehatでWordPressの振る舞いテストを自動化する「 WordHat」
テーマの開発やWordPressでサービスを構築する時に手間となる振る舞いテストを自動化することができるPHP製のBehatにWordPress特有のテストも加えておこなえる “WordHat” を使ってみました。
導入方法や関連リンクなどをまとめます。
Gherkin Syntax : Cucumber
追記 : 2019-01-09
複数行にわたるテキストエリアの振る舞いを追加する場合。
Behat scenario multi line input
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 project2. Composerを使ってWordHatをダンロードする。
composer require --dev paulgibbs/behat-wordpress-extension behat/mink-goutte-driver behat/mink-selenium2-driver3. WordHatの設定ファイルをサンプルからコピーして作成する。
cp vendor/paulgibbs/behat-wordpress-extension/behat.yml.dist behat.yml4. コピーした設定ファイル (behat.yml) を書き換える
- base_url をテストするURLに書き換えます。
- path をWordPressのコアファイルがあるディレクトリに相対パス・絶対パスで書き換えます。
- users をWordPressの管理者権限に変更します。
- WordPressがサブディレクトリにインストールされている場合はFAQを参照してください。
vendor/bin/behat --init6. 設定が完了しているかコマンドを実行して確認する。
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
- WordPressに対してBDDなテストを行うためのボイラープレートをつくった | Firegoby
- Behatを触ってみたメモ – Qiita
- behatで始めるBDD
- WordHat – Behat for WordPress
- GitHub – vccw-team/boilerplate-behat-wordpress: A boilerplate for Testing WordPress with Behat
追記 : 2019-01-09
複数行にわたるテキストエリアの振る舞いを追加する場合。
Behat scenario multi line input