Cucumber
Cucumberの概要•   Cucumberの構成    •   フィーチャ    •   cucumberコマンド    •   ステップ定義•   実行の順序    •   cucumberコマンドの実行        →各シナリオのステ...
フィーチャを構成する要素• タイトル• ナラティブ• シナリオ
フィーチャを構成する要素• タイトル• ナラティブ• シナリオ
Feature: 在庫管理者が在庫品目を追加するFeature: 暗号解読者が推測を送信するFeature: 新規に会員登録する
フィーチャを構成する要素• タイトル• ナラティブ• シナリオ
•   ナラティブ    •   物語    •   Gherkinキーワードで始まる行が含まれてはならない•   Connextraフォーマットで記述する(従わないといけない訳ではない)    •   英語        As a <role...
フィーチャを構成する要素• タイトル• ナラティブ• シナリオ
Gherkinキーワード• Feature              • Given• Background           • When• Scenario             • Then• Scenario   Outline  ...
$ cucumber --i18n ja    | feature      | "フィーチャ", "機能"                                       |   | background        | "背景...
シナリオの書き方Feature: Traveler books room ln order to reduce staff As a hotel owner l want travelers to book rooms on the web S...
シナリオの書き方# language:enFeature: Traveler books room ln order to reduce staff As a hotel owner l want travelers to book rooms...
$ cucumber# language:enFeature: Traveler books room ln order to reduce staff As a hotel owner l want travelers to book roo...
$ 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 tra...
宣言型のシナリオScenario: transfer money (declarative) Given I have $100 in checking And I have $20 in savings When I transfer $15...
フィーチャの構成features         $ cucumber features  insurance      $ cucumber features/insurance    medical      $ cucumber feat...
タグ• タグのつけ方@approved @iteration_12Feature: patient requests appointment @wip Scenario: patient selects available time• 実行方法...
複雑なタグ式$ cucumber --tags @foo,@bar→@foo || @var$ cucumber --tags @foo --tags @bar→@foo && @var$ cucumber --tags ~@dev→!@dev...
タグ式のその他の用途•   特定の環境のみで実行されるシナリオ•   ワークフローとビジネスルールなど、さまざまな種類の    テストを表すシナリオを示す•   高速に実行されるシナリオだけを実行する•   フィーチャセットまたはテーマに関連す...
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          Wo...
ステップ定義から   ステップ定義を呼び出すWhen I select checking as the source accountAnd I select savings as the target accountAnd I set $20....
When /I transfer (.*) from (.*) to (,*)/ do |amount, source, target| When "I select #{source} as the source account" When ...
• ステップ定義からステップ定義を呼び出すとDRYにはなるが、間接化が1段増える• 階層が増えると、失敗の原因を特定しづらくなる• ステップ定義ごとに異なる抽象化• feature→ステップ• feature→ステップ→ステップ→ステップ• 結...
フック•   featuresディレクトリの下にあるRubyファイルで設定できる    features/support/hooks.rbに書くのがおすすめ?•   フックはいくつあってもよい•   Cucumberのフックは3種類    • ...
タグ付きフックBefore("@foo") do puts "This will run before each scenario tagged with @foo"endBefore("@foo,~@bar", "@zap") do puts...
バックグラウンド•   フックはRubyファイルに書くため、技術者以外の人にはイミフ•   featureファイルにBeforeフックのようなものを明示したい場合    はバックグラウンドを用いる•   バックグラウンドは与えられたfeatur...
Feature: Invite friends Background: Logged in  Given I am logged in as "Aslak"  And the following people exist:    | name ...
マルチラインテキストScenario: pending implementation Given a file named "example_without_block_spec.rb" with:  """  describe "an exam...
複数行のテキストは正規表現でキャプチャする必要はない。正規表現に含まれなかった文字列はブロックの最後の引数に入る。Given /a file named "([^"]*)" with:/ do |filename, text| # ...endTh...
ステップ内のテーブル• cucumberは行の最初に   "|" を見つけたときにパースし て、Cucumber::Ast::Tableオブジェクトにする• ステップ内でCucumber::Ast::Tableオブジェクトを用いる 場合は、Cu...
シナリオアウトライン• Scenariosキーワードで、Scenario   Outlineに流し込むデー タをテーブルで定義できる• ScenariosのエイリアスとしてExamplesキーワードもある• 複数行のテキストや、テーブルの値にも...
Scenario Outline: submit guess Given the secret code is "<code>" When I guess "<guess>" Then the mark should be "<mark>"Sc...
Scenario Outline:  Given a discount of <discount> When I order thefollowing book:    | title	| price	 |    | Healthy eatin...
プロファイル• cucumberのオプションをあらかじめ書いておくためのファイル• cucumber.yml• config/cucumber.yml
wip: --tags @wip features$ cucumber -p wip$ cucumber --tags @wip features
Upcoming SlideShare
Loading in …5
×

BDD勉強会 第6回

2,782 views

Published on

0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,782
On SlideShare
0
From Embeds
0
Number of Embeds
85
Actions
Shares
0
Downloads
7
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide
  • \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回

    1. 1. Cucumber
    2. 2. Cucumberの概要• Cucumberの構成 • フィーチャ • cucumberコマンド • ステップ定義• 実行の順序 • cucumberコマンドの実行 →各シナリオのステップを解析し、ステップ定義にマッピング →対応するステップ定義が見つかったら、ステップ定義が処理を行う
    3. 3. フィーチャを構成する要素• タイトル• ナラティブ• シナリオ
    4. 4. フィーチャを構成する要素• タイトル• ナラティブ• シナリオ
    5. 5. Feature: 在庫管理者が在庫品目を追加するFeature: 暗号解読者が推測を送信するFeature: 新規に会員登録する
    6. 6. フィーチャを構成する要素• タイトル• ナラティブ• シナリオ
    7. 7. • ナラティブ • 物語 • Gherkinキーワードで始まる行が含まれてはならない• Connextraフォーマットで記述する(従わないといけない訳ではない) • 英語 As a <role> I want <feature> So that <business value> • 日本語 <だれだれ>が <なになに>したい なぜなら<こういうことをしたい>からだ
    8. 8. フィーチャを構成する要素• タイトル• ナラティブ• シナリオ
    9. 9. Gherkinキーワード• Feature • Given• Background • When• Scenario • Then• Scenario Outline • And• Scenarios • But• Examples •| |、” ”、#
    10. 10. $ cucumber --i18n ja | feature | "フィーチャ", "機能" | | background | "背景" | | scenario | "シナリオ" | | scenario_outline | "シナリオアウトライン", "シナリオテンプレート", "テンプレ", "シナリオテンプレ" | | examples | "例", "サンプル" | | given | "* ", "前提" | | when | "* ", "もし" | | then | "* ", "ならば" | | and | "* ", "かつ" | | but | "* ", "しかし", "但し", "ただし" | | given (code) | "前提" | | when (code) | "もし" | | then (code) | "ならば" | | and (code) | "かつ" | | but (code) | "しかし", "但し", "ただし" |
    11. 11. シナリオの書き方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
    12. 12. シナリオの書き方# 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
    13. 13. $ 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
    14. 14. $ cucumber features/book_room.feature:7 指定した行のシナリオのみ実行
    15. 15. Given、When、Then• Given • シナリオにおいて事実として受け入れるもの • 事前条件ではない(満たさなくても先に進める) • 例: • 預金口座の残高が20ドルであるとすれば • 今日が休日であるとすれば
    16. 16. Given、When、Then• When • シナリオにおけるイベントを示す • どのシナリオでもイベントは1つであるのが理想 • 例: • 15ドルを引き出した • 部屋の掃除をした
    17. 17. Given、When、Then• Then • 期待される結果を示す • 例: • 残高は5ドルである
    18. 18. シナリオの記述の仕方• 宣言型 • シナリオごとにカスタマイズされる傾向 • 開発者がビジネス開発やテストする場合に向く• 命令型 • 少ないステップ定義でより多くのシナリオが書ける • テキストシナリオを扱えるビジネスアナリストがいる場合に向く• 同じプロジェクト内で命令形のシナリオと宣言型のシナリオの バランスを保つのが重要 →最初のテストは命令形、確認済の事と同じような事をする場合は宣言型 等
    19. 19. 命令型のシナリオ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
    20. 20. 宣言型のシナリオ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
    21. 21. フィーチャの構成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
    22. 22. タグ• タグのつけ方@approved @iteration_12Feature: patient requests appointment @wip Scenario: patient selects available time• 実行方法$ cucumber --tags @wip
    23. 23. 複雑なタグ式$ 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
    24. 24. タグ式のその他の用途• 特定の環境のみで実行されるシナリオ• ワークフローとビジネスルールなど、さまざまな種類の テストを表すシナリオを示す• 高速に実行されるシナリオだけを実行する• フィーチャセットまたはテーマに関連するシナリオを実 行する
    25. 25. Cucumberの詳細
    26. 26. ステップ定義• 定義されていないStepを含むfeatureを実行すると、cucumberはStep Definifionのひな形を出力してくれる。• 正規表現を通してステップに引数を渡す場合は、すべてStringとして渡される。
    27. 27. Worldオブジェクト• 全てのシナリオはWorldオブジェクトのコンテキストで実行される• WorldオブジェクトはデフォルトではObjectクラスのインスタンス(Object以外のインスタンスにする方法は後述)
    28. 28. ヘルパーメソッドmodule MyHelper def some_helper ・・・ endendWorld(MyHelper)
    29. 29. WorldをObject以外にする class MyWorld def some_helper ・・・ end end World do MyWorld.new end• cucumber-railsは、WorldをActionController::IntegrationTest のインスタンスとして設定している
    30. 30. ステップ定義から ステップ定義を呼び出す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
    31. 31. 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
    32. 32. • ステップ定義からステップ定義を呼び出すとDRYにはなるが、間接化が1段増える• 階層が増えると、失敗の原因を特定しづらくなる• ステップ定義ごとに異なる抽象化• feature→ステップ• feature→ステップ→ステップ→ステップ• 結局は読みやすさと保守性のバランスを見てどうするか決めるしかない
    33. 33. フック• featuresディレクトリの下にあるRubyファイルで設定できる features/support/hooks.rbに書くのがおすすめ?• フックはいくつあってもよい• Cucumberのフックは3種類 • Before • すべてのシナリオの前に実行される • After • すべてのシナリオの後に実行される • AfterStep • すべてのステップの後に実行される
    34. 34. タグ付きフック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
    35. 35. バックグラウンド• フックはRubyファイルに書くため、技術者以外の人にはイミフ• featureファイルにBeforeフックのようなものを明示したい場合 はバックグラウンドを用いる• バックグラウンドは与えられたfeature内の全てのシナリオの前 に実行される• Beforeフックはバックグラウンドより前に実行される
    36. 36. 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
    37. 37. マルチラインテキスト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"
    38. 38. 複数行のテキストは正規表現でキャプチャする必要はない。正規表現に含まれなかった文字列はブロックの最後の引数に入る。Given /a file named "([^"]*)" with:/ do |filename, text| # ...endThen /the stdout should include/ do |text| # ...end
    39. 39. ステップ内のテーブル• cucumberは行の最初に "|" を見つけたときにパースし て、Cucumber::Ast::Tableオブジェクトにする• ステップ内でCucumber::Ast::Tableオブジェクトを用いる 場合は、Cucumber::Ast::Table#hashesを使う• CucumberはCucumber::Ast::Tableをステップ定義中の最後 のブロック引数として渡す
    40. 40. シナリオアウトライン• Scenariosキーワードで、Scenario Outlineに流し込むデー タをテーブルで定義できる• ScenariosのエイリアスとしてExamplesキーワードもある• 複数行のテキストや、テーブルの値にもscenario outline は使える
    41. 41. 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 | ---- |
    42. 42. 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 |
    43. 43. プロファイル• cucumberのオプションをあらかじめ書いておくためのファイル• cucumber.yml• config/cucumber.yml
    44. 44. wip: --tags @wip features$ cucumber -p wip$ cucumber --tags @wip features

    ×