Go to list of users who liked
Share on X(Twitter)
Share on Facebook
More than 5 years have passed since last update.
BehatはPHP製のBDDテストフレームワークです。
概要は下記スライドを見ておくといいでしょう。
http://www.slideshare.net/tchikuba/behatbdd
必要なライブラリのインストール
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":"*"}}behat/behat
behatの本体です。
テストシナリオを自然言語に近い形で記述し、実行する機能を提供します。
behat/mink
ブラウザのエミュレーションツールと組み合わせてテストを行う機能を提供します。
behatと組み合わせて利用することが可能です。
behat/mink-extension
behatで利用できるテストの機能を追加したり、テストケースで扱える言語を拡張したりします。
behat/mink-*-driver
behat+minkのテストでブラウザのエミュレーションツールを扱えるようにします。
上記サンプルではgoutte、shai、selenium、zombiejsをインストールしていますが、これらは全てインストールする必要はなく利用するブラウザのエミュレーションツールに対応したものをインストールすればいいです。
behatでテストを行うための準備
behatのテストシナリオを置きたいディレクトリに移動してvendor/bin/behat --initコマンドを実行します。
今回はproject/tests以下にbehatのテストを置いて行くことを前提にします。
コマンドを実行すると以下のようなファイルが配置されます。
project/ tests/ features/ bootstrap/ FeatureContext.phpbehat.ymlを用意する
behatでは実行のための設定をbehat.ymlというyaml形式の設定ファイルの記述していきます。
デフォルトではbehatコマンドの実行ディレクトリと同じ階層にあるbehat.ymlが読み込まれますが、-cオプションを利用することでbehat.ymlを読み込むパスを指定することも可能です。
今回はプロジェクトディレクトリ直下にbehat.ymlを置くことを想定します。
default:suites:default:path:%paths.base%/tests/featurescontexts:-FeatureContextpath
behatは、ここで指定したpathのテストシナリオを読み込んでテストを実行するようになります。
contexts
behatはここで指定したクラスの機能を利用してテストを実行します。
テストの作成と実行
テストはbehat.ymlのpathに指定したディレクトリ以下に作成していきます。
(今回はproject/tests/features/以下)
テストファイルの拡張子はfeatureである必要があります。
# language: jaフィーチャ: 空のテストシナリオ: 何もしない一行目は利用する言語の指定です。
デフォルトの状態ではテストケースが存在しないため、featureファイルにも何も記述していません。
この状態でbehatコマンドを実行するとテストが走ります。
フィーチャ: 空のテスト シナリオ: 何もしない # features\empty.feature:4No scenariosNo steps0m0.04s (10.34Mb)テストで利用可能なケースの確認
behatではテストケースをbehat.ymlのcontext以下に記述したクラスから読み込みます。
利用可能なテストケースはbehat -dlコマンドで確認出来ます。
デフォルトの状態では何もテストケースが登録されていないため、behat -dlコマンドを打っても何も表示されません。
Mink Extensionのテストケースを追加する
一からテストケースを作っていくのも辛いので、
冒頭でインストールしておいたMink Extensionが提供するテストケースを利用します。
default: suites: default: path: %paths.base%/tests/features contexts: - FeatureContext+ - Behat\MinkExtension\Context\MinkContext extensions: Behat\MinkExtension: base_url: http://google.com/この状態でbehat -dlコマンドを実行すると利用可能なテストケースが追加されていることが確認出来ます。
default | Given /^(?:|ユーザーは )ホームページを表示している$/default | When /^(?:|ユーザーは )ホームページへ移動する$/default | Given /^(?:|ユーザーは )"(?P<page>[^\s]+)" を表示している$/udefault | When /^(?:|ユーザーが )"(?P<page>[^\s]+)" へ移動する$/udefault | When /^(?:|ユーザーが )ページをリロードする$/u ・ ・ ・ブラウザのエミュレーションツールと合わせてE2Eテストを行う
googleのトップページから検索を行い、結果画面が表示されることを確認するテストシナリオを作成します。
# language: jaフィーチャ: グーグル検索シナリオ: recursionを検索前提 ホームページを表示しているもし"q" フィールドに"recursion" と入力するかつ"btnK" ボタンをクリックするならば "もしかして:recursion"と表示されていることブラウザのエミュレーションツールを利用するためには、behat.ymlを編集する必要があります。
default: suites: default: path: %paths.base%/tests/features contexts: - FeatureContext - Behat\MinkExtension\Context\MinkContext+ extensions:+ Behat\MinkExtension:+ base_url: http://google.com/+ sessions:+ default:+ selenium2: ~base_url
テスト対象のベースとなるURLを指定します。
Mink Extensionが提供するテストケースのうち、ホームページというキーワードはここで指定したURLを指します。
session
ここに利用するブラウザのエミュレーションツールを指定します。
この状態でbehatコマンドを実行するとテストが走ります。
結果は…
フィーチャ: グーグル検索 シナリオ: recursionを検索 # features\sample.feature:4 前提 ホームページを表示している # CustomContext::iAmOnHomepage() もし "q" フィールドに "recursion" と入力する # CustomContext::fillField() かつ "btnK" ボタンをクリックする # CustomContext::pressButton() ならば "もしかして: recursion" と表示されていること # CustomContext::assertPageContainsText() The text "もしかして: recursion" was not found anywhere in the text of the current page. (Behat\Mink\Exception\ResponseTextException)--- Failed scenarios: features\sample.feature:41 scenario (1 failed)4 steps (3 passed, 1 failed)0m5.97s (11.00Mb)テストケースを拡張する
先ほどのテストは検索結果の画面が表示される前に、"もしかして: recursion" と表示されていること というテストケースが走り、テストが失敗してしまいました。
画面が表示されるまで待つ、つまりn秒待つ というテストケースが必要になります。bootstrap/FeatureContext.phpを編集して新たにテストケースを加えます。
<?phpuseBehat\Behat\Context\Context;useBehat\Behat\Context\SnippetAcceptingContext;classFeatureContextimplementsContext,SnippetAcceptingContext{publicfunction__construct(){}/** * @When :time 秒待つ */publicfunctionwait($time){sleep($time);}} # language: ja フィーチャ: グーグル検索 シナリオ: recursionを検索 前提 ホームページを表示している もし "q" フィールドに "recursion" と入力する かつ "btnK" ボタンをクリックする+ かつ 1 秒待つ ならば "もしかして: recursion" と表示されていることこれでbehat -dlコマンドを実行するとテストケースが追加されていることが確認出来ます。
+ default | When :time 秒待つ default | Given /^(?:|ユーザーは )ホームページを表示している$/ default | When /^(?:|ユーザーは )ホームページへ移動する$/ default | Given /^(?:|ユーザーは )"(?P<page>[^\s]+)" を表示している$/u ・ ・ ・テストを実行すると今度はパスしました。
フィーチャ: グーグル検索 シナリオ: recursionを検索 # features\sample.feature:4 前提 ホームページを表示している # CustomContext::iAmOnHomepage() もし "q" フィールドに "recursion" と入力する # CustomContext::fillField() かつ "btnK" ボタンをクリックする # CustomContext::pressButton() かつ 1 秒待つ # FeatureContext::wait() ならば "もしかして: recursion" と表示されていること # CustomContext::assertPageContainsText()1 scenario (1 passed)5 steps (5 passed)0m9.29s (10.96Mb)所感
- テストシナリオが自然言語っていうのが嬉しい、エクセルテスト表とか書きたくないし、見たくもない。
- seleniumなどのエミュレーションツールを個別に起動しないといけないのが面倒
- behat公式サイトのドキュメントがバージョン2.5のままで、最新版と思って参考にしてしまうと大いにハマる
- テスト1回にかかる時間が長いのでpushやcommit時にテスト実行というやり方はキツイ気がする
- テスト1回にかかる時間が長いのでリリース頻度の高いサービスなどではリリースブランチにマージ前に実行というのもキツイ気がする(テスト実行時間の分リリースが後ろに伸びる、テストがパスしないとさらに長い時間かけてテストするステップを踏むのは辛い)
- テスト1回にかかる時間が長いので定期的に回す程度がいい?(そうすると誰のコミットでおかしくなったか分かりにくい)
実施できるならシステムの品質を保つのにかなり高い効果が上がると思うが、
実際に運用に組み込む場合の懸念が多いのが難点かな…
E2Eテストやってるところはこのあたり、どうやって解決してるんだろう?
Register as a new user and use Qiita more conveniently
- You get articles that match your needs
- You can efficiently read back useful information
- You can use dark theme