さて、第2回。
前回
今回はユーザーストーリーのお話。
ユーザーストーリー
◯◯として、××できる、なぜなら△△は▽▽したい(する)からだ
とまぁ、こういう箇条書きでアプリケーションの特徴を書き出すことを「ユーザーストーリー」と呼ぶらしい。
んで、今回はBDDで開発していくっとよ。
- ユーザーストーリーを定義
- 設計後、実装可能な単位に分割する
- 機能を実装 -> ユニットテストが成功する
- ユーザーストーリーのテストが成功する
図がありますが、ずっとグルグルする図になっています。
(なんかAmazonの図を思い出しました)
いまいちアジャイルのことがよくわかっていませんが、とりあえず進めることにします。
ユーザーストーリーの定義
本を読む。うんうん。なるほどね。(よくわからないワードがいっぱいでてきたぞー!!!!ヤベェ!)
とりあえず、箇条書きにまとめていく。
- BDDを使うお(^ω^
- BDDを使うにはDSL(ドメイン特化言語)を使うお(^ω^;
- DSLには「Gherkin(ガーキン)」とか「Cucumber(キューカンバー。。。きゅうり?)」、「Behat(?)」を使って自動実行していくお(°ω°;
ちょっと泣きそうです。なんか難しくない?
試してみる
機能や記法の説明から入っていますが、よくわかりませんので、とりあえず先に動かしてみます。
BDDプラグインのインストール
composer
を使ってインストール
- composer.json
$ cat composer.json { "name": "php_ci_book/blogapp", "authors": [ { "name": "test", "email": "test@gmail.com" } ], "config": { "vendor-dir":"Vendor" }, // ここから "repositories": [ { "type": "vcs", "url" : "git://github.com/sizuhiko/Bdd.git" } ], // ここまでを追加 "require": { "cakephp/cakephp": "2.6.*" }, // ここから "require-dev": { "pear/console_commandline": "@dev", "pear/pear_exception": "@dev", "sizuhiko/Bdd": "dev-master" } // ここまでも追加 }
$ composer require --dev sizuhiko/Bdd:dev-master ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) - Installing composer/installers (v1.0.21) Loading from cache - Installing symfony/yaml (v2.7.4) Downloading: 100% - Installing symfony/translation (v2.7.4) Downloading: 100% - Installing symfony/event-dispatcher (v2.7.4) Downloading: 100% - Installing symfony/dependency-injection (v2.7.4) Downloading: 100% - Installing symfony/filesystem (v2.7.4) Downloading: 100% - Installing symfony/config (v2.7.4) Downloading: 100% - Installing symfony/console (v2.7.4) Downloading: 100% - Installing symfony/finder (v2.7.4) Downloading: 100% - Installing behat/gherkin (v2.3.5) Downloading: 100% - Installing behat/behat (v2.5.5) Downloading: 100% - Installing behat/common-contexts (v1.2.0) Downloading: 100% - Installing phpunit/php-text-template (1.2.1) Loading from cache - Installing phpunit/phpunit-mock-objects (1.2.3) Loading from cache - Installing phpunit/php-timer (1.0.7) Loading from cache - Installing phpunit/php-file-iterator (1.4.1) Loading from cache - Installing phpunit/php-token-stream (1.2.2) Loading from cache - Installing phpunit/php-code-coverage (1.2.18) Loading from cache - Installing phpunit/phpunit (3.7.38) Loading from cache - Installing hamcrest/hamcrest-php (v1.1.1) Downloading: 100% - Installing pear/pear_exception (dev-master 8c18719) Cloning 8c18719fdae000b690e3912be401c76e406dd13b - Installing pear/console_commandline (dev-trunk 18ac06e) Cloning 18ac06ef5d0ea4db3522b1d0b5869547f0aac933 - Installing sizuhiko/spec-php (0.9.6.2) Downloading: 100% - Installing symfony/css-selector (v2.7.4) Downloading: 100% - Installing behat/mink (v1.5.0) Downloading: 100% - Installing behat/mink-extension (v1.2.0) Downloading: 100% - Installing sizuhiko/bdd (dev-master 58e4431) Cloning 58e44318a62fbd0a79d7cf6cbea1e7fcc4877871 # ~ 省略 ~ Writing lock file Generating autoload files
すげー色々落ちてきた。
Package guzzle/common is abandoned, you should avoid using it. Use guzzle/guzzle instead. Package guzzle/stream is abandoned, you should avoid using it. Use guzzle/guzzle instead. Package guzzle/parser is abandoned, you should avoid using it. Use guzzle/guzzle instead. Package guzzle/http is abandoned, you should avoid using it. Use guzzle/guzzle instead.
このエラーはよくわからん。のでぐぐったら、どうやらライブラリが足りないらしい。。。(多分)
なので、こいつもインストール
$ composer require guzzle/guzzle:~3.9
あと、ついでにこのプラグインもインストールしておいてね。だって。
$ composer require --dev behat/mink-goutte-driver:*
ロード設定
- ~/Config/bootstrap/environments/development.php
<?php Environment::configure('development', true, [ 'MYSQL_DB_HOST' => 'localhost', 'MYSQL_USERNAME' => 'xxx', 'MYSQL_PASSWORD' => 'xxx', 'MYSQL_DB_NAME' => 'db_name', 'MYSQL_TEST_DB_NAME' => 'test_db_name', 'MYSQL_PREFIX' => '' // ここから追記 ], function() { CakePlugin::load('Bdd'); });
こんな書き方もできるのね。(普通か)
んで、プラグインの初期構築のためcake
を実行する
$ ./Console/cake Bdd.init
behat.yml
が自動生成されます。ファイルを修正します。
default: paths: features: ../../features extensions: Behat\MinkExtension\Extension: base_url: 'http://test.localhost:8888/application-name/' # ここを修正します。 goutte: guzzle_parameters: request.params: redirect.disable: true # # switch disable followings if use behat/mink-selenium2-driver # # selenium: ~ # ここはコメントアウト # javascript_session: selenium # ここも # # switch enable followings if use behat/mink-selenium2-driver # # javascript_session: selenium2 # browser_name: 'firefox' # selenium2: # capabilities: { "browser": "firefox"}
おお!selenium
も使えるのね。
最後に追加したプラグインをコミットします。
プラグインを実行してみる
実行してみます。
と、ここで事件が
$ ./Console/cake Bdd.story --help Welcome to CakePHP v2.6.11 Console --------------------------------------------------------------- App : cakephp_integlation Path: /Users/git/cakephp_integlation/ --------------------------------------------------------------- /Users/git/cakephp_integlation/Plugin/BddPHP Fatal error: Class 'Behat\Behat\Console\BehatApplication' not found in /Users/git/cakephp_integlation/Plugin/Bdd/Console/Command/StoryShell.php on line 28 Fatal error: Class 'Behat\Behat\Console\BehatApplication' not found in /Users/git/cakephp_integlation/Plugin/Bdd/Console/Command/StoryShell.php on line 28 Fatal Error Error: Class 'Behat\Behat\Console\BehatApplication' not found in [/Users/git/cakephp_integlation/Plugin/Bdd/Console/Command/StoryShell.php, line 28]
・・・・???
どうやら、autoload.php
のパスが違うらしい
2つのファイルの1~10行目あたりにある、autoload.php
の読み込み箇所を変更する
- ~/Plugin/Bdd/Console/Command/SpecShell.php
<?php // ~ 省略 ~ if(file_exists(dirname(dirname(dirname(__FILE__))).DS.'..'.DS.'..'.DS.'vendor/autoload.php')) { require dirname(dirname(dirname(__FILE__))).DS.'..'.DS.'..'.DS.'vendor/autoload.php'; }
- ~/Plugin/Bdd/Console/Command/StoryShell.php
<?php // ~ 省略 ~ if(file_exists(dirname(dirname(dirname(__FILE__))).DS.'..'.DS.'..'.DS.'vendor/autoload.php')) { require dirname(dirname(dirname(__FILE__))).DS.'..'.DS.'..'.DS.'vendor/autoload.php'; }
変更後実行すると、問題なかった。
$ ./Console/cake Bdd.story --help Welcome to CakePHP v2.6.11 Console --------------------------------------------------------------- App : cakephp_integlation Path: /Users/git/cakephp_integlation/ --------------------------------------------------------------- /Users/git/cakephp_integlation/Plugin/BddUsage: behat [--init] [-f|--format="..."] [--out="..."] [--lang="..."] [--[no-]ansi] [--[no-]time] [--[no-]paths] [--[no-]snippets] [--[no-]snippets-paths] [--[no-]multiline] [--[no-]expand] [--story-syntax] [-d|--definitions="..."] [--name="..."] [--tags="..."] [--cache="..."] [--strict] [--dry-run] [--stop-on-failure] [--rerun="..."] [--append-snippets] [--append-to="..."] [features] Arguments: features Feature(s) to run. Could be: - a dir (features/)
フィーチャを記述する
- ~/Plugin/Bdd/features/blog_new_post.feature
# langage: ja フィーチャ: 会員として新しい記事を投稿できる、なぜなら会員は自分の言葉で発信したいからだ 背景: 前提 "会員" としてログインしている シナリオ: 新しい記事を投稿できる もし 以下の内容で記事を投稿する | タイトル | はじめてのブログ | | 本文 | はじめまして | ならば 新しい記事が登録されていること シナリオ: タイトルなしでは新しい記事は投稿できない もし 以下の内容で記事を投稿する | タイトル | | | 本文 | はじめまして | ならば 新しい記事が登録できないこと
実行。ムッ?
$ ./Console/cake Bdd.story Welcome to CakePHP v2.6.11 Console --------------------------------------------------------------- App : cakephp_integlation Path: /Users/git/cakephp_integlation/ --------------------------------------------------------------- /Users/git/cakephp_integlation/Plugin/Bdd [Behat\Gherkin\Exception\ParserException] Expected Comment or Scenario or Outline or Step token, but got Text on line: 2 in file: /Users/git/cakephp_integlation/Plugin/Bdd/features/blog_new_post.feature
・・・・? あ
- ~/Plugin/Bdd/features/blog_new_post.feature
# language: ja
language
のu
が間違えていたようです。
修正し、再度実行
$ ./Console/cake Bdd.story Welcome to CakePHP v2.6.11 Console --------------------------------------------------------------- App : cakephp_integlation Path: /Users/git/cakephp_integlation/ --------------------------------------------------------------- /Users/git/cakephp_integlation/Plugin/Bddフィーチャ: 会員として新しい記事を投稿できる、なぜなら会員は自分の言葉で発信したいからだ 背景: # /Users/git/cakephp_integlation/Plugin/Bdd/features/blog_new_post.feature:3 前提 "会員" としてログインしている シナリオ: 新しい記事を投稿できる # /Users/git/cakephp_integlation/Plugin/Bdd/features/blog_new_post.feature:5 もし 以下の内容で記事を投稿する | タイトル | はじめてのブログ | | 本文 | はじめまして | ならば 新しい記事が登録されていること シナリオ: タイトルなしでは新しい記事は投稿できない # /Users/git/cakephp_integlation/Plugin/Bdd/features/blog_new_post.feature:10 もし 以下の内容で記事を投稿する | タイトル | | | 本文 | はじめまして | ならば 新しい記事が登録できないこと 2 個のシナリオ (2 個未定義) 6 個のステップ (6 個未定義) 0m0.045s 未定義のステップを、次のスニペットで実装できます: $steps->Given('/^"([^"]*)" としてログインしている$/', function($world, $arg1) { throw new \Behat\Behat\Exception\PendingException(); }); $steps->Given('/^以下の内容で記事を投稿する$/', function($world, $table) { throw new \Behat\Behat\Exception\PendingException(); }); $steps->Given('/^新しい記事が登録されていること$/', function($world) { throw new \Behat\Behat\Exception\PendingException(); }); $steps->Given('/^新しい記事が登録できないこと$/', function($world) { throw new \Behat\Behat\Exception\PendingException(); });
うむむ。。。いまいちよくわからん。。。w (^^;
あともうひとつ作成します。
- ~/Plugin/Bdd/features/blog_posts.feature
# language: ja フィーチャ: 会員として記事を一覧表示できる、なぜなら会員はこれまでに書いた記事をまとめて確認したいからだ 背景: 前提 "会員" としてログインしている シナリオ: 記事を一覧表示できる 前提 記事が9件登録されている もし 自分の投稿を一覧表示する ならば ページ 1 に投稿が新しい順で 5 件表示されている かつ ページ 2 に投稿が新しい順で 4 件表示されている
これで、おk.最後に作成したファイルをコミットしましょう。
今回はここまで。
いまいち何ができるかなんてピンと来ないけど、これが役に建つんだろうね( ´_ゝ`)
ユーザーストーリーの書き方は別記事でまとめようかな。
これまでの記事
参考書籍
- 作者: 渡辺一宏,吉羽龍太郎,岸田健一郎,穴澤康裕
- 出版社/メーカー: インプレス
- 発売日: 2015/01/14
- メディア: Kindle版
- この商品を含むブログを見る
CakePHPで学ぶ継続的インテグレーション (impress top gear)
- 作者: 渡辺一宏,吉羽龍太郎,岸田健一郎,穴澤康裕,丸山弘詩
- 出版社/メーカー: インプレス
- 発売日: 2014/09/19
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る