Bdd From The Trenches

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

1 comments

Comments 1 - 1 of 1 previous next Post a comment

Post a comment
Embed Video
Edit your comment Cancel

6 Favorites

Bdd From The Trenches - Presentation Transcript

  1. BDD FROM THE Luismi Cavallé TRENCHES Jorge Gómez Sancha BeBanjo
  2. As a [Role] I want [Feature] So that [Benefit] Scenario = Acceptance Criteria Given [Context] And [Some more Context] When [Event] And [Some other Event] Then [Outcome] And [Another Outcome]
  3. Given [Context] Planteamiento When [Event] Nudo Then [Outcome] Desenlace
  4. User Stories = Great way to communicate functionality
  5. Searching for “THE WAY” to develop software
  6. We have made good progress...
  7. ...but we are always searching
  8. HOW
  9. HOW H Y
  10. Friday (afternoon)
  11. What’s the most important thing the system doesn’t do? http://dannorth.net/introducing-bdd
  12. Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature Feature
  13. Feature Feature Feature Feature Feature Feature Feature
  14. Story: User sees timeline for a title As a user, I want to see a timeline of all the events associated to a title, So that I have access to its full history Scenario: An entry in the title timeline gets created when scheduled Given Telefonica operates VOD services Imagenio And a user Borat from the company Telefonica And Pedro scheduled the title Spaceballs on 15-03-2008 in Imagenio When Borat logs in And Borat goes to the title's timeline page for title Spaceballs Then he should see an entry 'Scheduled by Borat' on March 15, 2008
  15. It’s game time
  16. Would you mind giving me some privacy?
  17. Would you mind giving me some privacy? Porras LuisMi
  18. Estimates Features L uismi R J ai orge S ergio A 3 2 4 3 B 1 .5 2 1 C 1 .5 15 . 1 D 15 . 1 15 . 2
  19. Estimates We use these Features L uismi R J ai orge S ergio Average A 3 2 4 3 3 B 1 .5 2 1 11 . C 1 .5 15 . 1 1 D 15 . 1 15 . 2 15 .
  20. Burndown Junkies Functionality Left F M T W Th Time
  21. Black Monday
  22. Progress Ideal Preso ✓ Estimating, Game, Burndown 20 100 Pair Programming 20 75 Acceptance vs Unit 20 50 Upfront Design 10 25 Love 10 0 Productivity 20 40’ 35’ 30’ 25’ 20’ 15’ 10’ 5’ End! Total 100 Left: 80
  23. Monday
  24. “Pair all the fucking time” -- Obie Fernandez
  25. “Aparéate todo el puto día” -- BeBanjo
  26. “Aparéate todo el puto día” -- BeBanjo
  27. # /bebanjo_app/features/login.feature Scenario: User logs in successfully Given an existing user Robert with password 'r0b3rt' When Robert logs in entering the password 'r0b3rt' Then he should be redirected to the home page
  28. $ cd bebanjo_app
  29. $ cd bebanjo_app $ script/cucumber features/login.feature
  30. $ cd bebanjo_app $ script/cucumber features/login.feature Scenario: User logs in successfully Given an existing user Robert with password 'r0b3rt' [PENDING] When Robert logs in entering the password 'r0b3rt' [PENDING] Then he should be redirected to the home page [PENDING]
  31. # /bebanjo_app/features/steps/user_steps.rb
  32. # /bebanjo_app/features/steps/user_steps.rb Given /^an existing user (.*) with password '(.*)'$/ do |username, password|
  33. # /bebanjo_app/features/steps/user_steps.rb Given /^an existing user (.*) with password '(.*)'$/ do |username, password| User.create(:username => username, :password => password)
  34. # /bebanjo_app/features/steps/user_steps.rb Given /^an existing user (.*) with password '(.*)'$/ do |username, password| User.create(:username => username, :password => password) end
  35. $ script/cucumber features/login.feature
  36. $ script/cucumber features/login.feature Scenario: User logs in successfully Given an existing user Robert with password 'r0b3rt' [FAILED] uninitialized constant User (NameError) When Robert logs in entering the password 'r0b3rt' [PENDING] Then he should be redirected to the home page [PENDING]
  37. $ script/cucumber features/login.feature Scenario: User logs in successfully Given an existing user Robert with password 'r0b3rt' [FAILED] uninitialized constant User (NameError) When Robert logs in entering the password 'r0b3rt' [PENDING] Then he should be redirected to the home page [PENDING]
  38. $ script/generate model User username:string password:string
  39. $ script/generate model User username:string password:string $ rake db:migrate && rake db:test:prepare
  40. $ script/cucumber features/login.feature
  41. $ script/cucumber features/login.feature Scenario: User logs in successfully Given an existing user Robert with password 'r0b3rt' When Robert logs in entering the password 'r0b3rt' [PENDING] Then he should be redirected to the home page [PENDING]
  42. # /bebanjo_app/features/steps/user_steps.rb When /^(.*) logs in entering the password '(.*)'$/ do |username, password|
  43. # /bebanjo_app/features/steps/user_steps.rb When /^(.*) logs in entering the password '(.*)'$/ do |username, password| visits \"/session/new\"
  44. # /bebanjo_app/features/steps/user_steps.rb When /^(.*) logs in entering the password '(.*)'$/ do |username, password| visits \"/session/new\" fills_in \"Username\", :with => username
  45. # /bebanjo_app/features/steps/user_steps.rb When /^(.*) logs in entering the password '(.*)'$/ do |username, password| visits \"/session/new\" fills_in \"Username\", :with => username fills_in \"Password\", :with => password
  46. # /bebanjo_app/features/steps/user_steps.rb When /^(.*) logs in entering the password '(.*)'$/ do |username, password| visits \"/session/new\" fills_in \"Username\", :with => username fills_in \"Password\", :with => password clicks_button \"Sign in\"
  47. # /bebanjo_app/features/steps/user_steps.rb When /^(.*) logs in entering the password '(.*)'$/ do |username, password| visits \"/session/new\" fills_in \"Username\", :with => username fills_in \"Password\", :with => password clicks_button \"Sign in\" end
  48. $ script/cucumber features/login.feature
  49. $ script/cucumber features/login.feature Scenario: User logs in successfully Given an existing user Robert with password 'r0b3rt' When Robert logs in entering the password 'r0b3rt' [FAILED] No route matches \"/session/new\" with {:method=>:get} (RoutingError) Then he should be redirected to the home page [PENDING]
  50. $ script/cucumber features/login.feature Scenario: User logs in successfully Given an existing user Robert with password 'r0b3rt' When Robert logs in entering the password 'r0b3rt' [FAILED] No route matches \"/session/new\" with {:method=>:get} (RoutingError) Then he should be redirected to the home page [PENDING]
  51. # /bebanjo_app/config/routes.rb ActionController::Routing::Routes.draw do |map| map.resource :session
  52. # /bebanjo_app/app/controllers/sessions_controller.rb
  53. # /bebanjo_app/app/controllers/sessions_controller.rb class SessionsController < ApplicationController
  54. # /bebanjo_app/app/controllers/sessions_controller.rb class SessionsController < ApplicationController def new
  55. # /bebanjo_app/app/controllers/sessions_controller.rb class SessionsController < ApplicationController def new end
  56. # /bebanjo_app/app/controllers/sessions_controller.rb class SessionsController < ApplicationController def new end def create
  57. # /bebanjo_app/app/controllers/sessions_controller.rb class SessionsController < ApplicationController def new end def create end
  58. # /bebanjo_app/app/controllers/sessions_controller.rb class SessionsController < ApplicationController def new end def create end end
  59. # /bebanjo_app/app/views/sessions/new.html.erb <% form_for :session, :url => session_path do |f| -%> <p> <%= f.label :username %>: <%= f.text_field :username %> </p> <p> <%= f.label :password %>: <%= f.password_field :password %> </p> <p> <%= f.submit \"Sign in\" %> </p> <% end -%>
  60. $ script/cucumber features/login.feature
  61. $ script/cucumber features/login.feature Scenario: User logs in successfully Given an existing user Robert with password 'r0b3rt' When Robert logs in entering the password 'r0b3rt' Then he should be redirected to the home page [PENDING]
  62. # /bebanjo_app/features/steps/user_steps.rb Then /^(?:he|she) should be redirected to the home page$/ do response.request.path.should == \"/\" end
  63. $ script/cucumber features/login.feature
  64. $ script/cucumber features/login.feature Scenario: User logs in successfully Given an existing user Robert with password 'r0b3rt' When Robert logs in entering the password 'r0b3rt' Then he should be redirected to the home page [FAILED] expected redirect to \"/\", got no redirect (ExpectationNotMetError)
  65. $ script/cucumber features/login.feature Scenario: User logs in successfully Given an existing user Robert with password 'r0b3rt' When Robert logs in entering the password 'r0b3rt' Then he should be redirected to the home page [FAILED] expected redirect to \"/\", got no redirect (ExpectationNotMetError)
  66. # /bebanjo_app/app/controllers/sessions_controller.rb class SessionsController < ApplicationController def new end def create redirect_to root_path end end
  67. $ script/cucumber features/login.feature
  68. $ script/cucumber features/login.feature Scenario: User logs in successfully Given an existing user Robert with password 'r0b3rt' When Robert logs in entering the password 'r0b3rt' Then he should be redirected to the home page 3 steps passed
  69. # /bebanjo_app/features/login.feature Scenario: User logs in with incorrect credentials Given an existing user Robert with password 'r0b3rt' When Robert logs in entering the password 'robert' Then he should not be redirected to the home page
  70. $ git commit -a -m “Scenario: User logs in successfully”
  71. $ git commit -a -m “Scenario: User logs in successfully” $ git push origin master
  72. Story driven Swapping Criteria
  73. Increased Focus Knowledge share Pride Effect
  74. Progress Ideal Preso ✓ Estimating, Game, Burndown 20 100 ✓ Pair Programming 20 75 Acceptance vs Unit 20 50 Upfront Design 10 25 Love 10 0 Productivity 20 40’ 35’ 30’ 25’ 20’ 15’ 10’ 5’ End! Total 100 Left: 60
  75. Tuesday
  76. Acceptance Unit
  77. Acceptance Unit
  78. Acceptance Unit
  79. Acceptance Unit Development / Design Great verification tool tool
  80. Acceptance
  81. # user_steps.rb Given /^an existing user (.*)$/ do |username| create_user(:username => username) end
  82. # user_steps.rb Given /^an existing user (.*)$/ do |username| create_user(:username => username) end # example_data.rb (fixture_replacement) attributes_for :user do |u| u.username = String.random u.password = \"secret\" u.password_confirmation = \"secret\" u.company = default_company end
  83. # user_steps.rb When /^(.*) logs in$/ do |username| visits \"/session/new\" fills_in \"Username\", :with => username fills_in \"Password\", :with => \"secret\" clicks_button \"Sign in\" end
  84. # user_steps.rb Then /^the email of (.*) should be (.*)/ do |username, email| user = User.find_by_username(username) user.email.should == email # assert_equal(email, user.email) end
  85. # user_steps.rb Then /^the email of (.*) should be (.*)/ do |username, email| user = User.find_by_username(username) user.email.should == email # assert_equal(email, user.email) end Then /^the user should see the title (.*)/ do |title| response.should have_tag(\".title\", title) # assert_select(\".title\", title) end
  86. Acceptance testing is great...
  87. Acceptance testing is great... • as a verification tool
  88. Acceptance testing is great... • as a verification tool • as a bridge between user needs and automated tests
  89. Acceptance testing is great... • as a verification tool • as a bridge between user needs and automated tests ...but as a development tool....
  90. Acceptance testing is great... • as a verification tool • as a bridge between user needs and automated tests ...but as a development tool.... • it is not easy to debug
  91. Acceptance testing is great... • as a verification tool • as a bridge between user needs and automated tests ...but as a development tool.... • it is not easy to debug • it is slow to run
  92. Acceptance testing is great... • as a verification tool • as a bridge between user needs and automated tests ...but as a development tool.... • it is not easy to debug • it is slow to run • it doesn’t encourage good design
  93. Acceptance testing is great... • as a verification tool • as a bridge between user needs and automated tests ...but as a development tool.... • it is not easy to debug • it is slow to run • it doesn’t encourage good design • it is not comprehensive
  94. Acceptance testing is great... • as a verification tool • as a bridge between user needs and automated tests ...but as a development tool.... • it is not easy to debug • it is slow to run • it doesn’t encourage good design • it is not comprehensive ...so we need something more
  95. Unit
  96. RSpec offers lots of possibilities:
  97. RSpec offers lots of possibilities: Model specs Controller specs View specs Helper specs Routes specs
  98. RSpec offers lots of possibilities: Model specs Controller specs Interaction-based View specs State-based Helper specs Structure-based Routes specs
  99. But we’re only interested in: Maximize Productivity Maximize Quality
  100. So, how do we spec... Our Views?
  101. So, how do we spec... Our Views? We mostly don’t
  102. So, how do we spec... Our Views? We mostly don’t Redundant with “then” steps in stories
  103. So, how do we spec... Our Controllers?
  104. So, how do we spec... Our Controllers? 67% Coverage
  105. So, how do we spec... Our Controllers? 67% Coverage Interaction-based unit test
  106. So, how do we spec... Our Controllers? 67% Coverage Interaction-based unit test Still discussing if it is worth
  107. # tasks_controller_spec.rb describe \"POST 'create'\" do before(:each) do @task_attibutes = stub(Hash) @task = stub(Task) @tasks.stub!(:create).and_return(@task) end def do_post post :create, :scheduled_title_id => 1, :task => @task_attributes end it \"should get the scheduled title from the current company\" do @scheduled_titles.should_receive(:find).with(\"1\").and_return(@scheduled_title) do_post end it \"should create the task\" do @tasks.should_receive(:create).with(@task_attributes) do_post end it \"should redirect to workflow\" do do_post assigns[:task].should == @task end end
  108. So, how do we spec... Our Models?
  109. So, how do we spec... Our Models? 87% Coverage
  110. So, how do we spec... Our Models? 87% Coverage State-based functional test
  111. So, how do we spec... Our Models? 87% Coverage State-based functional test Only the interesting behavior
  112. describe ScheduledTitle do describe \"late?\" do it \"should be late if begins_at is in the past\" do scheduled_title = new_scheduled_title(:begins_at => Date.today - 3.days) scheduled_title.should be_late end it \"should not be late if begins_at is in the future\" do scheduled_title = new_scheduled_title(:begins_at => Date.today + 3.days) scheduled_title.should_not be_late end it \"should not be late if begins_at is today\" do scheduled_title = new_scheduled_title(:begins_at => Date.today) scheduled_title.should_not be_late end end
  113. So, how do we spec... Other objects?
  114. So, how do we spec... Other objects? Helpers -- 32.1% Coverage
  115. So, how do we spec... Other objects? Helpers -- 32.1% Coverage Routes -- never
  116. So, how do we spec... Other objects? Helpers -- 32.1% Coverage Routes -- never Libs -- 86.7%
  117. How do we not spec?
  118. describe User do it { Factory(:user).should have_many(:projects) } it { Factory(:user).should belong_to(:company) } table_has_columns(User, :string, \"login\") end class User has_many :projects belongs_to :company
  119. describe User do it { Factory(:user).should have_many(:projects) } it { Factory(:user).should belong_to(:company) } table_has_columns(User, :string, \"login\") end class User create_table \"users\", :force => true do |t| has_many :projects t.column :login, :string end belongs_to :company
  120. describe User do it { Factory(:user).should have_many(:projects) } it { Factory(:user).should belong_to(:company) } table_has_columns(User, :string, \"login\") end Structure is not interesting behavior! class User create_table \"users\", :force => true do |t| has_many :projects t.column :login, :string end belongs_to :company
  121. Progress Ideal Preso ✓ Estimating, Game, Burndown 20 100 ✓ Pair Programming 20 75 ✓ Acceptance vs Unit 20 50 Upfront Design 10 25 Love 10 0 Productivity 20 40’ 35’ 30’ 25’ 20’ 15’ 10’ 5’ End! Total 100 Left: 40
  122. Wednesday
  123. Playboy TV
  124. Progress Ideal Preso ✓ Estimating, Game, Burndown 20 100 ✓ Pair Programming 20 75 ✓ Acceptance vs Unit 20 50 ✓ Upfront Design 10 25 Love 10 0 Productivity 20 40’ 35’ 30’ 25’ 20’ 15’ 10’ 5’ End! Total 100 Left: 30
  125. Thursday
  126. DRY Less code Skinny controller, fat model
  127. Technical debt DRY Less code Skinny controller, fat model
  128. Technical debt Broken windows DRY Less code Skinny controller, fat model
  129. Technical debt Broken windows DRY Less code Skinny controller, fat model Beautiful code
  130. Technical debt Broken windows DRY Less code Skinny controller, fat model Habitable software Beautiful code
  131. Technical debt Broken windows DRY Refactoring towards a deeper insight Less code Skinny controller, fat model Habitable software Beautiful code
  132. Progress Ideal Preso ✓ Estimating, Game, Burndown 20 100 ✓ Pair Programming 20 75 ✓ Acceptance vs Unit 20 50 ✓ Upfront Design 10 25 ✓ Love 10 0 Productivity 20 40’ 35’ 30’ 25’ 20’ 15’ 10’ 5’ End! Total 100 Left: 20
  133. and again, Friday
  134. You call that productivity?
  135. The End

+ jjggssjjggss, 10 months ago

custom

1624 views, 6 favs, 1 embeds more stats

At BeBanjo we develop web applications to manage al more

More info about this document

© All Rights Reserved

Go to text version

  • Total Views 1624
    • 1623 on SlideShare
    • 1 from embeds
  • Comments 1
  • Favorites 6
  • Downloads 0
Most viewed embeds
  • 1 views on http://192.168.10.100

more

All embeds
  • 1 views on http://192.168.10.100

less

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

Cancel
File a copyright complaint
Having problems? Go to our helpdesk?

Categories