m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

phpの振る舞い駆動テストのbehat3をインストール

テストってあんまり好きじゃない

エビデンスペタペタ貼るの結構苦痛

振る舞い駆動開発フレームワークのライブラリ

Behat Documentation — Behat 3.0.12 documentation
どんなんかはまだ良くわかっていないけどなんかやってみようと思った

インストール

composerで入れます
[vagrant@localhost ~]$ mkdir -p sample1;cd $_
[vagrant@localhost sample1]$ composer require --dev "behat/behat:3.*" --prefer-dist
[vagrant@localhost sample1]$ composer require --dev "behat/mink:1.*" --prefer-dist
[vagrant@localhost sample1]$ composer require --dev "behat/mink-extension:*" --prefer-dist
[vagrant@localhost sample1]$ composer require --dev "behat/mink-goutte-driver:*" --prefer-dist
[vagrant@localhost sample1]$ composer require --dev "behat/mink-sahi-driver:*" --prefer-dist
[vagrant@localhost sample1]$ composer require --dev "behat/mink-selenium2-driver:*" --prefer-dist
[vagrant@localhost sample1]$ composer require --dev "behat/mink-zombie-driver:*" --prefer-dist
[vagrant@localhost sample1]$ composer require "phpunit/phpunit:*" --prefer-dist

※今回はcomposerで入れてみました

composer.json
[vagrant@localhost sample1]$ cat composer.json
{
    "require-dev": {
        "behat/behat": "3.*",
        "behat/mink": "1.*",
        "behat/mink-extension": "*",
        "behat/mink-goutte-driver": "*",
        "behat/mink-sahi-driver": "*",
        "behat/mink-selenium2-driver": "*",
        "behat/mink-zombie-driver": "*"
    },
    "require": {
        "phpunit/phpunit": "*"
    }
}
[vagrant@localhost sample1]$

※あらかじめこれを作成していれても良い

インストール参考URL

PHP製BDDテストフレームワークBehatでE2Eテスト - Qiita
※必要そうなものはこちらより取得

バージョン

[vagrant@localhost sample1]$ ./vendor/bin/behat -V
behat version 3.0.15
[vagrant@localhost sample1]$

初期化

[vagrant@localhost sample1]$ ./vendor/bin/behat --init
+d features - place your *.feature files here
+d features/bootstrap - place your context classes here
+f features/bootstrap/FeatureContext.php - place your definitions, transformations and hooks here

[vagrant@localhost sample1]$

[vagrant@localhost sample1]$ tree features/
features/
└── bootstrap
    └── FeatureContext.php

1 directory, 1 file
[vagrant@localhost sample1]$

テストケース作成

振る舞いの作業を文章で入力できるようにしたものらしい

以下例

test1.feature
[vagrant@localhost sample1]$ vi features/test1.feature
# language: ja
フィーチャ: サンプルテスト
  シナリオ: とりあえずテスト
    もし "a" に "1" と入力する
    ならば "a" に "1" と設定されていること
実行
[vagrant@localhost sample1]$ vi features/test1.feature
[vagrant@localhost sample1]$ ./vendor/bin/behat
フィーチャ: サンプルテスト

  シナリオ: とりあえずテスト             # features/test1.feature:3
    もし "a" に "1" と入力する
    ならば "a" に "1" と設定されていること

1 scenario (1 undefined)
2 steps (2 undefined)
0m0.02s (10.59Mb)

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

    /**
     * @When :arg1 に :arg2 と入力する
     */
    public function niToruLiSuru($arg1, $arg2)
    {
        throw new PendingException();
    }

    /**
     * @Then :arg1 に :arg2 と設定されていること
     */
    public function niTosheDingSareteirukoto($arg1, $arg2)
    {
        throw new PendingException();
    }

[vagrant@localhost sample1]$

こんな感じになります。
まだ、フィーチャファイルを作成しただけですのでテストにはなりません。

features/bootstrap/FeatureContext.php
<?php

use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
use Behat\Behat\Tester\Exception\PendingException;

/**
 * Defines application features from the specific context.
 */
class FeatureContext implements Context, SnippetAcceptingContext
{
    /**
     * Initializes context.
     *
     * Every scenario gets its own context instance.
     * You can also pass arbitrary arguments to the
     * context constructor through behat.yml.
     */
    public function __construct()
    {
    }

    /**
     * @When :arg1 に :arg2 と入力する
     */
    public function niToruLiSuru($arg1, $arg2)
    {
        throw new PendingException();
    }

    /**
     * @Then :arg1 に :arg2 と設定されていること
     */
    public function niTosheDingSareteirukoto($arg1, $arg2)
    {
        throw new PendingException();
    }

}

とりあえず実行

[vagrant@localhost sample1]$ ./vendor/bin/behat
フィーチャ: サンプルテスト

  シナリオ: とりあえずテスト             # features/test1.feature:3
    もし "a" に "1" と入力する       # FeatureContext::niToruLiSuru()
      TODO: write pending definition
    ならば "a" に "1" と設定されていること # FeatureContext::niTosheDingSareteirukoto()

1 scenario (1 pending)
2 steps (1 pending, 1 skipped)
0m0.01s (10.95Mb)
[vagrant@localhost sample1]$

この状態ではまだテスト内容を実装していないのでテスト内容を入れる

<?php

use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
use Behat\Behat\Tester\Exception\PendingException;

/**
 * Defines application features from the specific context.
 */
class FeatureContext implements Context, SnippetAcceptingContext
{

    private $items;

    /**
     * Initializes context.
     *
     * Every scenario gets its own context instance.
     * You can also pass arbitrary arguments to the
     * context constructor through behat.yml.
     */
    public function __construct()
    {
        $this->items = array();
    }

    /**
     * @When :arg1 に :arg2 と入力する
     */
    public function niToruLiSuru($arg1, $arg2)
    {
        $this->items[$arg1] = $arg2;
    }

    /**
     * @Then :arg1 に :arg2 と設定されていること
     */
    public function niTosheDingSareteirukoto($arg1, $arg2)
    {
        PHPUnit_Framework_Assert::assertEquals($this->items[$arg1], $arg2);
    }

}

データを設定する処理とチェックする処理を追加して再度実施

[vagrant@localhost sample1]$ ./vendor/bin/behat
フィーチャ: サンプルテスト

  シナリオ: とりあえずテスト             # features/test1.feature:3
    もし "a" に "1" と入力する       # FeatureContext::niToruLiSuru()
    ならば "a" に "1" と設定されていること # FeatureContext::niTosheDingSareteirukoto()

1 scenario (1 passed)
2 steps (2 passed)
0m0.02s (11.52Mb)
[vagrant@localhost sample1]$

とりあえずこんな感じ

所感

シナリオというかたちで日本語で定義できるのでどんなことに対してのテストかをある程度把握しやすい。
今回はテストデータ自体が単純なので参考にはならないライブラリや他のフレームワークなどでうまくいくかを少し検証する必要がありそう。

CakePHPで学ぶ継続的インテグレーション (impress top gear)

CakePHPで学ぶ継続的インテグレーション (impress top gear)