I am a tester on the Extremely Cheezy team. Our team is building a revolutionary new online bookstore application called depot. It is Friday afternoon and our new Iteration begins on Monday. The user-facing portion of the application is nearly finished. All that remains is the checkout page. This is my story.
Starting the Feature
I walk over and sit down beside the product owner to discuss the checkout page. There is no need to schedule a meeting since we are all sitting in an open space collaborating continuously. She begins the conversation.
PO: I’ve been working with Kimberly (the UX girl) on the screen mockup. Here it is.
Me: Very nice. Let’s take a look at the story you have started.
Feature: Checking out after you complete your order As an online book buyer I need to provide my personal information so that the website can process my order
Me: This is a good start. What can you tell me about the details of this page?
PO: Well, all of the fields must be filled in before we can process the order.
Me: Okay. So all fields are required. What should happen if the user leaves one of the fields blank?
PO: Well I guess they should get a message informing them that the field cannot be blank.
Me: Good. What are the possible values for the Pay with field?
PO: We only handle Checks, Credit cards, and Purchase orders.
Me: That’s good to know. What should happen when the user completes all of the fields and places the order?
PO: The user should get a message thanking them for their order.
Me: Is there anything else I should know about this page?
PO: Not that I can think of right now.
Me: I think we have enough to get started. Let’s start writing the first version of the acceptance tests.
With my PO still watching, I open RubyMine and create a new feature file. I type the story info and a few notes to myself.
Feature: Checking out after you complete your order As an online book buyer I need to provide my personal information so that the website can process my order All fields are required. Should display error message when fields are left blank. Pay with should include Check, Credit card, and Purchase order. Should display thank you message when order is complete.
The Scenarios Please?
We really need to capture some of the details about the story in the form of Scenarios so the developer will know what to deliver when they pick up the story on Monday.
Me: Let’s write the scenario that describes what should happen when they fill in all of the fields on this page.
PO: OK. Remember it should display a thank-you message.
I write the following Scenario:
Scenario: filling in all fields
Given I am on the depot site
When I purchase a book
And I complete the order with:
| name | address | email | pay_type |
| Sam Smith | 123 Main Street | sam@example.com | Credit card |
Then I should see "Thank you for your order"
Me: What do you think of this?
PO: It’s good. I think the message is fine but I might want to change it once I talk to Jared. You know he always has an opinion on those things.
Me: That’s no problem. We can easily change them later. Now let me take a shot at writing the Scenarios for the required fields.
I start by writing the first Scenario for the required fields and show it to the product owner. She says this is exactly what she expected:
Scenario: Name is required Given I am on the depot site When I purchase a book And I complete the order leaving the "Name" field blank Then I should see an error message with "Name can't be blank"
So I continue to write Scenarios for the other required fields on the page. While I write these Scenarios I see some duplication in my steps. At first I pull the first two steps out of the Scenarios and place them in a Background but I soon realize that this takes away from the expressiveness of the Scenarios. I settle on just moving the first step to the Background.
I look back at my notes I placed in the Feature and realize that all that remains is to define what belongs in the Pay with field. I write one final Scenario.
Scenario: Options for Pay with When I purchase a book And go to the checkout page Then the Pay with dropdown should contain "Check" And the Pay with dropdown should contain "Credit card" And the Pay with dropdown should contain "Purchase order"
The product owner and I feel good about the acceptance tests. I spend the remainder of the day performing exploratory testing on a story from the current iteration.
Monday comes around
First thing Monday morning we have our Show-and-Tell. The product owner feels good about the progress we are making on the site and she heaps praise on the team. Next comes the Iteration Close, Retrospective, and Iteration Open. All of these meetings take about an hour so I am ready for my next coffee when they are over.
At the coffee pot I run into Joseph. He lets me know he intends to pick up the Checkout story when he gets back to his desk and wonders if I have time to perform one final review of the Scenarios. I tell him I do. Back at the team space a conversation begins.
Me: Let’s read over the Scenarios together one final time before we begin coding.
After reading all of the Scenarios together, Joseph has no questions and is ready to get started. If he would have come up with other Scenarios they would have been added now. Joseph starts coding and it is time for me to begin automating the Scenarios, but first of all I place the tags at the top of the Feature file and check in everything I have so far.
Here is my completed Feature:
@NR @I_4
Feature: Checking out after you complete your order
As an online book buyer
I need to provide my personal information
so that the website can process my order
Background:
Given I am on the depot site
Scenario: Filling in all fields
When I purchase a book
And I complete the order with:
| name | address | email | pay_type |
| Sam Smith | 1213 Main Street | sam@example.com | Credit card |
Then I should see "Thank you for your order"
Scenario: Name is required
When I purchase a book
And I complete the order leaving the "Name" field blank
Then I should see an error message with "Name can't be blank"
Scenario: Address is required
When I purchase a book
And I complete the order leaving the "Address" field blank
Then I should see an error message with "Address can't be blank"
Scenario: Email is required
When I purchase a book
And I complete the order leaving the "Email" field blank
Then I should see an error message with "Email can't be blank"
Scenario: Options for Pay with
When I purchase a book
And go to the checkout page
Then the Pay with dropdown should contain "Check"
And the Pay with dropdown should contain "Credit card"
And the Pay with dropdown should contain "Purchase order"
Let’s create the page object
Since I have the screen mockup from Kimberly I can create the initial page object fairly quickly. All I need to do is create a new class, identify the elements on the screen with WatirHelper, and create my initialize method so I can pass the @browser variable. I write the following in about five minutes:
class CheckoutPage
include WatirHelper
text_field(:name, :id => 'order_name')
text_field(:address, :id => 'order_address')
text_field(:email, :id => 'order_email')
select_list(:pay_type, :id => 'order_pay_type')
button(:place_order, :value => 'Place Order')
def initialize(browser)
@browser = browser
end
end
This is good enough for right now. I’ll enhance the class when I really know what my step definitions need.
Writing the Step Definitions
I let RubyMine generate the shell for the step definitions for me. Since I have been working at this for a while I only have to implement six methods. I go ahead and write the steps as I think they should be implemented. This forces me to add a complete_order method to my page helper. Here are the step definitions:
Given /^I am on the depot site$/ do @catalog = CatalogPage.new(@browser) @catalog.visit end When /^I complete the order with:$/ do |table| @checkout_page = @shopping_cart.goto_checkout_page @checkout_page.complete_order(table.hashes.first) end When /^I complete the order leaving the "([^\"]*)" field blank$/ do |field| @checkout_page = @shopping_cart.goto_checkout_page @checkout_page.complete_order(field.downcase => "") end Then /^I should see an error message with "([^\"]*)"$/ do |message| @checkout_page.content.should include message end When /^go to the checkout page$/ do @checkout_page = @shopping_cart.goto_checkout_page end Then /^the Pay with dropdown should contain "([^\"]*)"$/ do |value| @checkout_page.pay_type_select_list.options.should include value end
Completing the page object
Now that I have my step definitions complete it is time to round out the checkout page object. The first thing I do is add some default data.
With this in place I am able to add my complete_order method. This method takes an empty hash as a default parameter so it can be called without passing anything. Then it merges the hash parameter with the default data. Finally it sets the values on the page. Here is the complete source:
class CheckoutPage
include WatirHelper
DEFAULT_DATA = {
'name' => 'Cheezy',
'address' => '123 Main Street',
'email' => 'cheezy@example.com',
'pay_type' => 'Check'
}
text_field(:name, :id => 'order_name')
text_field(:address, :id => 'order_address')
text_field(:email, :id => 'order_email')
select_list(:pay_type, :id => 'order_pay_type')
button(:place_order, :value => 'Place Order')
def initialize(browser)
@browser = browser
end
def complete_order(data={})
data = DEFAULT_DATA.merge(data)
self.name = data['name']
self.address = data['address']
self.email = data['email']
self.pay_type = data['pay_type']
place_order
end
end
When I am finished I check everything into source control and let Joseph the developer know all of the automation is complete.
Finishing the story
Joseph runs the acceptance tests periodically while developing the application. When he believes he is finished he calls me over.
Dev: The story is finally finished.
Me: Great. Let’s run the cucumber feature then.
Joseph runs cucumber on his computer and I see all of the acceptance tests run successfully. I then tell him it is Okay to remove the @NR tag in the feature file and check it in at the same time he checks in his last code. This triggers these tests to run as part of the continuous build.
At this time the story is considered functionally complete.



Nice post, just started learning and trying out Cucumber so really interesting to read about it all being put into practice
I’m glad you enjoyed it. I have several posts on Cucumber and related topics. Let me know what you think of the other posts.
Pingback: Tweets that mention New blog post - A day in the life of an acceptance tester - -- Topsy.com
Awesome! Thanks for posting this stuff! I just wish I had known this several years ago.
Pingback: Acceptance Test Driven Development for Windows « Stephan Schwab
Having a good chunk of syntax to crib helped tremendously as I wrote my first (realistic) cucumber tests today.
Hopefully I can convince the team lead to switch out of java/selenium into cucumber/page object/selenium.
Nice job Cheez Whiz – but what did Jared have to say?