The document discusses test-driven development (TDD) and behavior-driven development (BDD) principles and practices for writing concise, valuable acceptance tests and user stories. Key points include using the INVEST criteria to evaluate user stories, focusing tests on business value through concrete examples and domain language over implementation details, and organizing testing code and files effectively.
14. Two sides to every (user) story
Narrative
Acceptance Criteria
- User/persona/role
- Multiple concrete
examples describing how
the feature works
- Goal or value the user
would like to achieve
- The interaction the user
should have with the
product in order to achieve
their goal and gain value
15. Our goals, user goals
Specification
Acceptance Test
Living Documentation
increasing
Domain Language
Key Examples
Shared Understanding
Scope
18. Refining User Stories
- Stories are refined through collaboration
- Stories may divide if they get complex
- Stories will often start with a small number
of key examples and expand as shared
understanding develops
- Refinement is complete when a story passes
the "INVEST" test.
20. INVEST in User Stories
Independent
Can be scheduled and re-prioritized with minimal risk of being blocked.
21. INVEST in User Stories
Independent
Negotiable
Can be changed or discarded if business, market, or technical needs require.
22. INVEST in User Stories
Independent
Negotiable
Valuable
Stories that don't add value for users will never see a return on investment.
23. INVEST in User Stories
Independent
Negotiable
Valuable
Estimable
A reasonable idea of effort required to complete is needed to pace the sprint.
24. INVEST in User Stories
Independent
Negotiable
Valuable
Estimable
Small
Quicker to implement, minimize risk, get feedback sooner.
25. INVEST in User Stories
Independent
Negotiable
Valuable
Estimable
Small
Testable
A story isn't considered done until its acceptance tests pass.
26. What is an acceptance test?
● Executable version of a refined user story
● Written in domain language
● Scenarios validate story acceptance criteria
● Defines start and finish lines
● Documents value proposition
● Respects "Three Levels of Description"
27. Three Levels of Description
Business Rule
What is the scenario demonstrating?
Scenario: Free delivery is offered to
customers who order two or more books
28. Three Levels of Description
Business Rule
What is the scenario demonstrating?
User Workflow
How can a user exercise the functionality?
Given I put two books in my cart
When I checkout
Then I should be able to select free delivery
29. Three Levels of Description
Business Rule
What is the scenario demonstrating?
User Workflow
How can a user exercise the functionality?
Technical Activity
What are the technical steps required to exercise each workflow step?
step 'I checkout' do
click_on 'Checkout'
end
31. Disambiguate w/Concrete Examples
Scenario Outline: Users cannot sign in after the sixth failed sign in attempt over a one
day period
Given I have failed to sign in <yesterday> times yesterday
And I have failed to sign in <today> times today
Then I should be <result> to sign in
Examples:
| yesterday | today | result |
| 0
| 0
| able
|
| 0
| 5
| able
|
| 0
| 6
| unable |
| 5
| 0
| able
|
| 5
| 5
| able
|
| 5
| 6
| unable |
| 6
| 0
| able
|
| 6
| 5
| able
|
| 6
| 6
| unable |
32. Gherkin Protip: Hide Implementation
Scenario: Selected customers are notified of a flash sale
Given I am a store manager
When I create a flash sale for VIP customers that starts
tomorrow
And it’s tomorrow
And Resque jobs are run
Then VIP customers receive a Flashmail
33. Gherkin Protip: Hide Implementation
Scenario: Selected customers are notified of a flash sale
Given I am a store manager
When I create a flash sale for VIP customers
Then VIP customers receive a Flashmail the day of the
flash
34. Gherkin Protip: Don’t Write Scripts
As a party planner with BFFs
In order to have the best party ever
I want to invite as many BFFs as possible
Given there is a user named Alice
And there is a user named Bob who is BFFs with Alice
And there is a user named Charlie who is BFFs with Bob
When Alice invites Bob to a party
But Alice does not invite Charlie to the same party
Then Alice receives a message
"Do you also want to invite Charlie?"
35. Gherkin Protip: Don’t Write Scripts
As a party planner with BFFs
In order to have the best party ever
I want to invite as many BFFs as possible
Given I am planning a party
When I invite my BFF Bob
Then I am asked if I might want to invite his BFF Charlie
36. Gherkin Protip:
Be skeptical of "I should see" steps
Is the act of seeing the thing valuable to the user or is it
an implementation detail?
Yes
Then I should see that the patron has overdue books
No
Then I should see the overdue book icon
37. Gherkin Protips:
Be skeptical of "And" and “But” keywords
Are these steps really one step?
Are these steps not focused on the feature?
Is this feature really two features?
Be skeptical of "and" and "or" in steps
Is this step really two steps?
Is this scenario really two scenarios?
38. Gherkin Protips:
Don't test every case
Add examples to disambiguate around edge cases
Never use generic steps to DRY tests
DRY Ruby code behind the steps
Listen when your Gherkin fights you
Can you explain the feature in simple terms?
39. Use ctags - Never Grep for Steps
● Open a .feature file
● Move cursor to a scenario step
● Press Ctrl+] to open the step definition
● Press Ctrl+t to go back to the .feature file
40. Step Definitions
# Gherkin
When I sign up with "email@example.com" and "password"
# Cucumber step definition
When /^I sign up (?:with|as) "(.*)" and "(.*)"$/ do |email, pw|
# More Ruby code here
end
# Turnip step definition
step "I sign up with/as :email and :password" do |email, pw|
# More Ruby code here
end
41. Use Custom Placeholders
step "there are :count monsters" do |count|
count.times { Monster.new(name) }
end
placeholder :count do
match /d+/, &:to_i # { |count| count.to_i }
match /no/ { 0 }
end
(or use Step Argument Transforms in Cucumber)
42. Use Helper Methods
module MyAccountSteps
step 'I am modifying my AwesomeApp account' do
sign_in @user = create(:user)
select_from_user_drop_down 'My account'
end
end
43. Organize Your Suite
spec
|- acceptance
|- features
|- encouragement.feature
|- macros
|- session_macros.rb
|- steps
|- encouragement_steps.rb