SlideShare a Scribd company logo
第65回 PHP勉強会
 @東京(Engine Yard)

behat/PHPUnitで始める
     BDD/TDD


2013/02/28(木)   @ビルコム
前置き。
about tchikuba
• 所属
   – ビルコム株式会社
• 自社サービス
   – ReBuy http://rebuy.jp/
   – Okkru https://okkru.jp
• 役割
   – 開発Playing Manager
• いいね!
   – Linux、ビール、宇宙平和
• facebook/twitter
   – tchikuba
ReBuy:facebookコマースアプリ
Okkru:ソーシャルギフト
我々の諸環境
•   OS:CentOS(nifty cloud)
•   Webサーバ:Nginx/Apache
•   DBサーバ:MySQL
•   CIサーバ:Jenkins/SeleniumServer
•   言語:PHP
•   フレームワーク:Zendframework
•   フロント:jQuery(Mobile)
•   SCM:Git
•   BTS:Backlog
聞きたいこと。




•開発プロセス?
•BDD/TDD?
本題。
TDDとは
• Test-Driven Developmentの

• 和訳:テスト駆動開発

• 特徴
  – テストファースト
  – リファクタリング


• メリット
  – スパゲッティの塩分低下
  – 開発アジリティ上昇
BDDとは
• Behavior-Driven Developmentの

• 和訳:振舞駆動開発

• 特徴
  – 自然言語
  – 要求仕様(スペック)


• メリット
  –  け れ 厙
  – オブジェクト指向強化
BDD/TDDのフレームワーク
  • BDD
   – behat + mink
   – PHPSpec
   – Selenium


  • TDD
   – PHPUnit
PHPUnit。
behat。
behat環境設定
• インストール (PHP5.3.4 ≧推奨)
 – Composer
   • vi composer.json
   • curl http://getcomposer.org/installer | php
   • php composer.phar install
 – PHAR
 – Git
• 初期プロジェクト生成
 – behat --init
ディレクトリ構成
• behat_root/
  – features/
     • bootstrap/
        – FeatureContext.php
     • *.feature
  – behat.yml
  – build.xml *for Jenkins

• *.feature:機能+シナリオ(複数可)
• FeatureContext.php:テスト定義
• bootstrap配下はオートロードされる
く却 コマンド
• テスト
 – behat [features/*.feature]


• コンテキスト一覧
 – behat –dl


• スニペット生成
 – behat –f snippets
featureの
Feature: facebook login
  facebook login

  @javascript
  Scenario: facebook login
    Given on facebook login page.
    When input email and password.
    And     press login button
    Then facebook logged in.
Contextの
<?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;

class FacebookloginContext extends BehatContext
{
   public $mink;

  public function __construct($mink)
  {
     $this->mink = $mink;
  }
(続く)
Contextの
  /**
   * @Given /^on facebook login page¥.$/
   */
  public function onFacebookLoginPage()
  {
     $this->mink->getSession()-
   >visit('http://www.facebook.com/login.php');
  }

  /**
   * @When /^input email and password¥.$/
   */
  public function inputEmailAndPassword()
  {
     $this->mink->getSession()->getPage()->fillField('email',
   MAIN_EMAIL);
     $this->mink->getSession()->getPage()->fillField('pass',
   PASSWORD);
  }
(続く)
Contextの
  /**
   * @Given /^press login button$/
   */
  public function pressLoginButton()
  {
     $this->mink->getSession()->getPage()->pressButton('Log In');
  }

  /**
   * @Then /^facebook logged in¥.$/
   */
  public function facebookLoggedIn()
  {
     assertEquals('https://www.facebook.com/', $this->mink-
   >getSession()->getCurrentUrl());
  }
}
(終わり)
FeatureContextの
<?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¥MinkContext;

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

  public $base_url;
  public $mink;
FeatureContextの
     public function __construct(array $parameters)
    {
       // Initialize your context here
       $driver = new ¥Behat¥Mink¥Driver¥Selenium2Driver(
                    SELENIUM2_BROWSER, null, SELENIUM2_URL
       );
       $session = new ¥Behat¥Mink¥Session($driver);
       $this->base_url = OKKRU_BASE_URL;
       $mink = new ¥Behat¥Mink¥Mink();
       $mink->registerSession('okkru', $session);
       $mink->setDefaultSessionName('okkru');
       $this->mink = $mink;

        // use other context
        $this->useContext('fbconnect', new FbconnectContext($mink));
        $this->useContext('facebooklogin', new FacebookloginContext($mink));
        $this->useContext('sendme', new SendmeContext($mink));
        $this->useContext('inputme', new InputmeContext($mink));
        $this->useContext('ticketsend', new TicketsendContext($mink));
        $this->useContext('ticketrecipient', new TicketrecipientContext($mink));
    }

}
り             な           :feature
Feature: sendme
  商品を自分で受け取ることが出来る。

 @javascript
 Scenario: 商品を自分贈りで購入する。
   Given テスト用商品ページにアクセスする。
   When 購入ボタンを押下する。
   Then ログイン画面に遷移する。
   When ログインボタンを押下する。
   Then facebookログインページに遷移する。
   When facebookログインする。
   Then 友人選択画面に遷移する。
   When 友人選択画面で自分贈りを選択する。
   Then 自分の住所情報が入 出来る。
   And     FBから引いた情報が補完されている。
   When 自分の住所情報を入 する。
   And     確認ボタンを押下する。
   Then 確認画面に入       卣が勖単される。
   When 確定ボタンを押下する。
   Then 決済画面に遷移する。
り                    な               :Context
<?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;

class SendmeContext extends BehatContext
{

  public $base_url;
  public $mink;

  public function __construct($mink)
  {
     $this->base_url = OKKRU_BASE_URL;
     $this->mink = $mink;
  }
(続く)
り                    な                :Context
/**
   * @Given /^テスト用商品ページにアクセスする。$/
   */
  public function accessDetail()
  {
      $this->mink->getSession()->visit($this->base_url .
   '/fbec_front/gift/detail/shop_id/' . SHOP_ID . '/product_id/' .
   PRODUCT_ID);
  }

  /**
   * @When /^購入ボタンを押下する。$/
   */
  public function pressProductButton()
  {
     $this->mink->getSession()->getPage()->clickLink('product-
   button');
  }
り                   な              :Context
/**
   * @Then /^ログイン画面に遷移する。$/
   */
  public function assertDetail2FBlogin()
  {
     $this->mink->assertSession()-
   >addressMatches("/fbec_front¥/gift¥/login¥/url/");
  }

  /**
   * @When /^ログインボタンを押下する。$/
   */
  public function pressConnectButton()
  {
     $this->mink->getSession()->wait(3000, "$('#login_btn').length
   > 0");
     $this->mink->getSession()->getPage()->clickLink('login_btn');
  }
り                         な                   :Context
/**
   * @Then /^facebookログインページに遷移する。$/
   */
  public function assertFBConnect2FBLogin()
  {
     $expected_url = 'https://www.facebook.com';
     $this->mink->getSession()->wait(3000);
     $actual_url = $this->mink->getSession()->getCurrentUrl();
     $this->getMainContext()->getSubContext('fbconnect')->assertContainUrl($expected_url,
    $actual_url);
  }

 /**
  * @When /^facebookログインする。$/
  */
 public function facebookLogin()
 {
    $this->getMainContext()->getSubContext('facebooklogin')->inputEmailAndPassword();
    $this->getMainContext()->getSubContext('facebooklogin')->pressLoginButton();
 }
り                  な               :Context
/**
   * @Then /^友人選択画面に遷移する。$/
   */
  public function displayFriendsSelect()
  {
     $this->mink->assertSession()-
   >addressMatches("/fbec_front¥/gift¥/friends¥/shop_id¥/" .
   SHOP_ID . "/");
  }

  /**
   * @When /^友人選択画面で自分贈りを選択する。$/
   */
  public function selectBuymyself()
  {
     $this->mink->getSession()->getPage()->clickLink('buymyself-
   button');
  }
り                       な                   :Context
/**
   * @Then /^自分の住所情報が入 出来る。$/
   */
  public function assertInputMyAddress()
  {
     $this->mink->assertSession()->pageTextContains('※贈り主情報:フリガナ');
     $this->mink->assertSession()->pageTextContains('※贈り主情報:メールアドレス');
     $this->mink->assertSession()->pageTextContains('※お届け先:   番号');
     $this->mink->assertSession()->pageTextContains('※お届け先:都道府県');
     $this->mink->assertSession()->pageTextContains('※お届け先:住所');
     $this->mink->assertSession()->pageTextContains('※お届け先:電話番号');
  }

 /**
  * @Given /^FBから引いた情報が補完されている。$/
  */
 public function assertSetFBinfo()
 {
    assertEquals(LAST_NAME_FB, $this->mink->getSession()->getPage()-
   >findById('last_name')->getValue());
    assertEquals(FIRST_NAME_FB, $this->mink->getSession()->getPage()-
   >findById('first_name')->getValue());
    assertEquals(MAIN_EMAIL, $this->mink->getSession()->getPage()->findById('email')-
   >getValue());
 }
り                              な                       :Context
/**
   * @When /^自分の住所情報を入 する。$/
   */
  public function inputMyAddress()
  {
     $this->mink->getSession()->getPage()->fillField('last_name', LAST_NAME_INPUT);
     $this->mink->getSession()->getPage()->fillField('first_name', FIRST_NAME_INPUT);
     $this->mink->getSession()->getPage()->fillField('last_name_kana', LAST_NAME_KANA);
     $this->mink->getSession()->getPage()->fillField('first_name_kana', FIRST_NAME_KANA);
     $this->mink->getSession()->getPage()->fillField('email', INPUT_EMAIL);
     $this->mink->getSession()->getPage()->fillField('zip3', ZIP3);
     $this->mink->getSession()->getPage()->fillField('zip4', ZIP4);
     $this->mink->getSession()->getPage()->selectFieldOption('prefecture', PREFECTURE);
     $this->mink->getSession()->getPage()->fillField('address', ADDRESS);
     $this->mink->getSession()->getPage()->fillField('address2', ADDRESS2);
     $this->mink->getSession()->getPage()->fillField('phone1', PHONE1);
     $this->mink->getSession()->getPage()->fillField('phone2', PHONE2);
     $this->mink->getSession()->getPage()->fillField('phone3', PHONE3);
     $this->mink->getSession()->getPage()->fillField('note', NOTE_SENDME);
  }

 /**
  * @Given /^確認ボタンを押下する。$/
  */
 public function pressSubmitShipmentButton()
 {
    $this->mink->getSession()->getPage()->clickLink('submit-shipment');
 }
り                       な                 :Context
/**
   * @Then /^確認画面に入             卣が勖単される。$/
   */
  public function assertDisplayInput()
  {
     $this->mink->assertSession()->pageTextContains(PRODUCT_NAME);
     $this->mink->assertSession()->pageTextContains(SHOP_NAME);
     $this->mink->assertSession()->pageTextContains(PRODUCT_PRICE);
     $this->mink->assertSession()->pageTextContains(PRODUCT_AND_WRAPPING_PRICE);
     $this->mink->assertSession()->pageTextContains(PRODUCT_ALL_PRICE);
     $this->mink->assertSession()->pageTextContains(LAST_NAME_INPUT . ' ' .
    FIRST_NAME_INPUT);
     $this->mink->assertSession()->pageTextContains(LAST_NAME_KANA . ' ' .
    FIRST_NAME_KANA);
     $this->mink->assertSession()->pageTextContains(INPUT_EMAIL);
     $this->mink->assertSession()->pageTextContains(ZIP3 . '-' . ZIP4);
     $this->mink->assertSession()->pageTextContains(PREFECTURE);
     $this->mink->assertSession()->pageTextContains(ADDRESS);
     $this->mink->assertSession()->pageTextContains(ADDRESS2);
     $this->mink->assertSession()->pageTextContains(PHONE1 . '-' . PHONE2 . '-' .
    PHONE3);
     $this->mink->assertSession()->pageTextContains(NOTE_SENDME);
  }
り                      な                   :Context
/**
   * @When /^確定ボタンを押下する。$/
   */
  public function pressSubmitConfirm()
  {
     $this->mink->getSession()->getPage()->clickLink('submit-confirm');
  }

    /**
     * @Then /^決済画面に遷移する。$/
     */
    public function assertConfirm2SBPS()
    {
       $this->mink->getSession()->wait(5000, 'typeof window.jQuery == "function"');
       $this->mink->getSession()->wait(3000, 'window.document.getElementById("#title") >
      0');
       $this->mink->assertSession()->addressMatches("/¥/f01¥/FepBuyInfoReceive.do/");
    }

}
でも。
まとめ
• メリット
  – BDDで「なんちゃって」アジャイルを回避
  – behatでテストファーストすることで事前の洗い出しが
         に


• デメリット
  – スケジュールに追われる場合後回しになりがちで開発
    プロセスを徹底するのが難しい
  – CIサーバに る定期  でアンドン化して 続メンテ
    ナンスしないと無効なテストケースが増殖
\(^o^)/オワタ
  facebook/twitterアカウント:tchikuba

More Related Content

What's hot

[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)
[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)
[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)Amazon Web Services Japan
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
Masatoshi Tada
 
SQLアンチパターン~ファントムファイル
SQLアンチパターン~ファントムファイルSQLアンチパターン~ファントムファイル
SQLアンチパターン~ファントムファイル
Itabashi Masayuki
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用
nagise
 
AWS Black Belt Techシリーズ Amazon VPC
AWS Black Belt Techシリーズ Amazon VPCAWS Black Belt Techシリーズ Amazon VPC
AWS Black Belt Techシリーズ Amazon VPC
Amazon Web Services Japan
 
Zabbixのパフォーマンスチューニング & インストール時の注意点
Zabbixのパフォーマンスチューニング & インストール時の注意点Zabbixのパフォーマンスチューニング & インストール時の注意点
Zabbixのパフォーマンスチューニング & インストール時の注意点
Kodai Terashima
 
EC2でkeepalived+LVS(DSR)
EC2でkeepalived+LVS(DSR)EC2でkeepalived+LVS(DSR)
EC2でkeepalived+LVS(DSR)Sugawara Genki
 
AWS IoT Coreを オンプレミス環境と使う際の アーキテクチャ例 (AWS IoT Deep Dive #5)
AWS IoT Coreを オンプレミス環境と使う際の アーキテクチャ例 (AWS IoT Deep Dive #5)AWS IoT Coreを オンプレミス環境と使う際の アーキテクチャ例 (AWS IoT Deep Dive #5)
AWS IoT Coreを オンプレミス環境と使う際の アーキテクチャ例 (AWS IoT Deep Dive #5)
Amazon Web Services Japan
 
20210216 AWS Black Belt Online Seminar AWS Database Migration Service
20210216 AWS Black Belt Online Seminar AWS Database Migration Service20210216 AWS Black Belt Online Seminar AWS Database Migration Service
20210216 AWS Black Belt Online Seminar AWS Database Migration Service
Amazon Web Services Japan
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
NTT DATA Technology & Innovation
 
What's new in Spring Boot 2.6 ?
What's new in Spring Boot 2.6 ?What's new in Spring Boot 2.6 ?
What's new in Spring Boot 2.6 ?
土岐 孝平
 
YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)
YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)
YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)
NTT DATA Technology & Innovation
 
20190424 AWS Black Belt Online Seminar Amazon Aurora MySQL
20190424 AWS Black Belt Online Seminar Amazon Aurora MySQL20190424 AWS Black Belt Online Seminar Amazon Aurora MySQL
20190424 AWS Black Belt Online Seminar Amazon Aurora MySQL
Amazon Web Services Japan
 
20200826 AWS Black Belt Online Seminar AWS CloudFormation
20200826 AWS Black Belt Online Seminar AWS CloudFormation 20200826 AWS Black Belt Online Seminar AWS CloudFormation
20200826 AWS Black Belt Online Seminar AWS CloudFormation
Amazon Web Services Japan
 
Laravelとテストについて
LaravelとテストについてLaravelとテストについて
Laravelとテストについて
Takeo Noda
 
Dockerを利用したローカル環境から本番環境までの構築設計
Dockerを利用したローカル環境から本番環境までの構築設計Dockerを利用したローカル環境から本番環境までの構築設計
Dockerを利用したローカル環境から本番環境までの構築設計
Koichi Nagaoka
 
ルータコンフィグのGit管理のススメ 〜Git管理以外を自動化してみた〜
ルータコンフィグのGit管理のススメ 〜Git管理以外を自動化してみた〜ルータコンフィグのGit管理のススメ 〜Git管理以外を自動化してみた〜
ルータコンフィグのGit管理のススメ 〜Git管理以外を自動化してみた〜
Taiji Tsuchiya
 
入社1年目のプログラミング初心者がSpringを学ぶための手引き
入社1年目のプログラミング初心者がSpringを学ぶための手引き入社1年目のプログラミング初心者がSpringを学ぶための手引き
入社1年目のプログラミング初心者がSpringを学ぶための手引き
土岐 孝平
 
Ansible 2.8 アップデート情報 -機能追加と注意点-
Ansible 2.8 アップデート情報 -機能追加と注意点-Ansible 2.8 アップデート情報 -機能追加と注意点-
Ansible 2.8 アップデート情報 -機能追加と注意点-
akira6592
 
MongoDBの監視
MongoDBの監視MongoDBの監視
MongoDBの監視
Tetsutaro Watanabe
 

What's hot (20)

[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)
[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)
[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
 
SQLアンチパターン~ファントムファイル
SQLアンチパターン~ファントムファイルSQLアンチパターン~ファントムファイル
SQLアンチパターン~ファントムファイル
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用
 
AWS Black Belt Techシリーズ Amazon VPC
AWS Black Belt Techシリーズ Amazon VPCAWS Black Belt Techシリーズ Amazon VPC
AWS Black Belt Techシリーズ Amazon VPC
 
Zabbixのパフォーマンスチューニング & インストール時の注意点
Zabbixのパフォーマンスチューニング & インストール時の注意点Zabbixのパフォーマンスチューニング & インストール時の注意点
Zabbixのパフォーマンスチューニング & インストール時の注意点
 
EC2でkeepalived+LVS(DSR)
EC2でkeepalived+LVS(DSR)EC2でkeepalived+LVS(DSR)
EC2でkeepalived+LVS(DSR)
 
AWS IoT Coreを オンプレミス環境と使う際の アーキテクチャ例 (AWS IoT Deep Dive #5)
AWS IoT Coreを オンプレミス環境と使う際の アーキテクチャ例 (AWS IoT Deep Dive #5)AWS IoT Coreを オンプレミス環境と使う際の アーキテクチャ例 (AWS IoT Deep Dive #5)
AWS IoT Coreを オンプレミス環境と使う際の アーキテクチャ例 (AWS IoT Deep Dive #5)
 
20210216 AWS Black Belt Online Seminar AWS Database Migration Service
20210216 AWS Black Belt Online Seminar AWS Database Migration Service20210216 AWS Black Belt Online Seminar AWS Database Migration Service
20210216 AWS Black Belt Online Seminar AWS Database Migration Service
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
 
What's new in Spring Boot 2.6 ?
What's new in Spring Boot 2.6 ?What's new in Spring Boot 2.6 ?
What's new in Spring Boot 2.6 ?
 
YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)
YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)
YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)
 
20190424 AWS Black Belt Online Seminar Amazon Aurora MySQL
20190424 AWS Black Belt Online Seminar Amazon Aurora MySQL20190424 AWS Black Belt Online Seminar Amazon Aurora MySQL
20190424 AWS Black Belt Online Seminar Amazon Aurora MySQL
 
20200826 AWS Black Belt Online Seminar AWS CloudFormation
20200826 AWS Black Belt Online Seminar AWS CloudFormation 20200826 AWS Black Belt Online Seminar AWS CloudFormation
20200826 AWS Black Belt Online Seminar AWS CloudFormation
 
Laravelとテストについて
LaravelとテストについてLaravelとテストについて
Laravelとテストについて
 
Dockerを利用したローカル環境から本番環境までの構築設計
Dockerを利用したローカル環境から本番環境までの構築設計Dockerを利用したローカル環境から本番環境までの構築設計
Dockerを利用したローカル環境から本番環境までの構築設計
 
ルータコンフィグのGit管理のススメ 〜Git管理以外を自動化してみた〜
ルータコンフィグのGit管理のススメ 〜Git管理以外を自動化してみた〜ルータコンフィグのGit管理のススメ 〜Git管理以外を自動化してみた〜
ルータコンフィグのGit管理のススメ 〜Git管理以外を自動化してみた〜
 
入社1年目のプログラミング初心者がSpringを学ぶための手引き
入社1年目のプログラミング初心者がSpringを学ぶための手引き入社1年目のプログラミング初心者がSpringを学ぶための手引き
入社1年目のプログラミング初心者がSpringを学ぶための手引き
 
Ansible 2.8 アップデート情報 -機能追加と注意点-
Ansible 2.8 アップデート情報 -機能追加と注意点-Ansible 2.8 アップデート情報 -機能追加と注意点-
Ansible 2.8 アップデート情報 -機能追加と注意点-
 
MongoDBの監視
MongoDBの監視MongoDBの監視
MongoDBの監視
 

Viewers also liked

Behat+Symfony2ではじめるBDD超入門
Behat+Symfony2ではじめるBDD超入門Behat+Symfony2ではじめるBDD超入門
Behat+Symfony2ではじめるBDD超入門
晃 遠山
 
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
leverages_event
 
phpspecで始めるBDD
phpspecで始めるBDDphpspecで始めるBDD
phpspecで始めるBDD
Yuuki Takezawa
 
Codeceptionの受け入れテストをマネる
Codeceptionの受け入れテストをマネるCodeceptionの受け入れテストをマネる
Codeceptionの受け入れテストをマネる
infinite_loop
 
TDDBC Fukuoka Day1
TDDBC Fukuoka Day1TDDBC Fukuoka Day1
TDDBC Fukuoka Day1
Takuto Wada
 
テスト自動化ツール[Selenium]を検討してみて
テスト自動化ツール[Selenium]を検討してみてテスト自動化ツール[Selenium]を検討してみて
テスト自動化ツール[Selenium]を検討してみて
裕史 川松
 
bashでWebブラウザ(Selenium WebDriver)を動かした話
bashでWebブラウザ(Selenium WebDriver)を動かした話bashでWebブラウザ(Selenium WebDriver)を動かした話
bashでWebブラウザ(Selenium WebDriver)を動かした話
洋史 東平
 
Scrutinizer CIでPHPも静的解析 #phpstudy
Scrutinizer CIでPHPも静的解析 #phpstudyScrutinizer CIでPHPも静的解析 #phpstudy
Scrutinizer CIでPHPも静的解析 #phpstudy
Hiraku Nakano
 
最強のPHP統合開発環境 PHPStorm
最強のPHP統合開発環境 PHPStorm最強のPHP統合開発環境 PHPStorm
最強のPHP統合開発環境 PHPStorm
晃 遠山
 
はじめてのUser-Agent文字列
はじめてのUser-Agent文字列はじめてのUser-Agent文字列
はじめてのUser-Agent文字列
Kenta USAMI
 
Codeceptionことはじめ
CodeceptionことはじめCodeceptionことはじめ
Codeceptionことはじめ
infinite_loop
 
「Selenium実践入門」で学ぶテスト自動化の世界
「Selenium実践入門」で学ぶテスト自動化の世界「Selenium実践入門」で学ぶテスト自動化の世界
「Selenium実践入門」で学ぶテスト自動化の世界
Nozomi Ito
 
5分でわかる静的解析入門
5分でわかる静的解析入門5分でわかる静的解析入門
5分でわかる静的解析入門
Kenta USAMI
 
たのしい独自フレームワーク
たのしい独自フレームワークたのしい独自フレームワーク
たのしい独自フレームワーク
Kenta USAMI
 
いつでも聞けるTDD入門 #TDDBC_NAGOYA
いつでも聞けるTDD入門 #TDDBC_NAGOYAいつでも聞けるTDD入門 #TDDBC_NAGOYA
いつでも聞けるTDD入門 #TDDBC_NAGOYA
kyon mm
 
今、最もイケてるPHPフレームワークLaravel4
今、最もイケてるPHPフレームワークLaravel4今、最もイケてるPHPフレームワークLaravel4
今、最もイケてるPHPフレームワークLaravel4
アシアル株式会社
 
脆弱性もバグ、だからテストしよう PHPカンファンレス2015
脆弱性もバグ、だからテストしよう PHPカンファンレス2015脆弱性もバグ、だからテストしよう PHPカンファンレス2015
脆弱性もバグ、だからテストしよう PHPカンファンレス2015
ichikaway
 
AWS October Webinar Series - Introducing Amazon Elasticsearch Service
AWS October Webinar Series - Introducing Amazon Elasticsearch ServiceAWS October Webinar Series - Introducing Amazon Elasticsearch Service
AWS October Webinar Series - Introducing Amazon Elasticsearch Service
Amazon Web Services
 
今さら聞けない人のためのDevOps超入門
今さら聞けない人のためのDevOps超入門今さら聞けない人のためのDevOps超入門
今さら聞けない人のためのDevOps超入門
VirtualTech Japan Inc.
 

Viewers also liked (20)

Behat+Symfony2ではじめるBDD超入門
Behat+Symfony2ではじめるBDD超入門Behat+Symfony2ではじめるBDD超入門
Behat+Symfony2ではじめるBDD超入門
 
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
 
phpspecで始めるBDD
phpspecで始めるBDDphpspecで始めるBDD
phpspecで始めるBDD
 
Codeceptionの受け入れテストをマネる
Codeceptionの受け入れテストをマネるCodeceptionの受け入れテストをマネる
Codeceptionの受け入れテストをマネる
 
TDDBC Fukuoka Day1
TDDBC Fukuoka Day1TDDBC Fukuoka Day1
TDDBC Fukuoka Day1
 
BPStudy20121221
BPStudy20121221BPStudy20121221
BPStudy20121221
 
テスト自動化ツール[Selenium]を検討してみて
テスト自動化ツール[Selenium]を検討してみてテスト自動化ツール[Selenium]を検討してみて
テスト自動化ツール[Selenium]を検討してみて
 
bashでWebブラウザ(Selenium WebDriver)を動かした話
bashでWebブラウザ(Selenium WebDriver)を動かした話bashでWebブラウザ(Selenium WebDriver)を動かした話
bashでWebブラウザ(Selenium WebDriver)を動かした話
 
Scrutinizer CIでPHPも静的解析 #phpstudy
Scrutinizer CIでPHPも静的解析 #phpstudyScrutinizer CIでPHPも静的解析 #phpstudy
Scrutinizer CIでPHPも静的解析 #phpstudy
 
最強のPHP統合開発環境 PHPStorm
最強のPHP統合開発環境 PHPStorm最強のPHP統合開発環境 PHPStorm
最強のPHP統合開発環境 PHPStorm
 
はじめてのUser-Agent文字列
はじめてのUser-Agent文字列はじめてのUser-Agent文字列
はじめてのUser-Agent文字列
 
Codeceptionことはじめ
CodeceptionことはじめCodeceptionことはじめ
Codeceptionことはじめ
 
「Selenium実践入門」で学ぶテスト自動化の世界
「Selenium実践入門」で学ぶテスト自動化の世界「Selenium実践入門」で学ぶテスト自動化の世界
「Selenium実践入門」で学ぶテスト自動化の世界
 
5分でわかる静的解析入門
5分でわかる静的解析入門5分でわかる静的解析入門
5分でわかる静的解析入門
 
たのしい独自フレームワーク
たのしい独自フレームワークたのしい独自フレームワーク
たのしい独自フレームワーク
 
いつでも聞けるTDD入門 #TDDBC_NAGOYA
いつでも聞けるTDD入門 #TDDBC_NAGOYAいつでも聞けるTDD入門 #TDDBC_NAGOYA
いつでも聞けるTDD入門 #TDDBC_NAGOYA
 
今、最もイケてるPHPフレームワークLaravel4
今、最もイケてるPHPフレームワークLaravel4今、最もイケてるPHPフレームワークLaravel4
今、最もイケてるPHPフレームワークLaravel4
 
脆弱性もバグ、だからテストしよう PHPカンファンレス2015
脆弱性もバグ、だからテストしよう PHPカンファンレス2015脆弱性もバグ、だからテストしよう PHPカンファンレス2015
脆弱性もバグ、だからテストしよう PHPカンファンレス2015
 
AWS October Webinar Series - Introducing Amazon Elasticsearch Service
AWS October Webinar Series - Introducing Amazon Elasticsearch ServiceAWS October Webinar Series - Introducing Amazon Elasticsearch Service
AWS October Webinar Series - Introducing Amazon Elasticsearch Service
 
今さら聞けない人のためのDevOps超入門
今さら聞けない人のためのDevOps超入門今さら聞けない人のためのDevOps超入門
今さら聞けない人のためのDevOps超入門
 

Similar to behatで始めるBDD

omoon.org の裏側 〜FuelPHP の task 活用例〜
omoon.org の裏側 〜FuelPHP の task 活用例〜omoon.org の裏側 〜FuelPHP の task 活用例〜
omoon.org の裏側 〜FuelPHP の task 活用例〜
Sotaro Omura
 
Try Jetpack
Try JetpackTry Jetpack
Try Jetpack
Hideaki Miyake
 
WordPressで提供するWeb API
WordPressで提供するWeb APIWordPressで提供するWeb API
WordPressで提供するWeb APIYuko Toriyama
 
Mojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてるMojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてるjamadam
 
Inside Movable Type
Inside Movable TypeInside Movable Type
Inside Movable Type
純生 野田
 
3ヶ月でリア充大学生がFBアプリをリリースするまで @macrocro
3ヶ月でリア充大学生がFBアプリをリリースするまで @macrocro3ヶ月でリア充大学生がFBアプリをリリースするまで @macrocro
3ヶ月でリア充大学生がFBアプリをリリースするまで @macrocroYuuki Kuroda
 
Ci tutorial
Ci tutorialCi tutorial
Ci tutorial
Kazuaki Ueda
 
WordBech Osaka No.28
WordBech Osaka No.28WordBech Osaka No.28
WordBech Osaka No.28Kite Koga
 
リアルFacebookガジェットを作った(ロングバージョン)
リアルFacebookガジェットを作った(ロングバージョン)リアルFacebookガジェットを作った(ロングバージョン)
リアルFacebookガジェットを作った(ロングバージョン)
Mariko Goda
 
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
Fujio Kojima
 
WordBench京都 9月号:kintone×WordPressハンズオン
WordBench京都 9月号:kintone×WordPressハンズオンWordBench京都 9月号:kintone×WordPressハンズオン
WordBench京都 9月号:kintone×WordPressハンズオン
Takashi Hosoya
 
FuelPHPをさわってみて
FuelPHPをさわってみてFuelPHPをさわってみて
FuelPHPをさわってみて
Sotaro Omura
 
SpringOne 2GX 2014 参加報告 & Spring 4.1について #jsug
SpringOne 2GX 2014 参加報告 & Spring 4.1について #jsugSpringOne 2GX 2014 参加報告 & Spring 4.1について #jsug
SpringOne 2GX 2014 参加報告 & Spring 4.1について #jsug
Toshiaki Maki
 
モバイル開発@symfony
モバイル開発@symfonyモバイル開発@symfony
モバイル開発@symfonyDaichi Kamemoto
 
[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2
Atsuo Yamasaki
 
WordPress widget api
WordPress widget apiWordPress widget api
WordPress widget api
Takami Kazuya
 
test
testtest
SocialWeb Conference vol.5 OpenSocial Night #2
SocialWeb Conference vol.5 OpenSocial Night #2SocialWeb Conference vol.5 OpenSocial Night #2
SocialWeb Conference vol.5 OpenSocial Night #2Nobuhiro Nakajima
 
初めての Data api
初めての Data api初めての Data api
初めての Data api
Yuji Takayama
 
Data apiで実現 進化するwebの世界
Data apiで実現 進化するwebの世界Data apiで実現 進化するwebの世界
Data apiで実現 進化するwebの世界
Yuji Takayama
 

Similar to behatで始めるBDD (20)

omoon.org の裏側 〜FuelPHP の task 活用例〜
omoon.org の裏側 〜FuelPHP の task 活用例〜omoon.org の裏側 〜FuelPHP の task 活用例〜
omoon.org の裏側 〜FuelPHP の task 活用例〜
 
Try Jetpack
Try JetpackTry Jetpack
Try Jetpack
 
WordPressで提供するWeb API
WordPressで提供するWeb APIWordPressで提供するWeb API
WordPressで提供するWeb API
 
Mojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてるMojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてる
 
Inside Movable Type
Inside Movable TypeInside Movable Type
Inside Movable Type
 
3ヶ月でリア充大学生がFBアプリをリリースするまで @macrocro
3ヶ月でリア充大学生がFBアプリをリリースするまで @macrocro3ヶ月でリア充大学生がFBアプリをリリースするまで @macrocro
3ヶ月でリア充大学生がFBアプリをリリースするまで @macrocro
 
Ci tutorial
Ci tutorialCi tutorial
Ci tutorial
 
WordBech Osaka No.28
WordBech Osaka No.28WordBech Osaka No.28
WordBech Osaka No.28
 
リアルFacebookガジェットを作った(ロングバージョン)
リアルFacebookガジェットを作った(ロングバージョン)リアルFacebookガジェットを作った(ロングバージョン)
リアルFacebookガジェットを作った(ロングバージョン)
 
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
 
WordBench京都 9月号:kintone×WordPressハンズオン
WordBench京都 9月号:kintone×WordPressハンズオンWordBench京都 9月号:kintone×WordPressハンズオン
WordBench京都 9月号:kintone×WordPressハンズオン
 
FuelPHPをさわってみて
FuelPHPをさわってみてFuelPHPをさわってみて
FuelPHPをさわってみて
 
SpringOne 2GX 2014 参加報告 & Spring 4.1について #jsug
SpringOne 2GX 2014 参加報告 & Spring 4.1について #jsugSpringOne 2GX 2014 参加報告 & Spring 4.1について #jsug
SpringOne 2GX 2014 参加報告 & Spring 4.1について #jsug
 
モバイル開発@symfony
モバイル開発@symfonyモバイル開発@symfony
モバイル開発@symfony
 
[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2
 
WordPress widget api
WordPress widget apiWordPress widget api
WordPress widget api
 
test
testtest
test
 
SocialWeb Conference vol.5 OpenSocial Night #2
SocialWeb Conference vol.5 OpenSocial Night #2SocialWeb Conference vol.5 OpenSocial Night #2
SocialWeb Conference vol.5 OpenSocial Night #2
 
初めての Data api
初めての Data api初めての Data api
初めての Data api
 
Data apiで実現 進化するwebの世界
Data apiで実現 進化するwebの世界Data apiで実現 進化するwebの世界
Data apiで実現 進化するwebの世界
 

More from Tsutomu Chikuba

Megurorb 15 lt
Megurorb 15 ltMegurorb 15 lt
Megurorb 15 lt
Tsutomu Chikuba
 
Ebisu.rb#15LT「turnipいいよturnip」
Ebisu.rb#15LT「turnipいいよturnip」Ebisu.rb#15LT「turnipいいよturnip」
Ebisu.rb#15LT「turnipいいよturnip」
Tsutomu Chikuba
 
Meguro.rb#3LT「Ruby入門書を書いてて得られた知見5選+3α」
Meguro.rb#3LT「Ruby入門書を書いてて得られた知見5選+3α」Meguro.rb#3LT「Ruby入門書を書いてて得られた知見5選+3α」
Meguro.rb#3LT「Ruby入門書を書いてて得られた知見5選+3α」
Tsutomu Chikuba
 
オープンデータ利活用への道のり@未来型不動産サービス「IESHIL(イエシル)」の事例
オープンデータ利活用への道のり@未来型不動産サービス「IESHIL(イエシル)」の事例オープンデータ利活用への道のり@未来型不動産サービス「IESHIL(イエシル)」の事例
オープンデータ利活用への道のり@未来型不動産サービス「IESHIL(イエシル)」の事例
Tsutomu Chikuba
 
turnipとcapybaraとBDDと私
turnipとcapybaraとBDDと私turnipとcapybaraとBDDと私
turnipとcapybaraとBDDと私
Tsutomu Chikuba
 
いよいよPHPerもリーンで行こう
いよいよPHPerもリーンで行こういよいよPHPerもリーンで行こう
いよいよPHPerもリーンで行こう
Tsutomu Chikuba
 
Php unit extensions_selenium2_testcaseによる結合試験でらくらくテスト♪
Php unit extensions_selenium2_testcaseによる結合試験でらくらくテスト♪Php unit extensions_selenium2_testcaseによる結合試験でらくらくテスト♪
Php unit extensions_selenium2_testcaseによる結合試験でらくらくテスト♪Tsutomu Chikuba
 
ビジネス的に高価値なアジャイルテスト
ビジネス的に高価値なアジャイルテストビジネス的に高価値なアジャイルテスト
ビジネス的に高価値なアジャイルテスト
Tsutomu Chikuba
 
【参観レポート】Lean startupnight real startup dialog
【参観レポート】Lean startupnight   real startup dialog【参観レポート】Lean startupnight   real startup dialog
【参観レポート】Lean startupnight real startup dialogTsutomu Chikuba
 
PHP agile test tips
PHP agile test tipsPHP agile test tips
PHP agile test tips
Tsutomu Chikuba
 
リーンソフトウェア開発で始めるFacebookアプリ開発
リーンソフトウェア開発で始めるFacebookアプリ開発リーンソフトウェア開発で始めるFacebookアプリ開発
リーンソフトウェア開発で始めるFacebookアプリ開発Tsutomu Chikuba
 

More from Tsutomu Chikuba (11)

Megurorb 15 lt
Megurorb 15 ltMegurorb 15 lt
Megurorb 15 lt
 
Ebisu.rb#15LT「turnipいいよturnip」
Ebisu.rb#15LT「turnipいいよturnip」Ebisu.rb#15LT「turnipいいよturnip」
Ebisu.rb#15LT「turnipいいよturnip」
 
Meguro.rb#3LT「Ruby入門書を書いてて得られた知見5選+3α」
Meguro.rb#3LT「Ruby入門書を書いてて得られた知見5選+3α」Meguro.rb#3LT「Ruby入門書を書いてて得られた知見5選+3α」
Meguro.rb#3LT「Ruby入門書を書いてて得られた知見5選+3α」
 
オープンデータ利活用への道のり@未来型不動産サービス「IESHIL(イエシル)」の事例
オープンデータ利活用への道のり@未来型不動産サービス「IESHIL(イエシル)」の事例オープンデータ利活用への道のり@未来型不動産サービス「IESHIL(イエシル)」の事例
オープンデータ利活用への道のり@未来型不動産サービス「IESHIL(イエシル)」の事例
 
turnipとcapybaraとBDDと私
turnipとcapybaraとBDDと私turnipとcapybaraとBDDと私
turnipとcapybaraとBDDと私
 
いよいよPHPerもリーンで行こう
いよいよPHPerもリーンで行こういよいよPHPerもリーンで行こう
いよいよPHPerもリーンで行こう
 
Php unit extensions_selenium2_testcaseによる結合試験でらくらくテスト♪
Php unit extensions_selenium2_testcaseによる結合試験でらくらくテスト♪Php unit extensions_selenium2_testcaseによる結合試験でらくらくテスト♪
Php unit extensions_selenium2_testcaseによる結合試験でらくらくテスト♪
 
ビジネス的に高価値なアジャイルテスト
ビジネス的に高価値なアジャイルテストビジネス的に高価値なアジャイルテスト
ビジネス的に高価値なアジャイルテスト
 
【参観レポート】Lean startupnight real startup dialog
【参観レポート】Lean startupnight   real startup dialog【参観レポート】Lean startupnight   real startup dialog
【参観レポート】Lean startupnight real startup dialog
 
PHP agile test tips
PHP agile test tipsPHP agile test tips
PHP agile test tips
 
リーンソフトウェア開発で始めるFacebookアプリ開発
リーンソフトウェア開発で始めるFacebookアプリ開発リーンソフトウェア開発で始めるFacebookアプリ開発
リーンソフトウェア開発で始めるFacebookアプリ開発
 

Recently uploaded

2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
yassun7010
 
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
harmonylab
 
FIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdfFIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance
 
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
atsushi061452
 
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdfFIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance
 
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
Fukuoka Institute of Technology
 
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
atsushi061452
 
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
iPride Co., Ltd.
 
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdfFIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance
 
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
Matsushita Laboratory
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
CRI Japan, Inc.
 
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
NTT DATA Technology & Innovation
 
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdfFIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance
 
【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow
Sony - Neural Network Libraries
 
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdfFIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance
 

Recently uploaded (15)

2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
 
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
 
FIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdfFIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdf
 
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
 
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdfFIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
 
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
 
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
 
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
 
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdfFIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
 
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
 
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
 
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdfFIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
 
【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow
 
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdfFIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
 

behatで始めるBDD

  • 1. 第65回 PHP勉強会 @東京(Engine Yard) behat/PHPUnitで始める BDD/TDD 2013/02/28(木) @ビルコム
  • 3. about tchikuba • 所属 – ビルコム株式会社 • 自社サービス – ReBuy http://rebuy.jp/ – Okkru https://okkru.jp • 役割 – 開発Playing Manager • いいね! – Linux、ビール、宇宙平和 • facebook/twitter – tchikuba
  • 6. 我々の諸環境 • OS:CentOS(nifty cloud) • Webサーバ:Nginx/Apache • DBサーバ:MySQL • CIサーバ:Jenkins/SeleniumServer • 言語:PHP • フレームワーク:Zendframework • フロント:jQuery(Mobile) • SCM:Git • BTS:Backlog
  • 9. TDDとは • Test-Driven Developmentの • 和訳:テスト駆動開発 • 特徴 – テストファースト – リファクタリング • メリット – スパゲッティの塩分低下 – 開発アジリティ上昇
  • 10. BDDとは • Behavior-Driven Developmentの • 和訳:振舞駆動開発 • 特徴 – 自然言語 – 要求仕様(スペック) • メリット – け れ 厙 – オブジェクト指向強化
  • 11. BDD/TDDのフレームワーク • BDD – behat + mink – PHPSpec – Selenium • TDD – PHPUnit
  • 13.
  • 15. behat環境設定 • インストール (PHP5.3.4 ≧推奨) – Composer • vi composer.json • curl http://getcomposer.org/installer | php • php composer.phar install – PHAR – Git • 初期プロジェクト生成 – behat --init
  • 16. ディレクトリ構成 • behat_root/ – features/ • bootstrap/ – FeatureContext.php • *.feature – behat.yml – build.xml *for Jenkins • *.feature:機能+シナリオ(複数可) • FeatureContext.php:テスト定義 • bootstrap配下はオートロードされる
  • 17. く却 コマンド • テスト – behat [features/*.feature] • コンテキスト一覧 – behat –dl • スニペット生成 – behat –f snippets
  • 18. featureの Feature: facebook login facebook login @javascript Scenario: facebook login Given on facebook login page. When input email and password. And press login button Then facebook logged in.
  • 19. Contextの <?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; class FacebookloginContext extends BehatContext { public $mink; public function __construct($mink) { $this->mink = $mink; } (続く)
  • 20. Contextの /** * @Given /^on facebook login page¥.$/ */ public function onFacebookLoginPage() { $this->mink->getSession()- >visit('http://www.facebook.com/login.php'); } /** * @When /^input email and password¥.$/ */ public function inputEmailAndPassword() { $this->mink->getSession()->getPage()->fillField('email', MAIN_EMAIL); $this->mink->getSession()->getPage()->fillField('pass', PASSWORD); } (続く)
  • 21. Contextの /** * @Given /^press login button$/ */ public function pressLoginButton() { $this->mink->getSession()->getPage()->pressButton('Log In'); } /** * @Then /^facebook logged in¥.$/ */ public function facebookLoggedIn() { assertEquals('https://www.facebook.com/', $this->mink- >getSession()->getCurrentUrl()); } } (終わり)
  • 22. FeatureContextの <?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¥MinkContext; /** * Features context. */ class FeatureContext extends MinkContext { public $base_url; public $mink;
  • 23. FeatureContextの public function __construct(array $parameters) { // Initialize your context here $driver = new ¥Behat¥Mink¥Driver¥Selenium2Driver( SELENIUM2_BROWSER, null, SELENIUM2_URL ); $session = new ¥Behat¥Mink¥Session($driver); $this->base_url = OKKRU_BASE_URL; $mink = new ¥Behat¥Mink¥Mink(); $mink->registerSession('okkru', $session); $mink->setDefaultSessionName('okkru'); $this->mink = $mink; // use other context $this->useContext('fbconnect', new FbconnectContext($mink)); $this->useContext('facebooklogin', new FacebookloginContext($mink)); $this->useContext('sendme', new SendmeContext($mink)); $this->useContext('inputme', new InputmeContext($mink)); $this->useContext('ticketsend', new TicketsendContext($mink)); $this->useContext('ticketrecipient', new TicketrecipientContext($mink)); } }
  • 24. な :feature Feature: sendme 商品を自分で受け取ることが出来る。 @javascript Scenario: 商品を自分贈りで購入する。 Given テスト用商品ページにアクセスする。 When 購入ボタンを押下する。 Then ログイン画面に遷移する。 When ログインボタンを押下する。 Then facebookログインページに遷移する。 When facebookログインする。 Then 友人選択画面に遷移する。 When 友人選択画面で自分贈りを選択する。 Then 自分の住所情報が入 出来る。 And FBから引いた情報が補完されている。 When 自分の住所情報を入 する。 And 確認ボタンを押下する。 Then 確認画面に入 卣が勖単される。 When 確定ボタンを押下する。 Then 決済画面に遷移する。
  • 25. な :Context <?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; class SendmeContext extends BehatContext { public $base_url; public $mink; public function __construct($mink) { $this->base_url = OKKRU_BASE_URL; $this->mink = $mink; } (続く)
  • 26. な :Context /** * @Given /^テスト用商品ページにアクセスする。$/ */ public function accessDetail() { $this->mink->getSession()->visit($this->base_url . '/fbec_front/gift/detail/shop_id/' . SHOP_ID . '/product_id/' . PRODUCT_ID); } /** * @When /^購入ボタンを押下する。$/ */ public function pressProductButton() { $this->mink->getSession()->getPage()->clickLink('product- button'); }
  • 27. な :Context /** * @Then /^ログイン画面に遷移する。$/ */ public function assertDetail2FBlogin() { $this->mink->assertSession()- >addressMatches("/fbec_front¥/gift¥/login¥/url/"); } /** * @When /^ログインボタンを押下する。$/ */ public function pressConnectButton() { $this->mink->getSession()->wait(3000, "$('#login_btn').length > 0"); $this->mink->getSession()->getPage()->clickLink('login_btn'); }
  • 28. な :Context /** * @Then /^facebookログインページに遷移する。$/ */ public function assertFBConnect2FBLogin() { $expected_url = 'https://www.facebook.com'; $this->mink->getSession()->wait(3000); $actual_url = $this->mink->getSession()->getCurrentUrl(); $this->getMainContext()->getSubContext('fbconnect')->assertContainUrl($expected_url, $actual_url); } /** * @When /^facebookログインする。$/ */ public function facebookLogin() { $this->getMainContext()->getSubContext('facebooklogin')->inputEmailAndPassword(); $this->getMainContext()->getSubContext('facebooklogin')->pressLoginButton(); }
  • 29. な :Context /** * @Then /^友人選択画面に遷移する。$/ */ public function displayFriendsSelect() { $this->mink->assertSession()- >addressMatches("/fbec_front¥/gift¥/friends¥/shop_id¥/" . SHOP_ID . "/"); } /** * @When /^友人選択画面で自分贈りを選択する。$/ */ public function selectBuymyself() { $this->mink->getSession()->getPage()->clickLink('buymyself- button'); }
  • 30. な :Context /** * @Then /^自分の住所情報が入 出来る。$/ */ public function assertInputMyAddress() { $this->mink->assertSession()->pageTextContains('※贈り主情報:フリガナ'); $this->mink->assertSession()->pageTextContains('※贈り主情報:メールアドレス'); $this->mink->assertSession()->pageTextContains('※お届け先: 番号'); $this->mink->assertSession()->pageTextContains('※お届け先:都道府県'); $this->mink->assertSession()->pageTextContains('※お届け先:住所'); $this->mink->assertSession()->pageTextContains('※お届け先:電話番号'); } /** * @Given /^FBから引いた情報が補完されている。$/ */ public function assertSetFBinfo() { assertEquals(LAST_NAME_FB, $this->mink->getSession()->getPage()- >findById('last_name')->getValue()); assertEquals(FIRST_NAME_FB, $this->mink->getSession()->getPage()- >findById('first_name')->getValue()); assertEquals(MAIN_EMAIL, $this->mink->getSession()->getPage()->findById('email')- >getValue()); }
  • 31. な :Context /** * @When /^自分の住所情報を入 する。$/ */ public function inputMyAddress() { $this->mink->getSession()->getPage()->fillField('last_name', LAST_NAME_INPUT); $this->mink->getSession()->getPage()->fillField('first_name', FIRST_NAME_INPUT); $this->mink->getSession()->getPage()->fillField('last_name_kana', LAST_NAME_KANA); $this->mink->getSession()->getPage()->fillField('first_name_kana', FIRST_NAME_KANA); $this->mink->getSession()->getPage()->fillField('email', INPUT_EMAIL); $this->mink->getSession()->getPage()->fillField('zip3', ZIP3); $this->mink->getSession()->getPage()->fillField('zip4', ZIP4); $this->mink->getSession()->getPage()->selectFieldOption('prefecture', PREFECTURE); $this->mink->getSession()->getPage()->fillField('address', ADDRESS); $this->mink->getSession()->getPage()->fillField('address2', ADDRESS2); $this->mink->getSession()->getPage()->fillField('phone1', PHONE1); $this->mink->getSession()->getPage()->fillField('phone2', PHONE2); $this->mink->getSession()->getPage()->fillField('phone3', PHONE3); $this->mink->getSession()->getPage()->fillField('note', NOTE_SENDME); } /** * @Given /^確認ボタンを押下する。$/ */ public function pressSubmitShipmentButton() { $this->mink->getSession()->getPage()->clickLink('submit-shipment'); }
  • 32. な :Context /** * @Then /^確認画面に入 卣が勖単される。$/ */ public function assertDisplayInput() { $this->mink->assertSession()->pageTextContains(PRODUCT_NAME); $this->mink->assertSession()->pageTextContains(SHOP_NAME); $this->mink->assertSession()->pageTextContains(PRODUCT_PRICE); $this->mink->assertSession()->pageTextContains(PRODUCT_AND_WRAPPING_PRICE); $this->mink->assertSession()->pageTextContains(PRODUCT_ALL_PRICE); $this->mink->assertSession()->pageTextContains(LAST_NAME_INPUT . ' ' . FIRST_NAME_INPUT); $this->mink->assertSession()->pageTextContains(LAST_NAME_KANA . ' ' . FIRST_NAME_KANA); $this->mink->assertSession()->pageTextContains(INPUT_EMAIL); $this->mink->assertSession()->pageTextContains(ZIP3 . '-' . ZIP4); $this->mink->assertSession()->pageTextContains(PREFECTURE); $this->mink->assertSession()->pageTextContains(ADDRESS); $this->mink->assertSession()->pageTextContains(ADDRESS2); $this->mink->assertSession()->pageTextContains(PHONE1 . '-' . PHONE2 . '-' . PHONE3); $this->mink->assertSession()->pageTextContains(NOTE_SENDME); }
  • 33. な :Context /** * @When /^確定ボタンを押下する。$/ */ public function pressSubmitConfirm() { $this->mink->getSession()->getPage()->clickLink('submit-confirm'); } /** * @Then /^決済画面に遷移する。$/ */ public function assertConfirm2SBPS() { $this->mink->getSession()->wait(5000, 'typeof window.jQuery == "function"'); $this->mink->getSession()->wait(3000, 'window.document.getElementById("#title") > 0'); $this->mink->assertSession()->addressMatches("/¥/f01¥/FepBuyInfoReceive.do/"); } }
  • 35. まとめ • メリット – BDDで「なんちゃって」アジャイルを回避 – behatでテストファーストすることで事前の洗い出しが に • デメリット – スケジュールに追われる場合後回しになりがちで開発 プロセスを徹底するのが難しい – CIサーバに る定期 でアンドン化して 続メンテ ナンスしないと無効なテストケースが増殖
  • 36.