behat+selenium

behat＋seleniumを組み合わせ方がやっと、理解できたのでメモ。
behatは単体テストとかIntegrationテストを自動化してくれるやつで、cucumberのPHP版です。

もうちょっと英語が読めれば、数時間で終わったはずなのに、時間かかってしまったww
自分の備忘録として残します。
日本語資料があまりないみたいなので、皆様の参考になればと思ってます。
ちなみに環境は、Mac OS Xの10.8.3です

まず、BehatとMInkのインストールと初期の使い方に関しては、以下を参照してください。
http://behat.org/
基礎がつかめれば、本題

まず、composer.jsonは以下

```composer.json
{
    "require": {
        "behat/behat": ">=2.4@stable",
        "behat/mink":  "1.4@stable",
        "behat/mink-extension": "*",
        "behat/mink-goutte-driver": "*",
        "behat/mink-selenium-driver":  "*",
        "behat/mink-selenium2-driver":  "*"
    },

    "config": {
        "bin-dir": "bin/"
    }
}
```


んで、composer取得

```composer.phar
curl -s https://getcomposer.org/installer | php
```

curl入ってなかったら、自分で入れてね

インストール

```install
php composer.phar install
```

behat初期化

```
HIRATSUKA-no-MacBook-Air:mink20130506 shiratsu$ ./bin/behat --init
Xdebug requires Zend Engine API version 220090626.
The Zend Engine API version 220100525 which is installed, is newer.
Contact Derick Rethans at http://xdebug.org/docs/faq#api for a later version of Xdebug.

+d features - place your *.feature files here
+d features/bootstrap - place bootstrap scripts and static files here
+f features/bootstrap/FeatureContext.php - place your feature related code here
```

これで初期化終わり。ってことで、featureファイルを作っていきます

```google.feature
Feature: Googleもしかして
  In order to see a word definition
  As a website user
  I need to be able to search for a word


  @javascript
  Scenario: Chromeは神かどうかのテスト
    Given I am on "http://www.google.co.jp"
    When I fill in "gbqfq" with "Chrome ゴミブラウザ"
    And I click "btnK"
    Then I should see "Chrome ゴミブラウザ" 
```

seleniumと組み合わせるには@javascriptをつけないとダメみたい。（http://mink.behat.org/#seleniumdriver）

ここまで出来たら、実行します。
っと、その前にselenium起動

```
java -jar /usr/local/bin/selenium-server-standalone-2.32.0.jar
```

あ、あとbehat.yml

```behat.yml
default:
    extensions:
        Behat\MinkExtension\Extension:
            selenium2: ~
            goutte:    ~

# No context:
no_context:
  paths:
    bootstrap: 'NON_EXISTING_FOLDER'
  filters:
    tags:      '~@javascript'    
```

No Contextから下は要らんかも。つでにgoutteも要らない

```
HIRATSUKA-no-MacBook-Air:mink20130506 shiratsu$ ./bin/behat
Xdebug requires Zend Engine API version 220090626.
The Zend Engine API version 220100525 which is installed, is newer.
Contact Derick Rethans at http://xdebug.org/docs/faq#api for a later version of Xdebug.

Feature: Googleもしかして
  In order to see a word definition
  As a website user
  I need to be able to search for a word

  @javascript
  Scenario: Chromeは神かどうかのテスト                    # features/google.feature:7
    Given I am on "http://www.google.co.jp"
    When I fill in "gbqfq" with "Chrome ゴミブラウザ"
    And I click "btnK"
    Then I should see "Chrome ゴミブラウザ"

1 個のシナリオ (1 個未定義)
4 個のステップ (4 個未定義)
0m0.021s

未定義のステップを、次のスニペットで実装できます:

    /**
     * @Given /^I am on "([^"]*)"$/
     */
    public function iAmOn($arg1)
    {
        throw new PendingException();
    }

    /**
     * @When /^I fill in "([^"]*)" with "([^"]*)"$/
     */
    public function iFillInWith($arg1, $arg2)
    {
        throw new PendingException();
    }

    /**
     * @Given /^I click "([^"]*)"$/
     */
    public function iClick($arg1)
    {
        throw new PendingException();
    }

    /**
     * @Then /^I should see "([^"]*)"$/
     */
    public function iShouldSee($arg1)
    {
        throw new PendingException();
    }
```

なんか追加しろって言ってるから、featureContextに追加する

```FeatureContext.php
<?php

use Behat\Behat\Context\ClosuredContextInterface,
    Behat\Behat\Context\TranslatedContextInterface,
    Behat\Behat\Context\BehatContext,
    Behat\Behat\Exception\PendingException;
use Behat\Gherkin\Node\PyStringNode,
    Behat\Gherkin\Node\TableNode;

use Behat\MinkExtension\Context\MinkDictionary;
//
// Require 3rd-party libraries here:
//
//   require_once 'PHPUnit/Autoload.php';
//   require_once 'PHPUnit/Framework/Assert/Functions.php';
//

/**
 * Features context.
 */
class FeatureContext extends BehatContext
{

    use MinkDictionary;
    /**
     * Initializes context.
     * Every scenario gets it's own context object.
     *
     * @param array $parameters context parameters (set them up through behat.yml)
     */
    public function __construct(array $parameters)
    {
        // Initialize your context here
    }

    /**
     * @Then /^I wait for the suggestion box to appear$/
     */
    public function iWaitForTheSuggestionBoxToAppear()
    {
        $this->getSession()->wait(5000, "$('.suggestions-results').children().length > 0");
    }

   /**
     * @Given /^I am on "([^"]*)"$/
     */
    public function iAmOn($arg1)
    {
        throw new PendingException();
    }

    /**
     * @When /^I fill in "([^"]*)" with "([^"]*)"$/
     */
    public function iFillInWith($arg1, $arg2)
    {
        throw new PendingException();
    }

    /**
     * @Given /^I click "([^"]*)"$/
     */
    public function iClick($arg1)
    {
        throw new PendingException();
    }

    /**
     * @Then /^I should see "([^"]*)"$/
     */
    public function iShouldSee($arg1)
    {
        throw new PendingException();
    }

//
// Place your definition and hook methods here:
//
//    /**
//     * @Given /^I have done something with "([^"]*)"$/
//     */
//    public function iHaveDoneSomethingWith($argument)
//    {
//        doSomethingWith($argument);
//    }
//
}
```

んで、また実行

```
IRATSUKA-no-MacBook-Air:mink20130506 shiratsu$ ./bin/behat
Xdebug requires Zend Engine API version 220090626.
The Zend Engine API version 220100525 which is installed, is newer.
Contact Derick Rethans at http://xdebug.org/docs/faq#api for a later version of Xdebug.

Feature: Googleもしかして
  In order to see a word definition
  As a website user
  I need to be able to search for a word

  @javascript
  Scenario: Chromeは神かどうかのテスト                    # features/google.feature:7
    Given I am on "http://www.google.co.jp"     # FeatureContext::iAmOn()
      TODO: write pending definition
    When I fill in "gbqfq" with "Chrome ゴミブラウザ" # FeatureContext::iFillInWith()
    And I click "btnK"                          # FeatureContext::iClick()
    Then I should see "Chrome ゴミブラウザ"           # FeatureContext::iShouldSee()

1 個のシナリオ (1 個ペンディング)
4 個のステップ (3 個スキップ, 1 個ペンディング)
0m0.019s
```

ペンディングっぽいのでExceptionを全部外してみる

```
<?php

use Behat\Behat\Context\ClosuredContextInterface,
    Behat\Behat\Context\TranslatedContextInterface,
    Behat\Behat\Context\BehatContext,
    Behat\Behat\Exception\PendingException;
use Behat\Gherkin\Node\PyStringNode,
    Behat\Gherkin\Node\TableNode;

use Behat\MinkExtension\Context\MinkDictionary;
//
// Require 3rd-party libraries here:
//
//   require_once 'PHPUnit/Autoload.php';
//   require_once 'PHPUnit/Framework/Assert/Functions.php';
//

/**
 * Features context.
 */
class FeatureContext extends BehatContext
{

    use MinkDictionary;
    /**
     * Initializes context.
     * Every scenario gets it's own context object.
     *
     * @param array $parameters context parameters (set them up through behat.yml)
     */
    public function __construct(array $parameters)
    {
        // Initialize your context here
    }

    /**
     * @Then /^I wait for the suggestion box to appear$/
     */
    public function iWaitForTheSuggestionBoxToAppear()
    {
        $this->getSession()->wait(5000, "$('.suggestions-results').children().length > 0");
    }

    /**
     * @Given /^I am on "([^"]*)"$/
     */
    public function iAmOn($arg1)
    {
        //throw new PendingException();
    }

    /**
     * @When /^I fill in "([^"]*)" with "([^"]*)"$/
     */
    public function iFillInWith($arg1, $arg2)
    {
        //throw new PendingException();
    }

    /**
     * @Given /^I click "([^"]*)"$/
     */
    public function iClick($arg1)
    {
        //throw new PendingException();
    }

    /**
     * @Then /^I should see "([^"]*)"$/
     */
    public function iShouldSee($arg1)
    {
        //throw new PendingException();
    }

//
// Place your definition and hook methods here:
//
//    /**
//     * @Given /^I have done something with "([^"]*)"$/
//     */
//    public function iHaveDoneSomethingWith($argument)
//    {
//        doSomethingWith($argument);
//    }
//
}
```

で、また実行

```
HIRATSUKA-no-MacBook-Air:mink20130506 shiratsu$ ./bin/behat
Xdebug requires Zend Engine API version 220090626.
The Zend Engine API version 220100525 which is installed, is newer.
Contact Derick Rethans at http://xdebug.org/docs/faq#api for a later version of Xdebug.

Feature: Googleもしかして
  In order to see a word definition
  As a website user
  I need to be able to search for a word

  @javascript
  Scenario: Chromeは神かどうかのテスト                    # features/google.feature:8
    Given I am on "http://www.google.co.jp"
      Ambiguous match of "I am on "http://www.google.co.jp"":
      to `/^I am on "([^"]*)"$/` from FeatureContext::iAmOn()
      to `/^(?:|I )am on "(?P<page>[^"]+)"$/` from FeatureContext::visit()
    When I fill in "gbqfq" with "Chrome ゴミブラウザ"
      Ambiguous match of "I fill in "gbqfq" with "Chrome ゴミブラウザ"":
      to `/^I fill in "([^"]*)" with "([^"]*)"$/` from FeatureContext::iFillInWith()
      to `/^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/` from FeatureContext::fillField()
    And I click "btnK"                          # FeatureContext::iClick()
    Then I should see "Chrome ゴミブラウザ"
      Ambiguous match of "I should see "Chrome ゴミブラウザ"":
      to `/^I should see "([^"]*)"$/` from FeatureContext::iShouldSee()
      to `/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/` from FeatureContext::assertPageContainsText()

1 個のシナリオ (1 個失敗)
4 個のステップ (1 個スキップ, 3 個失敗)
0m0.025s
```

なにAmbiguousって。。。ググったら、以下が出た
http://vermelho.jugem.jp/?eid=135

多分、２重になってるから、FeatureContextの方はコメントアウトしろってことかなってことで、iAmOn、iShouldSee、iFillInWithはメソッドごとコメントアウトして実行

```
HIRATSUKA-no-MacBook-Air:mink20130506 shiratsu$ ./bin/behat
Xdebug requires Zend Engine API version 220090626.
The Zend Engine API version 220100525 which is installed, is newer.
Contact Derick Rethans at http://xdebug.org/docs/faq#api for a later version of Xdebug.

Feature: Googleもしかして
  In order to see a word definition
  As a website user
  I need to be able to search for a word

  @javascript
  Scenario: Chromeは神かどうかのテスト                    # features/google.feature:8
    Given I am on "http://www.google.co.jp"     # FeatureContext::visit()
    When I fill in "gbqfq" with "Chrome ゴミブラウザ" # FeatureContext::fillField()
    And I click "btnK"                          # FeatureContext::iClick()
    Then I should see "Chrome ゴミブラウザ"           # FeatureContext::assertPageContainsText()
      The text "Chrome ゴミブラウザ" was not found anywhere in the text of the current page.

1 個のシナリオ (1 個失敗)
4 個のステップ (3 個成功, 1 個失敗)
0m4.482s
```

最後失敗するけど、無事selenium組み合わせられました。
疲れた