LoginSignup
2

More than 5 years have passed since last update.

Drupal 向け Behat の拡張その1 複数ステップの実行とカスタムステップの作成(前編)

Last updated at Posted at 2016-12-15

前回、Drupal 8 に Drupal 向け Behat のスタンドアロンでの導入とシンプルなテストシナリオという記事を書きました。その記事では、最後に簡単なテストシナリオを作成しましたが常に1つのステップと事前に定義されたステップだけでシナリオを組み立てることはかなり困難です。今回は複数ステップの実行と上記の記事でエラーメッセージの際に少し触れたカスタムステップの作成について説明していきます。

複数ステップの実行

前回作成したテストシナリオでは、前提条件、行う動作、期待する結果で実行するステップが1つずつでした。しかし、冒頭でも記述しましたが実際にテストシナリオを作成する際にステップが1つで済むことは少ないです。

今回の説明で使用するフィーチャーファイルを作成します。作成するファイル名は test2.feature にします。

cd /path/to/behat/behat-tests # Behat 動作ディレクトリ
touch features/test2.feature

作成するテストシナリオは下記になります。

Feature 名

テストフィーチャー2

シナリオ名

複数ステップの実行

前提条件

ユーザはログインしていない

トップページにアクセス

行う動作

/hogehoge にアクセス

1つ前のページに戻る

期待する結果

ステップ実行時の URL を表示する

HTTP ステータスコードは 404 ではない

今回は、前提条件、行う動作、期待する結果のそれぞれでステップを2つずつ記述しています。これらのステップを定義済みのステップから探し出すと、下記のようになります。

test2.feature
# Feature 名
Feature: テストフィーチャー2
  # Scenario 名
  Scenario: 複数ステップの実行
    # シナリオの中身
    Given I am not logged in
    Given I am at ""
    When I go to "hogehoge"
    When I move backward one page
    Then print current URL
    Then the response status code should not be 404

この内容で、Behat を実行すると下記のように問題なく実行できます。

Feature: テストフィーチャー2

  Scenario: 複数ステップの実行                               # features/test2.feature:4
    Given I am not logged in                        # Drupal\DrupalExtension\Context\DrupalContext::assertAnonymousUser()
    Given I am at ""                                # Drupal\DrupalExtension\Context\MinkContext::assertAtPath()
    When I go to "hogehoge"                         # Drupal\DrupalExtension\Context\MinkContext::visit()
    When I move backward one page                   # Drupal\DrupalExtension\Context\MinkContext::back()
    Then print current URL                          # Drupal\DrupalExtension\Context\MinkContext::printCurrentUrl()
      │ http://localhost:8888/
    Then the response status code should not be 404 # Drupal\DrupalExtension\Context\MinkContext::assertResponseStatusIsNot
()

しかし、全てステップの前に GivenWhenThen が付いているためどこからどこが前提条件を指すのかが分かりづらいです。Behat では、GivenWhenThen が複数存在している時、それらの2つ目以降は AndBut に置き換えることが出来ます。それらを置き換えると下記のようになります。

test2.feature
# Feature 名
Feature: テストフィーチャー2
  # Scenario 名
  Scenario: 複数ステップの実行
    # シナリオの中身
    Given I am not logged in
    And I am at ""
    When I go to "hogehoge"
    And I move backward one page
    Then print current URL
    But the response status code should not be 404

置き換えた後に Behat を実行すると、置き換える前と同様な結果が出力されます。

Feature: テストフィーチャー2

  Scenario: 複数ステップの実行                              # features/test2.feature:4
    Given I am not logged in                       # Drupal\DrupalExtension\Context\DrupalContext::assertAnonymousUser()
    And I am at ""                                 # Drupal\DrupalExtension\Context\MinkContext::assertAtPath()
    When I go to "hogehoge"                        # Drupal\DrupalExtension\Context\MinkContext::visit()
    And I move backward one page                   # Drupal\DrupalExtension\Context\MinkContext::back()
    Then print current URL                         # Drupal\DrupalExtension\Context\MinkContext::printCurrentUrl()
      │ http://localhost:8888/
    But the response status code should not be 404 # Drupal\DrupalExtension\Context\MinkContext::assertResponseStatusIsNot(
)

置き換えたことで、シナリオ内で GivenWhenThen がそれぞれ1回のみ出てくるようになったため、どこからどこが前提条件なのかが分かりやすくなりました。
Behat の公式ドキュメントのように AndBut の部分でインデントをつけることで読みやすさを改善することが出来ます。

パラメータがないカスタムステップの作成

カスタムステップを作成するためのテストシナリオを用意します。
今回のテストシナリオでは、test3.feature というファイル名にします。

cd /path/to/behat/behat-tests # Behat 動作ディレクトリ
touch features/test3.feature

作成するテストシナリオは下記になります。

Feature 名

テストフィーチャー3

シナリオ名

カスタムステップの作成

前提条件

ユーザはログインしていない

行う動作

<front> にアクセス

期待する結果

ステップの実行した現在時間を表示する

前提条件と行う動作に関しては、前回作成したテストシナリオとほとんど変わらないため定義済みのステップが存在します。しかし、“ステップの実行時間を表示する”は定義されていないため新たに定義を作成する必要があります。期待する結果への定義なので、最初の部分は Then になります。動作は現在時刻を表示するので、

Then print current date

と記述できます。
上記のテストシナリオは下記のようになります。

test3.feature
# Feature 名
Feature: テストフィーチャー3
  # Scenario 名

  Scenario: カスタムステップの作成
    # シナリオの中身
    Given I am not logged in
    When I go to "<front>"
    Then print current date

もちろん、このシナリオを実行しても定義されていないため下記のようにエラーが出てきます。

--- FeatureContext has missing steps. Define them with these snippets:

    /**
     * @Then print current date
     */
    public function printCurrentDate()
    {
        throw new PendingException();
    }

エラーメッセージに作成する関数のヒントが書かれているため、これを /path/to/behat/behat-tests/features/bootstrap/FeatureContext.php に追記します。追記する際は、コメントに見える

    /**
     * @Then print current date
     */

の部分も含めて追記します。(この部分がないとステップが未定義のままとして扱われます)
追記内容のままだと、throw new PendingException(); で例外を投げてしまい何もできないのでコードを書き換えていきます。

コードを書き換える前にすでに定義されている、ステップ実行時の URL を表示するステップ Then print current URLソースコードを見てみます。(Composer でインストールされたファイルならパスは、/path/to/behat/vendor/behat/mink-extension/src/Behat/MinkExtension/Context/MinkContext.php です)

MinkContext.php
    /**
     * Prints current URL to console.
     * Example: Then print current URL
     * Example: And print current URL
     *
     * @Then /^print current URL$/
     */
    public function printCurrentUrl()
    {
        echo $this->getSession()->getCurrentUrl();
    }

該当部分を抜粋すると上記になります。Behat のシナリオでも echo を使えば通常の PHP プログラムと同じく結果を出力できることが分かります。

echo を使えばよいことが分かったので、コードを書き換えます。

FeatureContext.php
  /**
   * @Then print current date
   */
  public function printCurrentDate()
  {
    echo (new DateTime())->format('Y/m/d H:i:s');
  }

書き換えた結果は上記のようになり、このテストシナリオを実行すると下記のようになります。

Feature: テストフィーチャー3

  Scenario: カスタムステップの作成      # features/test3.feature:5
    Given I am not logged in # Drupal\DrupalExtension\Context\DrupalContext::assertAnonymousUser()
    When I go to "<front>"   # Drupal\DrupalExtension\Context\MinkContext::visit()
    Then print current date  # FeatureContext::printCurrentDate()
      │ 2016/12/08 12:35:02

2 scenarios (2 passed)
6 steps (6 passed)
0m0.52s (11.18Mb)

Then print current date の次の行にステップの実行した時刻が表示されました。これで、引数がない時のカスタムステップが作成できました。

まとめ

今回の記事をまとめると以下のようになります。

  • シナリオ内のステップで GivenWhenThen が複数回使えることを示しました
  • GivenWhenThen を複数回使用する場合は AndBut でも記述ができる
    • AndBut で置き換えた方が、前提条件や行う動作、期待する結果の範囲が分かりやすくなる
  • パラメータがないカスタムステップを作成した
    • PHP での実装の際にステップの記述が必要になる
    • パラメータが有るパターンは次回になります

Behat on Drupal 8 の記事一覧

タイトル
第1回 Drupal 8 に Drupal 向け Behat のスタンドアロンでの導入とシンプルなテストシナリオ
第2回 Drupal 向け Behat の拡張その1 複数ステップの実行とカスタムステップの作成(前編)
第3回 Drupal 向け Behat の拡張その2 カスタムステップの作成(後編)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2