• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
BDD勉強会 第6回
 

BDD勉強会 第6回

on

  • 2,135 views

 

Statistics

Views

Total Views
2,135
Views on SlideShare
2,133
Embed Views
2

Actions

Likes
4
Downloads
5
Comments
0

1 Embed 2

https://twitter.com 2

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

BDD勉強会 第6回 BDD勉強会 第6回 Presentation Transcript

  • Cucumber
  • Cucumberの概要• Cucumberの構成 • フィーチャ • cucumberコマンド • ステップ定義• 実行の順序 • cucumberコマンドの実行 →各シナリオのステップを解析し、ステップ定義にマッピング →対応するステップ定義が見つかったら、ステップ定義が処理を行う
  • フィーチャを構成する要素• タイトル• ナラティブ• シナリオ
  • フィーチャを構成する要素• タイトル• ナラティブ• シナリオ
  • Feature: 在庫管理者が在庫品目を追加するFeature: 暗号解読者が推測を送信するFeature: 新規に会員登録する
  • フィーチャを構成する要素• タイトル• ナラティブ• シナリオ
  • • ナラティブ • 物語 • Gherkinキーワードで始まる行が含まれてはならない• Connextraフォーマットで記述する(従わないといけない訳ではない) • 英語 As a <role> I want <feature> So that <business value> • 日本語 <だれだれ>が <なになに>したい なぜなら<こういうことをしたい>からだ
  • フィーチャを構成する要素• タイトル• ナラティブ• シナリオ
  • Gherkinキーワード• Feature • Given• Background • When• Scenario • Then• Scenario Outline • And• Scenarios • But• Examples •| |、” ”、#
  • $ cucumber --i18n ja | feature | "フィーチャ", "機能" | | background | "背景" | | scenario | "シナリオ" | | scenario_outline | "シナリオアウトライン", "シナリオテンプレート", "テンプレ", "シナリオテンプレ" | | examples | "例", "サンプル" | | given | "* ", "前提" | | when | "* ", "もし" | | then | "* ", "ならば" | | and | "* ", "かつ" | | but | "* ", "しかし", "但し", "ただし" | | given (code) | "前提" | | when (code) | "もし" | | then (code) | "ならば" | | and (code) | "かつ" | | but (code) | "しかし", "但し", "ただし" |
  • シナリオの書き方Feature: Traveler books room ln order to reduce staff As a hotel owner l want travelers to book rooms on the web Scenario: Successful booking Scenario: Hotel is full Scenario: visitor forgets to enter email
  • シナリオの書き方# language:enFeature: Traveler books room ln order to reduce staff As a hotel owner l want travelers to book rooms on the web Scenario: Successful booking Given a hotel with “5” rooms and “0” bookings
  • $ cucumber# language:enFeature: Traveler books room ln order to reduce staff As a hotel owner l want travelers to book rooms on the web Scenario: Successful booking # features/book_room.feature:7 Given a hotel with “5” rooms and “0” bookings # features/book_room.feature:81 scenario (1 undifined)1 step (1 undefined)0m0.001sYou can implement step definitions for undefined steps with these snippets:Given /^a hotel with “([^”])” rooms and “([^”])” bookings$/ do |arg1, arg2| pending # express the regexp above with the code you wish you hadend
  • $ cucumber features/book_room.feature:7 指定した行のシナリオのみ実行
  • Given、When、Then• Given • シナリオにおいて事実として受け入れるもの • 事前条件ではない(満たさなくても先に進める) • 例: • 預金口座の残高が20ドルであるとすれば • 今日が休日であるとすれば
  • Given、When、Then• When • シナリオにおけるイベントを示す • どのシナリオでもイベントは1つであるのが理想 • 例: • 15ドルを引き出した • 部屋の掃除をした
  • Given、When、Then• Then • 期待される結果を示す • 例: • 残高は5ドルである
  • シナリオの記述の仕方• 宣言型 • シナリオごとにカスタマイズされる傾向 • 開発者がビジネス開発やテストする場合に向く• 命令型 • 少ないステップ定義でより多くのシナリオが書ける • テキストシナリオを扱えるビジネスアナリストがいる場合に向く• 同じプロジェクト内で命令形のシナリオと宣言型のシナリオの バランスを保つのが重要 →最初のテストは命令形、確認済の事と同じような事をする場合は宣言型 等
  • 命令型のシナリオScenario: transfer money (imperative) Given I have $100 in Checking And I have $20 in savings When I go to the transfer form And I select "Checking" from "Source Account" And I select "Savings" from "Target Account" And I fill in "Amount" with "15" And I press "Execute Transfer" Then I should see that l have $85 in checking And I should see that l have $35 in savings
  • 宣言型のシナリオScenario: transfer money (declarative) Given I have $100 in checking And I have $20 in savings When I transfer $15 from checking to savings Then I should have $85 in checking And I should have $35 in savings
  • フィーチャの構成features $ cucumber features insurance $ cucumber features/insurance medical $ cucumber features/insurance/medical dental $ cucumber features/insurance/ dental life $ cucumber features/insurance/ life disability $ cucumber features/insurance/ disability pto $ cucumber features/pto accrual $ cucumber features/pto/accrual usage $ cucumber features/pto/usage
  • タグ• タグのつけ方@approved @iteration_12Feature: patient requests appointment @wip Scenario: patient selects available time• 実行方法$ cucumber --tags @wip
  • 複雑なタグ式$ cucumber --tags @foo,@bar→@foo || @var$ cucumber --tags @foo --tags @bar→@foo && @var$ cucumber --tags ~@dev→!@dev$ cucumber --tags @foo,~@bar --tags @baz→(@foo || !@var) && @baz
  • タグ式のその他の用途• 特定の環境のみで実行されるシナリオ• ワークフローとビジネスルールなど、さまざまな種類の テストを表すシナリオを示す• 高速に実行されるシナリオだけを実行する• フィーチャセットまたはテーマに関連するシナリオを実 行する
  • Cucumberの詳細
  • ステップ定義• 定義されていないStepを含むfeatureを実行すると、cucumberはStep Definifionのひな形を出力してくれる。• 正規表現を通してステップに引数を渡す場合は、すべてStringとして渡される。
  • Worldオブジェクト• 全てのシナリオはWorldオブジェクトのコンテキストで実行される• WorldオブジェクトはデフォルトではObjectクラスのインスタンス(Object以外のインスタンスにする方法は後述)
  • ヘルパーメソッドmodule MyHelper def some_helper ・・・ endendWorld(MyHelper)
  • WorldをObject以外にする class MyWorld def some_helper ・・・ end end World do MyWorld.new end• cucumber-railsは、WorldをActionController::IntegrationTest のインスタンスとして設定している
  • ステップ定義から ステップ定義を呼び出すWhen I select checking as the source accountAnd I select savings as the target accountAnd I set $20.00 as the amountAnd I click transferWhen I transfer $20.00 from checking to savings
  • When /I transfer (.*) from (.*) to (,*)/ do |amount, source, target| When "I select #{source} as the source account" When "I select #{target} as the target account" When "I set #{amount} as the amount" When "I click transfer"endWhen /I transfer (.*) from (.*) to (.*)/ do |amount, source, target| steps %Q{ When I select #{source} as the source account And I select #{target} as the target account And I set #{amount} as the amount And I click transfer }end
  • • ステップ定義からステップ定義を呼び出すとDRYにはなるが、間接化が1段増える• 階層が増えると、失敗の原因を特定しづらくなる• ステップ定義ごとに異なる抽象化• feature→ステップ• feature→ステップ→ステップ→ステップ• 結局は読みやすさと保守性のバランスを見てどうするか決めるしかない
  • フック• featuresディレクトリの下にあるRubyファイルで設定できる features/support/hooks.rbに書くのがおすすめ?• フックはいくつあってもよい• Cucumberのフックは3種類 • Before • すべてのシナリオの前に実行される • After • すべてのシナリオの後に実行される • AfterStep • すべてのステップの後に実行される
  • タグ付きフックBefore("@foo") do puts "This will run before each scenario tagged with @foo"endBefore("@foo,~@bar", "@zap") do puts "This will run before each scenario tagged with @foo or not @bar AND @zap"end
  • バックグラウンド• フックはRubyファイルに書くため、技術者以外の人にはイミフ• featureファイルにBeforeフックのようなものを明示したい場合 はバックグラウンドを用いる• バックグラウンドは与えられたfeature内の全てのシナリオの前 に実行される• Beforeフックはバックグラウンドより前に実行される
  • Feature: Invite friends Background: Logged in Given I am logged in as "Aslak" And the following people exist: | name | friend? | | David | yes | | Vidkun | no | Scenario: Invite someone who is alreadv a friend Scenario: Invite someone who is not a friend Scenario: Invite someone who doesnt have an account
  • マルチラインテキストScenario: pending implementation Given a file named "example_without_block_spec.rb" with: """ describe "an example" do it "is a pending example" end """ When I run "rspec example_without_block_spec.rb" Then the exit code should be 0 And the output should contain "1 example, 0 failures, 1 pending" And the output should contain "Not Yet Implemented" And the output should contain "example_without_block_spec.rb:2"
  • 複数行のテキストは正規表現でキャプチャする必要はない。正規表現に含まれなかった文字列はブロックの最後の引数に入る。Given /a file named "([^"]*)" with:/ do |filename, text| # ...endThen /the stdout should include/ do |text| # ...end
  • ステップ内のテーブル• cucumberは行の最初に "|" を見つけたときにパースし て、Cucumber::Ast::Tableオブジェクトにする• ステップ内でCucumber::Ast::Tableオブジェクトを用いる 場合は、Cucumber::Ast::Table#hashesを使う• CucumberはCucumber::Ast::Tableをステップ定義中の最後 のブロック引数として渡す
  • シナリオアウトライン• Scenariosキーワードで、Scenario Outlineに流し込むデー タをテーブルで定義できる• ScenariosのエイリアスとしてExamplesキーワードもある• 複数行のテキストや、テーブルの値にもscenario outline は使える
  • Scenario Outline: submit guess Given the secret code is "<code>" When I guess "<guess>" Then the mark should be "<mark>"Scenarios: all numbers correct | code | guess | mark | | 1234 | 1234 | ++++ | | 1234 | 1243 | ++-- | | 1234 | 1423 | +--- | | 1234 | 4321 | ---- |
  • Scenario Outline: Given a discount of <discount> When I order thefollowing book: | title | price | | Healthy eating for programmers | <price> | Then the statement should read: """ Statement for David Total due: <total> """Scenarios: | discount | price | total | | 10% | $29.99 | $26.99 | | 15% | $29.99 | $25.49 |
  • プロファイル• cucumberのオプションをあらかじめ書いておくためのファイル• cucumber.yml• config/cucumber.yml
  • wip: --tags @wip features$ cucumber -p wip$ cucumber --tags @wip features